@Override public int hashCode() { return cs.hashCode(); }
@Override public String toString() { return "CallStringContext: " + cs.toString(); }
@Override public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] receiver) { if (callee == null) { throw new IllegalArgumentException("callee is null"); } if (callee.isWalaSynthetic()) { SyntheticMethod s = (SyntheticMethod) callee; if (s.isFactoryMethod()) { return new CallStringContext(new CallString(site, caller.getMethod())); } } return null; }
@Override protected Collection<CGNode> getConstructorCallers(ScopeMappingInstanceKey smik, Pair<String, String> name) { // in JavaScript, the 'new' instruction is wrapped in a synthetic constructor method. we want the // caller of that constructor method, which we obtain from the context for the constructor method final Context creatorContext = smik.getCreator().getContext(); CGNode callerOfConstructor = (CGNode) creatorContext.get(ContextKey.CALLER); Collection<CGNode> result = null; if (callerOfConstructor != null) { return Collections.singleton(callerOfConstructor); } else { CallString cs = (CallString) creatorContext.get(CallStringContextSelector.CALL_STRING); if (cs != null) { IMethod[] methods = cs.getMethods(); assert methods.length == 1; IMethod m = methods[0]; result = builder.getCallGraph().getNodes(m.getReference()); } } if (result == null) { IClassHierarchy cha = smik.getCreator().getClassHierarchy(); MethodReference ref = MethodReference.findOrCreate(JavaScriptLoader.JS, TypeReference.findOrCreate(cha.getLoaders()[0].getReference(), name.snd), AstMethodReference.fnAtomStr, AstMethodReference.fnDesc.toString()); final IMethod method = cha.resolveMethod(ref); if (method != null) { return builder.getCallGraph().getNodes(method.getReference()); } } return result; }
@Override public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] receiver) { if (callee == null) { throw new IllegalArgumentException("callee is null"); } if (callee.isWalaSynthetic()) { SyntheticMethod s = (SyntheticMethod) callee; if (s.isFactoryMethod()) { return new CallStringContext(new CallString(site, caller.getMethod())); } } return null; }
@Override protected Collection<CGNode> getConstructorCallers(ScopeMappingInstanceKey smik, Pair<String, String> name) { // in JavaScript, the 'new' instruction is wrapped in a synthetic constructor method. we want the // caller of that constructor method, which we obtain from the context for the constructor method final Context creatorContext = smik.getCreator().getContext(); CGNode callerOfConstructor = (CGNode) creatorContext.get(ContextKey.CALLER); Collection<CGNode> result = null; if (callerOfConstructor != null) { return Collections.singleton(callerOfConstructor); } else { CallString cs = (CallString) creatorContext.get(CallStringContextSelector.CALL_STRING); if (cs != null) { IMethod[] methods = cs.getMethods(); assert methods.length == 1; IMethod m = methods[0]; result = builder.getCallGraph().getNodes(m.getReference()); } } if (result == null) { IClassHierarchy cha = smik.getCreator().getClassHierarchy(); MethodReference ref = MethodReference.findOrCreate(JavaScriptLoader.JS, TypeReference.findOrCreate(cha.getLoaders()[0].getReference(), name.snd), AstMethodReference.fnAtomStr, AstMethodReference.fnDesc.toString()); final IMethod method = cha.resolveMethod(ref); if (method != null) { return builder.getCallGraph().getNodes(method.getReference()); } } return result; }
@Override public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] actualParameters) { Context baseContext = base.getCalleeTarget(caller, site, callee, actualParameters); final boolean exceedsRecursionBound = exceedsRecursionBound(baseContext, 0); if (!exceedsRecursionBound) { return baseContext; } else if (callee instanceof JavaScriptConstructor) { // for constructors, we want to keep some basic context sensitivity to // avoid horrible imprecision return new CallStringContext(new CallString(site, caller.getMethod())); } else { // TODO somehow k-limit more smartly? return Everywhere.EVERYWHERE; } }
@Override public int hashCode() { return cs.hashCode(); }
@Override public String toString() { return "CallStringContext: " + cs.toString(); }
@Override public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] actualParameters) { Context baseContext = base.getCalleeTarget(caller, site, callee, actualParameters); final boolean exceedsRecursionBound = exceedsRecursionBound(baseContext, 0); if (!exceedsRecursionBound) { return baseContext; } else if (callee instanceof JavaScriptConstructor) { // for constructors, we want to keep some basic context sensitivity to // avoid horrible imprecision return new CallStringContext(new CallString(site, caller.getMethod())); } else { // TODO somehow k-limit more smartly? return Everywhere.EVERYWHERE; } }
@Override public int hashCode() { return cs.hashCode() * base.hashCode(); }
@Override public String toString() { return "CallStringContextPair: " + cs.toString() + ':' + base.toString(); }
protected CallString getCallString(CGNode caller, CallSiteReference site, IMethod target) { int length = getLength(caller, site, target); if (length > 0) { if (caller.getContext().get(CALL_STRING) != null) { return new CallString(site, caller.getMethod(), length, (CallString) caller.getContext().get(CALL_STRING)); } else { return new CallString(site, caller.getMethod()); } } else { return null; } }
@Override public int hashCode() { return cs.hashCode() * base.hashCode(); }
@Override public String toString() { return "CallStringContextPair: " + cs.toString() + ':' + base.toString(); }
protected CallString getCallString(CGNode caller, CallSiteReference site, IMethod target) { int length = getLength(caller, site, target); if (length > 0) { if (caller.getContext().get(CALL_STRING) != null) { return new CallString(site, caller.getMethod(), length, (CallString) caller.getContext().get(CALL_STRING)); } else { return new CallString(site, caller.getMethod()); } } else { return null; } }