@Override public <E> void eagerlyPutMethodAnalysis(Class<E> analysisClass, @Nonnull MethodDescriptor methodDescriptor, E analysisObject) { try { ClassContext classContext = getClassAnalysis(ClassContext.class, methodDescriptor.getClassDescriptor()); assert analysisClass.isInstance(analysisObject); classContext.putMethodAnalysis(analysisClass, methodDescriptor, analysisObject); } catch (CheckedAnalysisException e) { IllegalStateException ise = new IllegalStateException("Unexpected exception adding method analysis to cache"); ise.initCause(e); throw ise; } }
@Override public void purgeMethodAnalyses(@Nonnull MethodDescriptor methodDescriptor) { try { ClassContext classContext = getClassAnalysis(ClassContext.class, methodDescriptor.getClassDescriptor()); classContext.purgeMethodAnalyses(methodDescriptor); } catch (CheckedAnalysisException e) { IllegalStateException ise = new IllegalStateException("Unexpected exception purging method analyses from cache"); ise.initCause(e); throw ise; } }
public void addCalledMethod(MethodDescriptor m) { assert m.getClassDescriptor().getClassName().indexOf('.') == -1; calledMethods.add(createXMethod(m)); }
@Override public XMethod findMethod(MethodDescriptor descriptor) { if (!descriptor.getClassDescriptor().equals(this)) { throw new IllegalArgumentException(); } return findMatchingMethod(descriptor); }
@Override protected void writeKey(Writer writer, MethodDescriptor method) throws IOException { writer.write(method.getClassDescriptor().toDottedClassName()); writer.write(","); writer.write(method.getName()); writer.write(","); writer.write(method.getSignature()); writer.write(","); XMethod xMethod = XFactory.createXMethod(method); writer.write(Integer.toString(xMethod.getAccessFlags() & 0xf)); } }
@Override public UsagesRequiringNonNullValues analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException { // ClassContext classContext = getClassContext(jclass); ClassContext classContext = analysisCache.getClassAnalysis(ClassContext.class, descriptor.getClassDescriptor()); Method method = getMethod(analysisCache, descriptor); return DerefFinder.getAnalysis(classContext, method); } }
protected UnresolvedXMethod(MethodDescriptor m) { super(m.getClassDescriptor().getDottedClassName(), m.getName(), m.getSignature(), m.isStatic() ? Const.ACC_STATIC : 0); if (XFactory.DEBUG_UNRESOLVED) { System.out.println("Unresolved xmethod: " + this); } }
public static SourceLineAnnotation fromVisitedInstruction(MethodDescriptor methodDescriptor, int position) { try { IAnalysisCache analysisCache = Global.getAnalysisCache(); JavaClass jclass = analysisCache.getClassAnalysis(JavaClass.class, methodDescriptor.getClassDescriptor()); Method method = analysisCache.getMethodAnalysis(Method.class, methodDescriptor); return fromVisitedInstruction(jclass, method, position); } catch (CheckedAnalysisException e) { return createReallyUnknown(methodDescriptor.getClassDescriptor().toDottedClassName()); } }
/** * @param m method to check * @return array of argument numbers (0-based) which this method writes into or null if we don't know anything about this method */ private static int changedArg(MethodDescriptor m) { if(m.equals(ARRAY_COPY)) { return 2; } if(m.getName().equals("toArray") && m.getSignature().equals("([Ljava/lang/Object;)[Ljava/lang/Object;") && Subtypes2.instanceOf(m.getClassDescriptor(), "java.util.Collection")) { return 0; } if ((m.getName().equals("sort") || m.getName().equals("fill") || m.getName().equals("reverse") || m.getName().equals( "shuffle")) && (m.getSlashedClassName().equals("java/util/Arrays") || m.getSlashedClassName().equals("java/util/Collections"))) { return 0; } return -1; }
@Override public @CheckForNull JumpInfo analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException { Method method = analysisCache.getMethodAnalysis(Method.class, descriptor); JavaClass jclass = getJavaClass(analysisCache, descriptor.getClassDescriptor()); Code code = method.getCode(); if (code == null) { return null; } JumpStackComputation branchAnalysis = new JumpStackComputation(descriptor); return computeJumpInfo(jclass, method, branchAnalysis); }
/** * Convenience method for generating a method signature in human readable * form. * * @param methodDescriptor * a MethodDescriptor * @return the formatted version of that signature */ public static String convertMethodSignature(MethodDescriptor methodDescriptor) { return convertMethodSignature(methodDescriptor.getClassDescriptor().toDottedClassName(), methodDescriptor.getName(), methodDescriptor.getSignature()); }
/** * Add source line annotation for given Location in a method. * * @param methodDescriptor * the method * @param location * the Location in the method * @return this BugInstance */ @Nonnull public BugInstance addSourceLine(MethodDescriptor methodDescriptor, Location location) { try { IAnalysisCache analysisCache = Global.getAnalysisCache(); ClassContext classContext = analysisCache.getClassAnalysis(ClassContext.class, methodDescriptor.getClassDescriptor()); Method method = analysisCache.getMethodAnalysis(Method.class, methodDescriptor); return addSourceLine(classContext, method, location); } catch (CheckedAnalysisException e) { return addSourceLine(SourceLineAnnotation.createReallyUnknown(methodDescriptor.getClassDescriptor() .toDottedClassName())); } }
/** * @param m method to check * @return true if we may assume that given unseen method has no side effect */ private static boolean hasNoSideEffectUnknown(MethodDescriptor m) { if(m.isStatic() && m.getName().equals(Const.STATIC_INITIALIZER_NAME)) { // No side effect for class initializer of unseen class return true; } if(!m.isStatic() && m.getName().equals("toString") && m.getSignature().equals("()Ljava/lang/String;")) { // We assume no side effect for unseen toString methods return true; } if(!m.isStatic() && m.getName().equals("hashCode") && m.getSignature().equals("()I")) { // We assume no side effect for unseen hashCode methods return true; } if(m.isStatic() && m.getName().equals("values") && m.getSignature().startsWith("()")) { // We assume no side effect for unseen enums return Subtypes2.instanceOf(m.getClassDescriptor(), "java.lang.Enum"); } return false; }
/** * Constructor. * * @param methodDescriptor * the MethodDescriptor indicating the method it is unprofitable * to analyze */ public MethodUnprofitableException(MethodDescriptor methodDescriptor) { super("Appears unprofitable to analyze " + methodDescriptor.toString()); this.method = XFactory.createXMethod(methodDescriptor.getClassDescriptor().toDottedClassName(), methodDescriptor.getName(), methodDescriptor.getSignature(), methodDescriptor.isStatic()); }
public MatchMethodEntry(MethodDescriptor method, ObligationPolicyDatabaseActionType action, ObligationPolicyDatabaseEntryType entryType, Obligation... obligations) { this(new SubtypeTypeMatcher(method.getClassDescriptor()), new ExactStringMatcher(method.getName()), new ExactStringMatcher(method.getSignature()), method.isStatic(), action, entryType, obligations); }
/** * Execute dataflow analyses (only if required). * * @throws CheckedAnalysisException */ public void execute() throws CheckedAnalysisException { method = Global.getAnalysisCache().getMethodAnalysis(Method.class, methodDescriptor); ClassContext classContext = Global.getAnalysisCache().getClassAnalysis(ClassContext.class, methodDescriptor.getClassDescriptor()); BitSet bytecodeSet = classContext.getBytecodeSet(method); if (bytecodeSet == null) { return; } if (bytecodeSet.get(Const.MONITORENTER) || bytecodeSet.get(Const.MONITOREXIT)) { this.lockDataflow = classContext.getLockDataflow(method); } else if (method.isSynchronized()) { this.vnaDataflow = classContext.getValueNumberDataflow(method); // will // need // this // later } }
@Override public CallListDataflow analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException { CallListAnalysis analysis = new CallListAnalysis(getCFG(analysisCache, descriptor), getDepthFirstSearch(analysisCache, descriptor), getConstantPoolGen(analysisCache, descriptor.getClassDescriptor())); CallListDataflow dataflow = new CallListDataflow(getCFG(analysisCache, descriptor), analysis); dataflow.execute(); return dataflow; } }
@Override public LoadDataflow analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException { MethodGen methodGen = getMethodGen(analysisCache, descriptor); if (methodGen == null) { return null; } LoadAnalysis analysis = new LoadAnalysis(getDepthFirstSearch(analysisCache, descriptor), getConstantPoolGen( analysisCache, descriptor.getClassDescriptor())); LoadDataflow dataflow = new LoadDataflow(getCFG(analysisCache, descriptor), analysis); dataflow.execute(); return dataflow; } }
@Override public StoreDataflow analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException { MethodGen methodGen = getMethodGen(analysisCache, descriptor); if (methodGen == null) { return null; } StoreAnalysis analysis = new StoreAnalysis(getDepthFirstSearch(analysisCache, descriptor), getConstantPoolGen( analysisCache, descriptor.getClassDescriptor())); StoreDataflow dataflow = new StoreDataflow(getCFG(analysisCache, descriptor), analysis); dataflow.execute(); return dataflow; } }
@Override public Method analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException { JavaClass jclass = analysisCache.getClassAnalysis(JavaClass.class, descriptor.getClassDescriptor()); Method[] methodList = jclass.getMethods(); Method result = null; // As a side-effect, cache all of the Methods for this JavaClass for (Method method : methodList) { MethodDescriptor methodDescriptor = DescriptorFactory.instance().getMethodDescriptor( descriptor.getSlashedClassName(), method.getName(), method.getSignature(), method.isStatic()); // Put in cache eagerly analysisCache.eagerlyPutMethodAnalysis(Method.class, methodDescriptor, method); if (methodDescriptor.equals(descriptor)) { result = method; } } return result; }