@Override public IAnalysisCache createAnalysisCache(IClassPath classPath, BugReporter errorLogger) { IAnalysisCache analysisCache = new AnalysisCache(classPath, errorLogger); return analysisCache; } }
@Override public <E> E getMethodAnalysis(Class<E> analysisClass, @Nonnull MethodDescriptor methodDescriptor) throws CheckedAnalysisException { requireNonNull(methodDescriptor, "methodDescriptor is null"); ClassContext classContext = getClassAnalysis(ClassContext.class, methodDescriptor.getClassDescriptor()); Object object = classContext.getMethodAnalysis(analysisClass, methodDescriptor); if (object == null) { try { object = analyzeMethod(classContext, analysisClass, methodDescriptor); if (object == null) { object = NULL_ANALYSIS_RESULT; } } catch (RuntimeException e) { object = new AbnormalAnalysisResult(e); } catch (CheckedAnalysisException e) { object = new AbnormalAnalysisResult(e); } classContext.putMethodAnalysis(analysisClass, methodDescriptor, object); } if (Debug.VERIFY_INTEGRITY && object == null) { throw new IllegalStateException("AnalysisFactory failed to produce a result object"); } if (object instanceof AbnormalAnalysisResult) { return checkedCast(analysisClass, ((AbnormalAnalysisResult) object).returnOrThrow()); } return checkedCast(analysisClass, object); }
/** * Adds the data for given analysis type from given map to the cache * @param analysisClass non null analysis type * @param map non null, pre-filled map with analysis data for given type */ public <E> void reuseClassAnalysis(Class<E> analysisClass, Map<ClassDescriptor, Object> map) { Map<ClassDescriptor, Object> myMap = classAnalysisMap.get(analysisClass); if (myMap != null) { myMap.putAll(map); } else { myMap = createMap(classAnalysisEngineMap, analysisClass); myMap.putAll(map); classAnalysisMap.put(analysisClass, myMap); } }
Map<ClassDescriptor, Object> descriptorMap = findOrCreateDescriptorMap(classAnalysisMap, classAnalysisEngineMap, analysisClass); throw new IllegalArgumentException("No analysis engine registered to produce " + analysisClass.getName()); Profiler profiler = getProfiler(); return checkedCast(analysisClass, ((AbnormalAnalysisResult) analysisResult).returnOrThrow()); return checkedCast(analysisClass, analysisResult);
@Override public <E> E getDatabase(Class<E> databaseClass) { return getDatabase(databaseClass, false); } @Override
@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; } }
@SuppressWarnings("unchecked") private <E> Map<ClassDescriptor, E> getAllClassAnalysis(Class<E> analysisClass) { Map<ClassDescriptor, Object> descriptorMap = findOrCreateDescriptorMap(classAnalysisMap, classAnalysisEngineMap, analysisClass); return (Map<ClassDescriptor, E>) descriptorMap; }
@Override public <E> E probeClassAnalysis(Class<E> analysisClass, @Nonnull ClassDescriptor classDescriptor) { Map<ClassDescriptor, Object> descriptorMap = classAnalysisMap.get(analysisClass); if (descriptorMap == null) { return null; } return checkedCast(analysisClass, descriptorMap.get(classDescriptor)); }
@Override public void purgeAllMethodAnalysis() { // System.out.println("ZZZ : purging all method analyses"); try { Map<ClassDescriptor, ClassContext> map = getAllClassAnalysis(ClassContext.class); Collection<?> allClassContexts = map.values(); for (Object c : allClassContexts) { if (c instanceof ClassContext) { ((ClassContext) c).purgeAllMethodAnalyses(); } } } catch (ClassCastException e) { AnalysisContext.logError("Unable to purge method analysis", e); } }
/** * Analyze a method. * * @param classContext * ClassContext storing method analysis objects for method's * class * @param analysisClass * class the method analysis object should belong to * @param methodDescriptor * method descriptor identifying the method to analyze * @return the computed analysis object for the method * @throws CheckedAnalysisException */ @SuppressWarnings("unchecked") private <E> E analyzeMethod(ClassContext classContext, Class<E> analysisClass, MethodDescriptor methodDescriptor) throws CheckedAnalysisException { IMethodAnalysisEngine<E> engine = (IMethodAnalysisEngine<E>) methodAnalysisEngineMap.get(analysisClass); if (engine == null) { throw new IllegalArgumentException("No analysis engine registered to produce " + analysisClass.getName()); } Profiler profiler = getProfiler(); profiler.start(engine.getClass()); try { return engine.analyze(this, methodDescriptor); } finally { profiler.end(engine.getClass()); } }
Map<ClassDescriptor, Object> descriptorMap = findOrCreateDescriptorMap(classAnalysisMap, classAnalysisEngineMap, analysisClass); throw new IllegalArgumentException("No analysis engine registered to produce " + analysisClass.getName()); Profiler profiler = getProfiler(); return checkedCast(analysisClass, ((AbnormalAnalysisResult) analysisResult).returnOrThrow()); return checkedCast(analysisClass, analysisResult);
@Override public @CheckForNull <E> E getOptionalDatabase(Class<E> databaseClass) { return getDatabase(databaseClass, true); } public <E> E getDatabase(Class<E> databaseClass, boolean optional) {
@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; } }
@SuppressWarnings("unchecked") private <E> Map<ClassDescriptor, E> getAllClassAnalysis(Class<E> analysisClass) { Map<ClassDescriptor, Object> descriptorMap = findOrCreateDescriptorMap(classAnalysisMap, classAnalysisEngineMap, analysisClass); return (Map<ClassDescriptor, E>) descriptorMap; }
@Override public <E> E probeClassAnalysis(Class<E> analysisClass, @Nonnull ClassDescriptor classDescriptor) { Map<ClassDescriptor, Object> descriptorMap = classAnalysisMap.get(analysisClass); if (descriptorMap == null) { return null; } return checkedCast(analysisClass, descriptorMap.get(classDescriptor)); }
@Override public void purgeAllMethodAnalysis() { // System.out.println("ZZZ : purging all method analyses"); try { Map<ClassDescriptor, ClassContext> map = getAllClassAnalysis(ClassContext.class); Collection<?> allClassContexts = map.values(); for (Object c : allClassContexts) { if (c instanceof ClassContext) { ((ClassContext) c).purgeAllMethodAnalyses(); } } } catch (ClassCastException e) { AnalysisContext.logError("Unable to purge method analysis", e); } }
/** * Analyze a method. * * @param classContext * ClassContext storing method analysis objects for method's * class * @param analysisClass * class the method analysis object should belong to * @param methodDescriptor * method descriptor identifying the method to analyze * @return the computed analysis object for the method * @throws CheckedAnalysisException */ @SuppressWarnings("unchecked") private <E> E analyzeMethod(ClassContext classContext, Class<E> analysisClass, MethodDescriptor methodDescriptor) throws CheckedAnalysisException { IMethodAnalysisEngine<E> engine = (IMethodAnalysisEngine<E>) methodAnalysisEngineMap.get(analysisClass); if (engine == null) { throw new IllegalArgumentException("No analysis engine registered to produce " + analysisClass.getName()); } Profiler profiler = getProfiler(); profiler.start(engine.getClass()); try { return engine.analyze(this, methodDescriptor); } finally { profiler.end(engine.getClass()); } }
@Override public <E> E getMethodAnalysis(Class<E> analysisClass, @Nonnull MethodDescriptor methodDescriptor) throws CheckedAnalysisException { requireNonNull(methodDescriptor, "methodDescriptor is null"); ClassContext classContext = getClassAnalysis(ClassContext.class, methodDescriptor.getClassDescriptor()); Object object = classContext.getMethodAnalysis(analysisClass, methodDescriptor); if (object == null) { try { object = analyzeMethod(classContext, analysisClass, methodDescriptor); if (object == null) { object = NULL_ANALYSIS_RESULT; } } catch (RuntimeException e) { object = new AbnormalAnalysisResult(e); } catch (CheckedAnalysisException e) { object = new AbnormalAnalysisResult(e); } classContext.putMethodAnalysis(analysisClass, methodDescriptor, object); } if (Debug.VERIFY_INTEGRITY && object == null) { throw new IllegalStateException("AnalysisFactory failed to produce a result object"); } if (object instanceof AbnormalAnalysisResult) { return checkedCast(analysisClass, ((AbnormalAnalysisResult) object).returnOrThrow()); } return checkedCast(analysisClass, object); }
@Override public <E> E getDatabase(Class<E> databaseClass) { return getDatabase(databaseClass, false); } @Override
@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; } }