mirror of
https://github.com/github/codeql.git
synced 2026-02-28 21:03:50 +01:00
Java: Autoformat semmle.code.java.dispatch.
This commit is contained in:
@@ -9,12 +9,11 @@ private import semmle.code.java.Maps
|
||||
/**
|
||||
* Gets a viable dispatch target for `ma`. This is the input dispatch relation.
|
||||
*/
|
||||
private Method viableImpl_inp(MethodAccess ma) {
|
||||
result = viableImpl_v2(ma)
|
||||
}
|
||||
private Method viableImpl_inp(MethodAccess ma) { result = viableImpl_v2(ma) }
|
||||
|
||||
private Callable dispatchCand(Call c) {
|
||||
c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration() or
|
||||
c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration()
|
||||
or
|
||||
result = viableImpl_inp(c)
|
||||
}
|
||||
|
||||
@@ -97,18 +96,23 @@ private predicate dispatchOrigin(ClassInstanceExpr cie, MethodAccess ma, Method
|
||||
|
||||
/** Holds if `t` is a type that is relevant for dispatch flow. */
|
||||
private predicate relevant(RefType t) {
|
||||
exists(ClassInstanceExpr cie | dispatchOrigin(cie, _, _) and t = cie.getConstructedType().getSourceDeclaration()) or
|
||||
relevant(t.getErasure()) or
|
||||
exists(RefType r | relevant(r) and t = r.getASourceSupertype()) or
|
||||
relevant(t.(Array).getComponentType()) or
|
||||
t instanceof MapType or
|
||||
exists(ClassInstanceExpr cie |
|
||||
dispatchOrigin(cie, _, _) and t = cie.getConstructedType().getSourceDeclaration()
|
||||
)
|
||||
or
|
||||
relevant(t.getErasure())
|
||||
or
|
||||
exists(RefType r | relevant(r) and t = r.getASourceSupertype())
|
||||
or
|
||||
relevant(t.(Array).getComponentType())
|
||||
or
|
||||
t instanceof MapType
|
||||
or
|
||||
t instanceof CollectionType
|
||||
}
|
||||
|
||||
/** A node with a type that is relevant for dispatch flow. */
|
||||
private class RelevantNode extends Node {
|
||||
RelevantNode() { relevant(this.getType()) }
|
||||
}
|
||||
private class RelevantNode extends Node { RelevantNode() { relevant(this.getType()) } }
|
||||
|
||||
/**
|
||||
* Holds if `p` is the `i`th parameter of a viable dispatch target of `call`.
|
||||
@@ -141,7 +145,8 @@ private predicate callFlowStepCand(RelevantNode n1, RelevantNode n2) {
|
||||
ret.getEnclosingCallable() = m and
|
||||
ret.getResult() = n1.asExpr() and
|
||||
m = dispatchCand(n2.asExpr())
|
||||
) or
|
||||
)
|
||||
or
|
||||
viableArgParamCand(n1, n2)
|
||||
}
|
||||
|
||||
@@ -151,47 +156,66 @@ private predicate callFlowStepCand(RelevantNode n1, RelevantNode n2) {
|
||||
*/
|
||||
private predicate flowStep(RelevantNode n1, RelevantNode n2) {
|
||||
exists(BaseSsaVariable v, BaseSsaVariable def |
|
||||
def.(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr() or
|
||||
def.(BaseSsaImplicitInit).isParameterDefinition(n1.asParameter()) or
|
||||
def.(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
|
||||
or
|
||||
def.(BaseSsaImplicitInit).isParameterDefinition(n1.asParameter())
|
||||
or
|
||||
exists(EnhancedForStmt for |
|
||||
for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and
|
||||
for.getExpr() = n1.asExpr() and
|
||||
n1.getType() instanceof Array
|
||||
)
|
||||
|
|
||||
|
|
||||
v.getAnUltimateDefinition() = def and
|
||||
v.getAUse() = n2.asExpr()
|
||||
) or
|
||||
exists(Callable c |
|
||||
n1.(InstanceParameterNode).getCallable() = c
|
||||
|
|
||||
exists(InstanceAccess ia | ia = n2.asExpr() and ia.getEnclosingCallable() = c and ia.isOwnInstanceAccess()) or
|
||||
)
|
||||
or
|
||||
exists(Callable c | n1.(InstanceParameterNode).getCallable() = c |
|
||||
exists(InstanceAccess ia |
|
||||
ia = n2.asExpr() and ia.getEnclosingCallable() = c and ia.isOwnInstanceAccess()
|
||||
)
|
||||
or
|
||||
n2.(ImplicitInstanceAccess).getInstanceAccess().(OwnInstanceAccess).getEnclosingCallable() = c
|
||||
) or
|
||||
)
|
||||
or
|
||||
exists(Field f |
|
||||
f.getAnAssignedValue() = n1.asExpr() and
|
||||
n2.asExpr().(FieldRead).getField() = f
|
||||
) or
|
||||
)
|
||||
or
|
||||
exists(EnumType enum, Method getValue |
|
||||
enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and
|
||||
getValue.getDeclaringType() = enum and
|
||||
(getValue.hasName("values") or getValue.hasName("valueOf")) and
|
||||
n2.asExpr().(MethodAccess).getMethod() = getValue
|
||||
) or
|
||||
n2.asExpr().(ParExpr).getExpr() = n1.asExpr() or
|
||||
n2.asExpr().(CastExpr).getExpr() = n1.asExpr() or
|
||||
n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr() or
|
||||
n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr() or
|
||||
n2.asExpr().(AssignExpr).getSource() = n1.asExpr() or
|
||||
n2.asExpr().(ArrayInit).getAnInit() = n1.asExpr() or
|
||||
n2.asExpr().(ArrayCreationExpr).getInit() = n1.asExpr() or
|
||||
n2.asExpr().(ArrayAccess).getArray() = n1.asExpr() or
|
||||
exists(Argument arg | n1.asExpr() = arg and arg.isVararg() and n2.(ImplicitVarargsArray).getCall() = arg.getCall()) or
|
||||
)
|
||||
or
|
||||
n2.asExpr().(ParExpr).getExpr() = n1.asExpr()
|
||||
or
|
||||
n2.asExpr().(CastExpr).getExpr() = n1.asExpr()
|
||||
or
|
||||
n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr()
|
||||
or
|
||||
n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr()
|
||||
or
|
||||
n2.asExpr().(AssignExpr).getSource() = n1.asExpr()
|
||||
or
|
||||
n2.asExpr().(ArrayInit).getAnInit() = n1.asExpr()
|
||||
or
|
||||
n2.asExpr().(ArrayCreationExpr).getInit() = n1.asExpr()
|
||||
or
|
||||
n2.asExpr().(ArrayAccess).getArray() = n1.asExpr()
|
||||
or
|
||||
exists(Argument arg |
|
||||
n1.asExpr() = arg and arg.isVararg() and n2.(ImplicitVarargsArray).getCall() = arg.getCall()
|
||||
)
|
||||
or
|
||||
exists(AssignExpr a, Variable v |
|
||||
a.getSource() = n1.asExpr() and
|
||||
a.getDest().(ArrayAccess).getArray() = v.getAnAccess() and
|
||||
n2.asExpr() = v.getAnAccess().(RValue)
|
||||
) or
|
||||
)
|
||||
or
|
||||
exists(Variable v, MethodAccess put, MethodAccess get |
|
||||
put.getArgument(1) = n1.asExpr() and
|
||||
put.getMethod().(MapMethod).hasName("put") and
|
||||
@@ -199,17 +223,19 @@ private predicate flowStep(RelevantNode n1, RelevantNode n2) {
|
||||
get.getQualifier() = v.getAnAccess() and
|
||||
get.getMethod().(MapMethod).hasName("get") and
|
||||
n2.asExpr() = get
|
||||
) or
|
||||
)
|
||||
or
|
||||
exists(Variable v, MethodAccess add |
|
||||
add.getAnArgument() = n1.asExpr() and
|
||||
add.getMethod().(CollectionMethod).hasName("add") and
|
||||
add.getQualifier() = v.getAnAccess()
|
||||
|
|
||||
|
|
||||
exists(MethodAccess get |
|
||||
get.getQualifier() = v.getAnAccess() and
|
||||
get.getMethod().(CollectionMethod).hasName("get") and
|
||||
n2.asExpr() = get
|
||||
) or
|
||||
)
|
||||
or
|
||||
exists(EnhancedForStmt for, BaseSsaVariable ssa, BaseSsaVariable def |
|
||||
for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and
|
||||
for.getExpr() = v.getAnAccess() and
|
||||
@@ -223,7 +249,8 @@ private predicate flowStep(RelevantNode n1, RelevantNode n2) {
|
||||
* Holds if `n` is forward-reachable from a relevant `ClassInstanceExpr`.
|
||||
*/
|
||||
private predicate nodeCandFwd(Node n) {
|
||||
dispatchOrigin(n.asExpr(), _, _) or
|
||||
dispatchOrigin(n.asExpr(), _, _)
|
||||
or
|
||||
exists(Node mid | nodeCandFwd(mid) | flowStep(mid, n) or callFlowStepCand(mid, n))
|
||||
}
|
||||
|
||||
@@ -236,7 +263,8 @@ private predicate nodeCand(Node n) {
|
||||
dispatchOrigin(_, ma, _) and
|
||||
n = getInstanceArgument(ma) and
|
||||
nodeCandFwd(n)
|
||||
) or
|
||||
)
|
||||
or
|
||||
exists(Node mid | nodeCand(mid) | flowStep(n, mid) or callFlowStepCand(n, mid)) and
|
||||
nodeCandFwd(n)
|
||||
}
|
||||
|
||||
@@ -24,12 +24,11 @@ Callable exactCallable(Call c) {
|
||||
c instanceof ConstructorCall and result = c.getCallee()
|
||||
}
|
||||
|
||||
private predicate implCount(MethodAccess m, int c) {
|
||||
strictcount(viableImpl(m)) = c
|
||||
}
|
||||
private predicate implCount(MethodAccess m, int c) { strictcount(viableImpl(m)) = c }
|
||||
|
||||
Callable viableCallable(Call c) {
|
||||
result = viableImpl(c) or
|
||||
result = viableImpl(c)
|
||||
or
|
||||
c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration()
|
||||
}
|
||||
|
||||
@@ -38,11 +37,11 @@ class CalledMethod extends Method {
|
||||
CalledMethod() { exists(MethodAccess ma | ma.getMethod() = this) }
|
||||
}
|
||||
|
||||
cached private module Dispatch {
|
||||
cached
|
||||
private module Dispatch {
|
||||
/** Gets a viable implementation of the method called in the given method access. */
|
||||
cached Method viableImpl(MethodAccess ma) {
|
||||
result = DispatchFlow::viableImpl_out(ma)
|
||||
}
|
||||
cached
|
||||
Method viableImpl(MethodAccess ma) { result = DispatchFlow::viableImpl_out(ma) }
|
||||
|
||||
private predicate qualType(VirtualMethodAccess ma, RefType t, boolean exact) {
|
||||
exprTypeFlow(ma.getQualifier(), t, exact)
|
||||
@@ -53,13 +52,14 @@ cached private module Dispatch {
|
||||
*
|
||||
* Gets a viable implementation of the method called in the given method access.
|
||||
*/
|
||||
cached Method viableImpl_v2(MethodAccess ma) {
|
||||
cached
|
||||
Method viableImpl_v2(MethodAccess ma) {
|
||||
result = viableImpl_v1(ma) and
|
||||
(
|
||||
exists(Method def, RefType t, boolean exact |
|
||||
qualType(ma, t, exact) and
|
||||
def = ma.getMethod()
|
||||
|
|
||||
|
|
||||
exact = true and result = exactMethodImpl(def, t.getSourceDeclaration())
|
||||
or
|
||||
exact = false and
|
||||
@@ -67,7 +67,8 @@ cached private module Dispatch {
|
||||
result = viableMethodImpl(def, t.getSourceDeclaration(), t2) and
|
||||
not Unification_v2::failsUnification(t, t2)
|
||||
)
|
||||
) or
|
||||
)
|
||||
or
|
||||
not qualType(ma, _, _)
|
||||
)
|
||||
}
|
||||
@@ -84,12 +85,14 @@ cached private module Dispatch {
|
||||
}
|
||||
|
||||
private predicate unificationTargets(Type t1, Type t2) {
|
||||
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g)) or
|
||||
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g))
|
||||
or
|
||||
exists(Array a1, Array a2 |
|
||||
unificationTargets(a1, a2) and
|
||||
t1 = a1.getComponentType() and
|
||||
t2 = a2.getComponentType()
|
||||
) or
|
||||
)
|
||||
or
|
||||
exists(ParameterizedType pt1, ParameterizedType pt2, int pos |
|
||||
unificationTargets(pt1, pt2) and
|
||||
not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and
|
||||
@@ -99,7 +102,9 @@ cached private module Dispatch {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate typeArgsOfUnificationTargets(ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2) {
|
||||
private predicate typeArgsOfUnificationTargets(
|
||||
ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2
|
||||
) {
|
||||
unificationTargets(t1, t2) and
|
||||
arg1 = t1.getTypeArgument(pos) and
|
||||
arg2 = t2.getTypeArgument(pos)
|
||||
@@ -111,14 +116,21 @@ cached private module Dispatch {
|
||||
exists(RefType arg1, RefType arg2 |
|
||||
typeArgsOfUnificationTargets(t1, t2, _, arg1, arg2) and
|
||||
failsUnification(arg1, arg2)
|
||||
) or
|
||||
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType()) or
|
||||
)
|
||||
or
|
||||
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType())
|
||||
or
|
||||
not (
|
||||
t1 instanceof Array and t2 instanceof Array or
|
||||
t1.(PrimitiveType) = t2.(PrimitiveType) or
|
||||
t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration() or
|
||||
t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration() or
|
||||
t1 instanceof BoundedType and t2 instanceof RefType or
|
||||
t1 instanceof Array and t2 instanceof Array
|
||||
or
|
||||
t1.(PrimitiveType) = t2.(PrimitiveType)
|
||||
or
|
||||
t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration()
|
||||
or
|
||||
t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration()
|
||||
or
|
||||
t1 instanceof BoundedType and t2 instanceof RefType
|
||||
or
|
||||
t1 instanceof RefType and t2 instanceof BoundedType
|
||||
)
|
||||
)
|
||||
@@ -156,11 +168,12 @@ cached private module Dispatch {
|
||||
*/
|
||||
private Method viableImpl_v1_cand(MethodAccess source) {
|
||||
not result.isAbstract() and
|
||||
if source instanceof VirtualMethodAccess then
|
||||
if source instanceof VirtualMethodAccess
|
||||
then
|
||||
exists(CalledMethod def, RefType t, boolean exact |
|
||||
source.getMethod() = def and
|
||||
hasQualifierType(source, t, exact)
|
||||
|
|
||||
|
|
||||
exact = true and result = exactMethodImpl(def, t.getSourceDeclaration())
|
||||
or
|
||||
exact = false and
|
||||
@@ -169,8 +182,7 @@ cached private module Dispatch {
|
||||
not Unification_v1::failsUnification(t, t2)
|
||||
)
|
||||
)
|
||||
else
|
||||
result = source.getMethod().getSourceDeclaration()
|
||||
else result = source.getMethod().getSourceDeclaration()
|
||||
}
|
||||
|
||||
private module Unification_v1 {
|
||||
@@ -185,12 +197,14 @@ cached private module Dispatch {
|
||||
}
|
||||
|
||||
private predicate unificationTargets(Type t1, Type t2) {
|
||||
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g)) or
|
||||
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g))
|
||||
or
|
||||
exists(Array a1, Array a2 |
|
||||
unificationTargets(a1, a2) and
|
||||
t1 = a1.getComponentType() and
|
||||
t2 = a2.getComponentType()
|
||||
) or
|
||||
)
|
||||
or
|
||||
exists(ParameterizedType pt1, ParameterizedType pt2, int pos |
|
||||
unificationTargets(pt1, pt2) and
|
||||
not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and
|
||||
@@ -200,7 +214,9 @@ cached private module Dispatch {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate typeArgsOfUnificationTargets(ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2) {
|
||||
private predicate typeArgsOfUnificationTargets(
|
||||
ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2
|
||||
) {
|
||||
unificationTargets(t1, t2) and
|
||||
arg1 = t1.getTypeArgument(pos) and
|
||||
arg2 = t2.getTypeArgument(pos)
|
||||
@@ -212,14 +228,21 @@ cached private module Dispatch {
|
||||
exists(RefType arg1, RefType arg2 |
|
||||
typeArgsOfUnificationTargets(t1, t2, _, arg1, arg2) and
|
||||
failsUnification(arg1, arg2)
|
||||
) or
|
||||
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType()) or
|
||||
)
|
||||
or
|
||||
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType())
|
||||
or
|
||||
not (
|
||||
t1 instanceof Array and t2 instanceof Array or
|
||||
t1.(PrimitiveType) = t2.(PrimitiveType) or
|
||||
t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration() or
|
||||
t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration() or
|
||||
t1 instanceof BoundedType and t2 instanceof RefType or
|
||||
t1 instanceof Array and t2 instanceof Array
|
||||
or
|
||||
t1.(PrimitiveType) = t2.(PrimitiveType)
|
||||
or
|
||||
t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration()
|
||||
or
|
||||
t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration()
|
||||
or
|
||||
t1 instanceof BoundedType and t2 instanceof RefType
|
||||
or
|
||||
t1 instanceof RefType and t2 instanceof BoundedType
|
||||
)
|
||||
)
|
||||
@@ -227,7 +250,8 @@ cached private module Dispatch {
|
||||
}
|
||||
|
||||
private RefType getPreciseType(Expr e) {
|
||||
result = e.(FunctionalExpr).getConstructedType() or
|
||||
result = e.(FunctionalExpr).getConstructedType()
|
||||
or
|
||||
not e instanceof FunctionalExpr and result = e.getType()
|
||||
}
|
||||
|
||||
@@ -237,20 +261,25 @@ cached private module Dispatch {
|
||||
// and take the type of the assigned value.
|
||||
exists(RefType srctype | srctype = getPreciseType(src) |
|
||||
exists(BoundedType bd | bd = srctype |
|
||||
t = bd.getAnUltimateUpperBoundType() or
|
||||
t = bd.getAnUltimateUpperBoundType()
|
||||
or
|
||||
not exists(bd.getAnUltimateUpperBoundType()) and t = ma.getMethod().getDeclaringType()
|
||||
) or
|
||||
)
|
||||
or
|
||||
t = srctype and not srctype instanceof BoundedType
|
||||
) and
|
||||
// If we have a class instance expression, then we know the exact type.
|
||||
// This is an important improvement in precision.
|
||||
if src instanceof ClassInstanceExpr then exact = true else exact = false
|
||||
) or
|
||||
)
|
||||
or
|
||||
// If the call has no qualifier then it's an implicit `this` qualifier,
|
||||
// so start from the caller's declaring type or enclosing type.
|
||||
not exists(ma.getQualifier()) and exact = false and
|
||||
not exists(ma.getQualifier()) and
|
||||
exact = false and
|
||||
(
|
||||
ma.isOwnMethodAccess() and t = ma.getEnclosingCallable().getDeclaringType() or
|
||||
ma.isOwnMethodAccess() and t = ma.getEnclosingCallable().getDeclaringType()
|
||||
or
|
||||
ma.isEnclosingMethodAccess(t)
|
||||
)
|
||||
}
|
||||
@@ -274,9 +303,7 @@ cached private module Dispatch {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasSrcMethod(SrcRefType t, Method impl) {
|
||||
exists(Method m |
|
||||
t.hasMethod(m, _, _) and impl = m.getSourceDeclaration()
|
||||
)
|
||||
exists(Method m | t.hasMethod(m, _, _) and impl = m.getSourceDeclaration())
|
||||
}
|
||||
|
||||
private predicate hasViableSubtype(RefType t, SrcRefType sub) {
|
||||
@@ -284,7 +311,6 @@ cached private module Dispatch {
|
||||
not sub instanceof Interface and
|
||||
not sub.isAbstract()
|
||||
}
|
||||
|
||||
}
|
||||
import Dispatch
|
||||
|
||||
@@ -294,7 +320,7 @@ private Expr variableTrackStep(Expr use) {
|
||||
use.getType() instanceof RefType and
|
||||
not result instanceof NullLiteral and
|
||||
not v.(LocalVariableDecl).getDeclExpr().hasImplicitInit()
|
||||
|
|
||||
|
|
||||
not v instanceof Parameter and
|
||||
result = v.getAnAssignedValue()
|
||||
or
|
||||
@@ -314,6 +340,7 @@ private Expr variableTrackPath(Expr use) {
|
||||
* Gets an expression by tracking `use` backwards through variable assignments.
|
||||
*/
|
||||
Expr variableTrack(Expr use) {
|
||||
result = variableTrackPath(use) or
|
||||
result = variableTrackPath(use)
|
||||
or
|
||||
not exists(variableTrackPath(use)) and result = use
|
||||
}
|
||||
|
||||
@@ -29,9 +29,7 @@ class FunctionalInterface extends Interface {
|
||||
}
|
||||
|
||||
/** Gets the single method of this interface. */
|
||||
Method getRunMethod() {
|
||||
getAPotentialRunMethod(this).getSourceDeclaration() = result
|
||||
}
|
||||
Method getRunMethod() { getAPotentialRunMethod(this).getSourceDeclaration() = result }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,7 +39,8 @@ class FunctionalInterface extends Interface {
|
||||
private predicate runner(Method m, int n, Method runmethod) {
|
||||
m.getParameterType(n).(RefType).getSourceDeclaration().(FunctionalInterface).getRunMethod() = runmethod and
|
||||
(
|
||||
m.isNative() or
|
||||
m.isNative()
|
||||
or
|
||||
exists(Parameter p, MethodAccess ma, int j |
|
||||
p = m.getParameter(n) and
|
||||
ma.getEnclosingCallable() = m and
|
||||
@@ -63,7 +62,8 @@ private Expr getRunnerArgument(MethodAccess ma, Method runmethod) {
|
||||
result = ma.getArgument(param)
|
||||
)
|
||||
or
|
||||
getRunnerArgument(ma, runmethod).(CastExpr).getExpr() = result or
|
||||
getRunnerArgument(ma, runmethod).(CastExpr).getExpr() = result
|
||||
or
|
||||
getRunnerArgument(ma, runmethod).(VarAccess).getVariable().getAnAssignedValue() = result
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user