private void prepareAlarmManagerSet(Body body, InvokeStmt setStmt, SootMethodRef reportRef) { Value oldVal = setStmt.getInvokeExpr().getArg(1); Local longLocal = UtilInstrumenter.generateFreshLocal(body, LongType.v()); SootMethod currentTimeMillis = Scene.v().getMethod("<java.lang.System: long currentTimeMillis()>"); StaticInvokeExpr timeInvoke = Jimple.v().newStaticInvokeExpr(currentTimeMillis.makeRef()); AssignStmt timeInitalize = Jimple.v().newAssignStmt(longLocal, timeInvoke); AddExpr addTime = Jimple.v().newAddExpr(longLocal, LongConstant.v(2000L)); AssignStmt timeAssign = Jimple.v().newAssignStmt(longLocal, addTime); body.getUnits().insertBefore(timeInitalize, setStmt); body.getUnits().insertBefore(timeAssign, setStmt); InvokeExpr expr = setStmt.getInvokeExpr(); expr.setArg(0, IntConstant.v(0)); expr.setArg(1, longLocal); // Report the change InvokeStmt reportStmt = Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr( reportRef, oldVal, longLocal)); reportStmt.addTag(new InstrumentedCodeTag()); body.getUnits().insertAfter(reportStmt, setStmt); }
public void fill() { DomI domI = (DomI) doms[0]; DomM domM = (DomM) doms[1]; int numI = domI.size(); for (int iIdx = 0; iIdx < numI; iIdx++) { Unit i = (Unit) domI.get(iIdx); if(SootUtilities.isInvoke(i)){ InvokeExpr ie = SootUtilities.getInvokeExpr(i); if(ie instanceof StaticInvokeExpr){ SootMethod m = ie.getMethod(); if(m.isStatic()){ m = StubRewrite.maybeReplaceCallDest(SootUtilities.getMethod(i), m); int mIdx = domM.indexOf(m); if (mIdx >= 0) add(iIdx, mIdx); else if (Config.verbose >= 2) Messages.log(NOT_FOUND, m, SootUtilities.toLocStr(i)); } } } } }
@Override public void caseStaticInvokeExpr(StaticInvokeExpr v) { logger.fine("Invoke expression is of type StaticInvoke"); logger.finest(v.toString()); rightElement = RightElement.NOT; if (actualContext == StmtContext.INVOKE || actualContext == StmtContext.ASSIGNRIGHT ) { Local[] args = vh.getArgumentsForInvokedMethod(v); String method = v.getMethod().toString(); if (ExternalClasses.methodMap.containsKey(method)) { logger.fine("Found an external class " + method); logger.fine("This class is treated in a special way"); ExternalClasses.receiveCommand(method, callingStmt, args); } else { logger.fine("Found an external class " + method); logger.fine("This class is treated as an internal class"); JimpleInjector.storeArgumentLevels(callingStmt, args); } } else { throw new InternalAnalyzerException( "Unexpected Context for Invoke Expression"); } }
@Override public Try<Option<ValueCast<Level>>> detectValueCastFromCall(StaticInvokeExpr e) { SootMethod m = e.getMethod(); BiFunction<TypeView<Level>, TypeView<Level>, Try<Option<ValueCast<Level>>>> makeCast = (t1, t2) -> { Optional<ValueCast<Level>> result = Interop.asJavaStream(Vars.getAll(e.getArg(0))).findFirst().map(value -> makeValueCast(t1, t2, Option.apply(value))); return new Success<>(Interop.asScalaOption(result)); }; if (castEquals(castHighToDyn, m)) { return makeCast.apply(THIGH, DYN); } else if (castEquals(castLowToDyn, m)) { return makeCast.apply(TLOW, DYN); } else if (castEquals(castDynToLow, m)) { return makeCast.apply(DYN, TLOW); } else if (castEquals(castDynToHigh, m)) { return makeCast.apply(DYN, THIGH); } else { return new Success<>(Option.empty()); } }
public static Unit makeJimpleStaticCallForPathExecution(String methodName, Object... args) { SootClass sootClass = Scene.v().getSootClass(UtilInstrumenter.JAVA_CLASS_FOR_PATH_EXECUTION); Unit generated = null; ArrayList<Type> argTypes = new ArrayList<Type>(); ArrayList<Value> argList = new ArrayList<Value>(); if (args != null) { if (args.length % 2 != 0) { throw new RuntimeException( "Mismatched argument types:values in static call to " + methodName); } else { for (int i = 0; i < args.length; i++) if (i % 2 == 0) // First type, then argument argTypes.add((Type) args[i]); else argList.add((Value) args[i]); } } SootMethod createAndAdd = sootClass.getMethod(methodName, argTypes); StaticInvokeExpr sie = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), argList); generated = Jimple.v().newInvokeStmt(sie); return generated; }
private void instrumentEachBranchAccess(Body body, Unit unit){ SootClass sootClass = Scene.v().getSootClass( UtilInstrumenter.JAVA_CLASS_FOR_PATH_INSTRUMENTATION); // Create the method invocation SootMethod createAndAdd = sootClass.getMethod("reportConditionOutcomeSynchronous", Collections.<Type>singletonList(BooleanType.v())); StaticInvokeExpr sieThen = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), IntConstant.v(1)); StaticInvokeExpr sieElse = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), IntConstant.v(0)); Unit sieThenUnit = Jimple.v().newInvokeStmt(sieThen); sieThenUnit.addTag(new InstrumentedCodeTag()); Unit sieElseUnit = Jimple.v().newInvokeStmt(sieElse); sieElseUnit.addTag(new InstrumentedCodeTag()); //treatment of target statement ("true"-branch) IfStmt ifStmt = (IfStmt)unit; Stmt targetStmt = ifStmt.getTarget(); if(!branchTargetStmt.contains(targetStmt.toString())) { branchTargetStmt.add(sieThenUnit.toString()); body.getUnits().insertBefore(sieThenUnit, targetStmt); NopStmt nop = Jimple.v().newNopStmt(); GotoStmt gotoNop = Jimple.v().newGotoStmt(nop); body.getUnits().insertBeforeNoRedirect(nop, targetStmt); body.getUnits().insertBeforeNoRedirect(gotoNop, sieThenUnit); } //treatment of "else"-branch body.getUnits().insertAfter(sieElseUnit, unit); }
@Override public void caseStaticInvokeExpr(StaticInvokeExpr v) { //just propagate the taint value of previous statement Stmt prevStmt = stmtVisitor.getPreviousDataFlowPathElement(currentStatement); if(prevStmt == null) throw new RuntimeException("there is no previous statement"); else { //create an assignment between the incoming taint-value and the //assigned taint-value inside the method SMTBinding bindingPrevStmt = stmtVisitor.getBindingForTaintedValue(prevStmt); //if there is no taint-tracking involved, we do not have to create an SMT formula if(bindingPrevStmt == null) return; AccessPath accessPath = stmtVisitor.getCorrectAccessPathForStmt(currentStatement); Local identityStmtTaintValue = accessPath.getPlainValue(); SMTBinding bindingCurentStmt = stmtVisitor.getLatestBindingForValue(identityStmtTaintValue); if(bindingCurentStmt == null) { bindingCurentStmt = stmtVisitor.createNewBindingForValue(identityStmtTaintValue); stmtVisitor.addValueBindingToVariableDeclaration(identityStmtTaintValue, bindingCurentStmt); } if(bindingCurentStmt != bindingPrevStmt) { SMTSimpleAssignment simpleAssignForTaintProp = new SMTSimpleAssignment(bindingCurentStmt, new SMTBindingValue(bindingPrevStmt)); SMTAssertStatement simpleAssignAssert = new SMTAssertStatement(simpleAssignForTaintProp); stmtVisitor.addAssertStmtToAllPrograms(simpleAssignAssert); } this.result = bindingCurentStmt; } }
/***** API calls *****/ // Sanitizer for user study. Kill the parameter and its aliases private boolean applySanitizer(Unit call, FlowAbstraction source) { // Call itself Stmt stmt = (Stmt) call; final String target = stmt.getInvokeExpr().getMethod().getSignature(); final List<Value> args = stmt.getInvokeExpr().getArgs(); if (!target.equals("<sanitizers.Sanitizer: void sanitize(java.lang.Object)>")) return false; if (killforSanit(call, args.get(0), source)) return true; // Case of valueOf for primitive types // a = Integer.valueOf(b); and sanit(a) -> must also treat aliases of b List<Unit> predecessors = icfg.getPredsOf(call); for (Unit predecessor : predecessors) { if (predecessor instanceof DefinitionStmt) { DefinitionStmt def = (DefinitionStmt) predecessor; if (def.getLeftOp().equals(args.get(0)) && def.getRightOp() instanceof StaticInvokeExpr) { InvokeExpr expr = (StaticInvokeExpr) def.getRightOp(); final SootMethod method = expr.getMethod(); if (method.getName().equals("valueOf") && expr.getArgCount() == 1 && method.getDeclaringClass().getType().equals(method.getReturnType()) && isPrimitiveType(method.getReturnType())) { if (killforSanit(predecessor, expr.getArg(0), source)) return true; } } } } return false; }
@Override public void caseStaticInvokeExpr(StaticInvokeExpr sie) { BuilderMethodReference method = DexPrinter.toMethodReference (sie.getMethodRef(), dexFile); List<Register> arguments = getInvokeArgumentRegs(sie); stmtV.addInsn(buildInvokeInsn("INVOKE_STATIC", method, arguments), origStmt); }
public void caseStaticInvokeExpr(StaticInvokeExpr expr) { result = result.add(mgr.INITIALIZATION_ERRORS); for (int i = 0; i < expr.getArgCount(); i++) { result = result.add(mightThrow(expr.getArg(i))); } result = result.add(mightThrow(expr.getMethodRef())); }
public static boolean isStaticInvoke(Unit q){ assert (q instanceof JInvokeStmt || q instanceof JAssignStmt); InvokeExpr ie; if (q instanceof JInvokeStmt) ie = ((JInvokeStmt)q).getInvokeExpr(); else if (q instanceof JAssignStmt) ie = ((InvokeExpr)(((JAssignStmt)q).rightBox.getValue())); else ie = null; if (ie != null && ie instanceof StaticInvokeExpr) return true; return false; }
public static StaticInvokeExpr createJimpleStaticInvokeExpr(String javaClass, String call, List<Object> args) { SootClass sootClass = Scene.v().getSootClass(javaClass); ArrayList<Type> argTypes = new ArrayList<Type>(); ArrayList<Value> argList = new ArrayList<Value>(); if (args != null) { if (args.size() % 2 != 0) { throw new RuntimeException( "Mismatched argument types:values in static call to " + call); } else { for (int i = 0; i < args.size(); i++) if (i % 2 == 0) // First type, then argument argTypes.add((Type) args.get(i)); else argList.add((Value) args.get(i)); } } SootMethod createAndAdd = sootClass.getMethod(call, argTypes); StaticInvokeExpr sie = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), argList); log.debug("new invoke expression: "+ sie); return sie; }
private static void initializePeP(SootClass sc){ SootMethod onCreate = null; log.info("add Pep initialization in class "+ sc); for(SootMethod sm : sc.getMethods()){ if(sm.getName().equals("onCreate") && sm.getParameterCount() == 1 && sm.getParameterType(0).toString().equals("android.os.Bundle")){ onCreate = sm; } } if(onCreate != null){ List<Unit> generated = new ArrayList<Unit>(); Body body = onCreate.retrieveActiveBody(); Local thisLocal = body.getThisLocal(); SootClass context = Scene.v().forceResolve("android.content.Context", SootClass.BODIES); // SootMethod applicationContext =sc.getMethod("android.content.Context getApplicationContext()"); SootMethod applicationContext = context.getMethod("android.content.Context getApplicationContext()"); SpecialInvokeExpr virtInvExpr = Jimple.v().newSpecialInvokeExpr(thisLocal, applicationContext.makeRef()); Local applicationContextLocal = generateFreshLocal(body, RefType.v("android.content.Context")); generated.add(Jimple.v().newAssignStmt(applicationContextLocal, virtInvExpr)); List<Object> args = new ArrayList<Object>(); args.add(RefType.v("android.content.Context")); args.add(applicationContextLocal); StaticInvokeExpr staticInvExpr = Instrumentation.createJimpleStaticInvokeExpr(Settings.instance.INSTRUMENTATION_HELPER_JAVA, Settings.instance.INSTRUMENTATION_HELPER_INITIALIZE_METHOD, args); generated.add(Jimple.v().newInvokeStmt(staticInvExpr)); Unit onCreateSpecialInvoke = getSuperOnCreateUnit(body); if(onCreateSpecialInvoke == null) throw new RuntimeException("error: super.onCreate() statement missing in method "+ onCreate); body.getUnits().insertAfter(generated, onCreateSpecialInvoke); } }
@Override public void caseStaticInvokeExpr(StaticInvokeExpr v) { SootClass sootClass = v.getMethod().getDeclaringClass(); handleStatic(sootClass); handleInvoke(v); addProgramCounterConstraint(sootClass.getName()); }
public Option<ValueCast<Level>> detectValueCastFromStmt(Stmt s) throws TypingException { if (s.containsInvokeExpr()) { InvokeExpr e = s.getInvokeExpr(); if (e instanceof StaticInvokeExpr) { Try<Option<ValueCast<Level>>> result = this.detectValueCastFromCall((StaticInvokeExpr) e); if (result.isSuccess()) { return result.get(); } else { throw new TypingException(result.failed().get().getMessage()); } } } return Option.empty(); }
public Option<CxCast<Level>> detectContextCastStartFromStmt(Stmt s) throws TypingException { if (s.containsInvokeExpr()) { InvokeExpr e = s.getInvokeExpr(); if (e instanceof StaticInvokeExpr) { Try<Option<CxCast<Level>>> result = this.detectContextCastStartFromCall((StaticInvokeExpr) e); if (result.isSuccess()) { return result.get(); } else { throw new TypingException(result.failed().get().getMessage()); } } } return Option.empty(); }
public boolean detectContextCastEndFromStmt(Stmt s) { if (s.containsInvokeExpr()) { InvokeExpr e = s.getInvokeExpr(); if (e instanceof StaticInvokeExpr) { return this.detectContextCastEndFromCall((StaticInvokeExpr) e); } } return false; }
@Test public void testValid() { StaticInvokeExpr callCastHighToDyn = makeCall_1("castHighToDyn"); StaticInvokeExpr callCastLowToDyn = makeCall_1("castLowToDyn"); StaticInvokeExpr callCxCastHighToDyn = makeCall_0("cxCastHighToDyn"); StaticInvokeExpr callCxCastLowToDyn = makeCall_0("cxCastLowToDyn"); StaticInvokeExpr callCxCastEnd = makeCall_0("cxCastEnd"); assertThat("makeCall_ generates wrong name" + callCastHighToDyn.getMethod().toString(), callCastHighToDyn.getMethod().toString(), is("<de.unifreiburg.cs.proglang.jgs.support.ACasts: java.lang.Object castHighToDyn(java.lang.Object)>")); assertThat("makeCall_ generates wrong name" + callCxCastHighToDyn.getMethod().toString(), callCxCastHighToDyn.getMethod().toString(), is("<de.unifreiburg.cs.proglang.jgs.support.ACasts: void cxCastHighToDyn()>")); Map<String,String> valueCasts = new HashMap<>(); valueCasts.put(callCastHighToDyn.getMethod().toString(), "HIGH ~> ?"); valueCasts.put(callCastLowToDyn.getMethod().toString(), "LOW ~> ?"); Map<String,String> cxCasts = new HashMap<>(); cxCasts.put(callCxCastHighToDyn.getMethod().toString(), "HIGH ~> ?"); cxCasts.put(callCxCastLowToDyn.getMethod().toString(), "LOW ~> ?"); String cxCastEnd = callCxCastEnd.getMethod().toString(); ACasts<Level> casts = CastsFromMapping$.MODULE$.<Level>apply(parseConversionMap(types, valueCasts), parseConversionMap(types, cxCasts), cxCastEnd); assertThat(String.format("wrong conversion for %s", callCxCastHighToDyn.getMethod().toString()), Interop.asJavaOptional(casts.detectValueCastFromCall(callCastHighToDyn)), convertsBetween(THIGH, DYN)); assertThat(String.format("wrong conversion for %s", callCxCastLowToDyn.getMethod().toString()), Interop.asJavaOptional(casts.detectValueCastFromCall(callCastLowToDyn)), convertsBetween(TLOW, DYN)); assertThat(casts.detectValueCastFromCall(callCxCastHighToDyn), is(Success.apply(Option.empty()))); }
@Override public Try<Option<CxCast<Level>>> detectContextCastStartFromCall(StaticInvokeExpr e) { SootMethod m = e.getMethod(); BiFunction<TypeView<Level>, TypeView<Level>, Try<Option<CxCast<Level>>>> makeCast = (t1, t2) -> new Success<>(Option.apply(makeContextCast(t1, t2))); if (castEquals(castCxDynToHigh, m)) { return makeCast.apply(DYN, THIGH); } else if (castEquals(castCxHighToDyn, m)) { return makeCast.apply(THIGH, DYN); } else { return new Success<>(Option.empty()); } }
public void caseStaticInvokeExpr(StaticInvokeExpr expr) { handleCall(expr, expr.getMethod()); }
public void caseStaticInvokeExpr(StaticInvokeExpr v) { printInvokeExpr(v); }
@Override public void caseStaticInvokeExpr(StaticInvokeExpr arg0) { throw new RuntimeException("This must be handeled by SootStmtSwitch!"); }
private List<Unit> instrumentIntentAddings(BiDiInterproceduralCFG<Unit, SootMethod> cfg, Unit unit, InvokeExpr sinkExpr, Set<ResultSourceInfo> sourceInfo){ if(isMethodInterComponentSink(sinkExpr.getMethod())){ SootMethod method = cfg.getMethodOf(unit); Body body = null; if(method.hasActiveBody()) body = method.retrieveActiveBody(); else throw new RuntimeException("No body found!"); Set<String> sourceCategories = getDataIdList(sourceInfo); final String hashSetType = "java.util.HashSet"; List<Unit> generated = new ArrayList<Unit>(); //HashSet initialization Local hashSetLocal = generateFreshLocal(body, RefType.v(hashSetType)); NewExpr newExpr = Jimple.v().newNewExpr(RefType.v(hashSetType)); AssignStmt assignStmt = Jimple.v().newAssignStmt(hashSetLocal, newExpr); generated.add(assignStmt); //constructor call SpecialInvokeExpr constructorCall = Jimple.v().newSpecialInvokeExpr(hashSetLocal, Scene.v().getMethod("<java.util.HashSet: void <init>()>").makeRef()); InvokeStmt constructorCallStmt = Jimple.v().newInvokeStmt(constructorCall); generated.add(constructorCallStmt); //add categories to HashSet for(String cat : sourceCategories){ InterfaceInvokeExpr addCall = Jimple.v().newInterfaceInvokeExpr(hashSetLocal, Scene.v().getMethod("<java.util.Set: boolean add(java.lang.Object)>").makeRef(), StringConstant.v(cat)); InvokeStmt addCallStmt = Jimple.v().newInvokeStmt(addCall); generated.add(addCallStmt); } //get Intent Value intent = sinkExpr.getArg(0); List<Object> args = new ArrayList<Object>(); args.add(RefType.v("android.content.Intent")); args.add(intent); args.add(RefType.v(hashSetType)); args.add(hashSetLocal); StaticInvokeExpr sie = Instrumentation.createJimpleStaticInvokeExpr( Settings.INSTRUMENTATION_HELPER_JAVA, "addTaintInformationToIntent", args); InvokeStmt invStmt = Jimple.v().newInvokeStmt(sie); generated.add(invStmt); return generated; } return Collections.emptyList(); }
@Override public void caseStaticInvokeExpr(StaticInvokeExpr v) { throwInvalidWriteException(v); }
private StaticInvokeExpr makeCall_0(String methodName) { SootMethod m = new SootMethod(methodName, emptyList(), VoidType.v(), Modifier.STATIC); this.castClass.addMethod(m); return Jimple.v().newStaticInvokeExpr(m.makeRef(), NullConstant.v()); }
private StaticInvokeExpr makeCall_1(String methodName) { soot.Type t = RefType.v("java.lang.Object"); SootMethod m = new SootMethod(methodName, singletonList(t), t, Modifier.STATIC); this.castClass.addMethod(m); return Jimple.v().newStaticInvokeExpr(m.makeRef(), NullConstant.v()); }
@Override public boolean detectContextCastEndFromCall(StaticInvokeExpr e) { return castEquals(castCxEnd, e.getMethod()); }
/** * Computes the targets of an invoke expression using a given points-to graph. * * <p>For static invocations, there is only target. For instance method * invocations, the targets depend on the type of receiver objects pointed-to * by the instance variable whose method is being invoked.</p> * * <p>If the instance variable points to a summary node, then the returned * value is <tt>null</tt> signifying a <em>default</em> call-site.</p> */ private Set<SootMethod> getTargets(SootMethod callerMethod, Stmt callStmt, InvokeExpr ie, PointsToGraph ptg) { Set<SootMethod> targets = new HashSet<SootMethod>(); SootMethod invokedMethod = ie.getMethod(); String subsignature = invokedMethod.getSubSignature(); // Static and special invocations refer to the target method directly if (ie instanceof StaticInvokeExpr || ie instanceof SpecialInvokeExpr) { targets.add(invokedMethod); return targets; } else { assert (ie instanceof InterfaceInvokeExpr || ie instanceof VirtualInvokeExpr); // Get the receiver Local receiver = (Local) ((InstanceInvokeExpr) ie).getBase(); // Get what objects the receiver points-to Set<AnyNewExpr> heapNodes = ptg.getTargets(receiver); if (heapNodes != null) { // For each object, find the invoked method for the declared type for (AnyNewExpr heapNode : heapNodes) { if (heapNode == PointsToGraph.SUMMARY_NODE) { // If even one pointee is a summary node, then this is a default site return null; } else if (heapNode instanceof NewArrayExpr) { // Probably getClass() or something like that on an array return null; } // Find the top-most class that declares a method with the given // signature and add it to the resulting targets SootClass sootClass = ((RefType) heapNode.getType()).getSootClass(); do { if (sootClass.declaresMethod(subsignature)) { targets.add(sootClass.getMethod(subsignature)); break; } else if (sootClass.hasSuperclass()) { sootClass = sootClass.getSuperclass(); } else { sootClass = null; } } while (sootClass != null); } } if (targets.isEmpty()) { // System.err.println("Warning! Null call at: " + callStmt+ " in " + callerMethod); } return targets; } }
/** * The method should update the <em>security level</em> of an invoke * expression with type {@link StaticInvokeExpr}, but it is not possible to * update the level of an invoke expression. * * @param v * The invoke expression for which the <em>security level</em> * should be updated. * @see soot.jimple.ExprSwitch#caseStaticInvokeExpr(soot.jimple.StaticInvokeExpr) * @throws InvalidSwitchException * Always, because the update is not possible. */ @Override public void caseStaticInvokeExpr(StaticInvokeExpr v) { throw new SwitchException(getMsg("exception.analysis.switch.update_error", this.getClass().getSimpleName(), v.getClass().getSimpleName(), v.toString(), getSourceLine())); }
/** * Returns true if a method call is fixed, i.e., assuming that all classes in the Scene resemble library code, * then client code cannot possible overwrite the called method. * This is trivially true for InvokeStatic and InvokeSpecial, but can also hold for virtual invokes if * all possible call targets in the library cannot be overwritten. * @see #clientOverwriteableOverwrites(SootMethod) */ public static boolean isFixed(InvokeExpr ie) { return ie instanceof StaticInvokeExpr || ie instanceof SpecialInvokeExpr || !clientOverwriteableOverwrites(ie.getMethod()); }
/** * DOC * * @see soot.jimple.ExprSwitch#caseStaticInvokeExpr(soot.jimple.StaticInvokeExpr) */ @Override public void caseStaticInvokeExpr(StaticInvokeExpr v) { this.extractor.addMethodEnvironmentForMethod(v.getMethod()); }
/** * Looks up the <em>security level</em> of the given invoke expression with * the type {@link StaticInvokeExpr} and stores the resulting level in * {@link SecurityLevelValueReadSwitch#level}. Also the parameter * <em>security level</em> and the <em>write effects</em> will be handled. * * @param v * The invoke expression, for which the level should be looked * up. * @see soot.jimple.ExprSwitch#caseStaticInvokeExpr(soot.jimple.StaticInvokeExpr) * @see SecurityLevelValueReadSwitch#handleInvokeExpr(InvokeExpr) */ @Override public void caseStaticInvokeExpr(StaticInvokeExpr v) { handleInvokeExpr(v); }
public abstract Try<Option<ValueCast<Level>>> detectValueCastFromCall(StaticInvokeExpr e);
public abstract Try<Option<CxCast<Level>>> detectContextCastStartFromCall(StaticInvokeExpr e);
public abstract boolean detectContextCastEndFromCall(StaticInvokeExpr e);