diff --git a/sootup.java.core/src/main/java/sootup/java/core/views/JavaModuleView.java b/sootup.java.core/src/main/java/sootup/java/core/views/JavaModuleView.java index 1771fe527b9..ecbd71f10c4 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/views/JavaModuleView.java +++ b/sootup.java.core/src/main/java/sootup/java/core/views/JavaModuleView.java @@ -28,7 +28,6 @@ import java.util.stream.Stream; import javax.annotation.Nonnull; import sootup.core.SourceTypeSpecifier; -import sootup.core.cache.FullCache; import sootup.core.cache.provider.ClassCacheProvider; import sootup.core.cache.provider.FullCacheProvider; import sootup.core.inputlocation.AnalysisInputLocation; @@ -38,7 +37,6 @@ import sootup.core.signatures.PackageName; import sootup.core.types.ClassType; import sootup.java.core.*; -import sootup.java.core.language.JavaLanguage; import sootup.java.core.signatures.ModulePackageName; import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.JavaClassType; @@ -96,9 +94,12 @@ public JavaModuleView( @Nonnull ClassCacheProvider cacheProvider, @Nonnull Function classLoadingOptionsSpecifier, @Nonnull SourceTypeSpecifier sourceTypeSpecifier) { - super(inputLocations, cacheProvider, sourceTypeSpecifier); + super( + inputLocations, + cacheProvider, + sourceTypeSpecifier, + JavaModuleIdentifierFactory.getInstance()); this.moduleInfoAnalysisInputLocations = moduleInputLocations; - JavaModuleInfo unnamedModuleInfo = JavaModuleInfo.getUnnamedModuleInfo(); moduleInfoMap.put(unnamedModuleInfo.getModuleSignature(), unnamedModuleInfo); } @@ -163,7 +164,7 @@ private boolean isPackageVisibleToModule( @Override @Nonnull - protected Optional getAbstractClass(@Nonnull ClassType type) { + protected Optional getClassSource(@Nonnull ClassType type) { Optional cs = moduleInfoAnalysisInputLocations.stream() @@ -177,7 +178,7 @@ protected Optional getAbstractClass(@Nonnull ClassType type return cs; } - return super.getAbstractClass(type); + return super.getClassSource(type); } @Nonnull @@ -433,7 +434,7 @@ public synchronized Collection getTransitiveClasses(@Nonnull Modu @Nonnull @Override public JavaModuleIdentifierFactory getIdentifierFactory() { - return (JavaModuleIdentifierFactory) new JavaLanguage(9).getIdentifierFactory(); + return (JavaModuleIdentifierFactory) identifierFactory; } @Nonnull @@ -479,40 +480,4 @@ public Set getNamedModules() { } return modules; } - - @Override - @Nonnull - protected synchronized Collection resolveAll() { - if (isFullyResolved && cache instanceof FullCache) { - return cache.getClasses().stream() - .map(clazz -> (JavaSootClass) clazz) - .collect(Collectors.toList()); - } - - Collection> resolvedClassesOpts = - inputLocations.stream() - .flatMap(location -> location.getClassSources(this).stream()) - .map(this::buildClassFrom) - .collect(Collectors.toList()); - - Collection> resolvedModuleClassesOpts = - moduleInfoAnalysisInputLocations.stream() - .flatMap(location -> location.getClassSources(this).stream()) - .map(this::buildClassFrom) - .collect(Collectors.toList()); - - Collection> combinedResolvedClassesOpts = - Stream.concat(resolvedClassesOpts.stream(), resolvedModuleClassesOpts.stream()) - .collect(Collectors.toList()); - - Collection resolvedClasses = - combinedResolvedClassesOpts.stream() - .filter(Optional::isPresent) - .map(Optional::get) - .collect(Collectors.toList()); - - isFullyResolved = true; - - return resolvedClasses; - } } diff --git a/sootup.java.core/src/main/java/sootup/java/core/views/JavaView.java b/sootup.java.core/src/main/java/sootup/java/core/views/JavaView.java index aad8eaef21b..94311b9b003 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/views/JavaView.java +++ b/sootup.java.core/src/main/java/sootup/java/core/views/JavaView.java @@ -22,10 +22,7 @@ * #L% */ -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import javax.annotation.Nonnull; import sootup.core.SourceTypeSpecifier; @@ -41,7 +38,6 @@ import sootup.core.types.ClassType; import sootup.core.views.AbstractView; import sootup.java.core.*; -import sootup.java.core.language.JavaLanguage; import sootup.java.core.types.AnnotationType; /** @@ -52,6 +48,7 @@ * @author Jan Martin Persch */ public class JavaView extends AbstractView { + @Nonnull protected final JavaIdentifierFactory identifierFactory; @Nonnull protected final List inputLocations; @Nonnull protected final ClassCache cache; @@ -83,16 +80,41 @@ public JavaView( @Nonnull List inputLocations, @Nonnull ClassCacheProvider cacheProvider, @Nonnull SourceTypeSpecifier sourceTypeSpecifier) { + this(inputLocations, cacheProvider, sourceTypeSpecifier, JavaIdentifierFactory.getInstance()); + } + + protected JavaView( + @Nonnull List inputLocations, + @Nonnull ClassCacheProvider cacheProvider, + @Nonnull SourceTypeSpecifier sourceTypeSpecifier, + @Nonnull JavaIdentifierFactory idf) { this.inputLocations = inputLocations; this.cache = cacheProvider.createCache(); this.sourceTypeSpecifier = sourceTypeSpecifier; + this.identifierFactory = idf; } /** Resolves all classes that are part of the view and stores them in the cache. */ @Override @Nonnull public synchronized Collection getClasses() { - return resolveAll(); + if (isFullyResolved && cache instanceof FullCache) { + return cache.getClasses().stream() + .map(clazz -> (JavaSootClass) clazz) + .collect(Collectors.toList()); + } + + Collection resolvedClasses = + inputLocations.stream() + .flatMap(location -> location.getClassSources(this).stream()) + .map(this::buildClassFrom) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + + isFullyResolved = true; + + return resolvedClasses; } /** Resolves the class matching the provided {@link ClassType ClassType}. */ @@ -104,7 +126,7 @@ public synchronized Optional getClass(@Nonnull ClassType type) { return Optional.of(cachedClass); } - Optional abstractClass = getAbstractClass(type); + Optional abstractClass = getClassSource(type); return abstractClass.flatMap(this::buildClassFrom); } @@ -112,36 +134,37 @@ public synchronized Optional getClass(@Nonnull ClassType type) { @Nonnull public Optional getMethod(@Nonnull MethodSignature signature) { final Optional aClass = getClass(signature.getDeclClassType()); - if (!aClass.isPresent()) { - return Optional.empty(); + if (aClass.isPresent()) { + return aClass.get().getMethod(signature.getSubSignature()); } - return aClass.get().getMethod(signature.getSubSignature()); + return Optional.empty(); } @Override @Nonnull public Optional getField(@Nonnull FieldSignature signature) { final Optional aClass = getClass(signature.getDeclClassType()); - if (!aClass.isPresent()) { - return Optional.empty(); + if (aClass.isPresent()) { + return aClass.get().getField(signature.getSubSignature()); } - return aClass.get().getField(signature.getSubSignature()); + return Optional.empty(); } @Nonnull @Override public JavaIdentifierFactory getIdentifierFactory() { - return (JavaIdentifierFactory) new JavaLanguage(8).getIdentifierFactory(); + return identifierFactory; } /** Returns the number of classes that are currently stored in the cache. */ - public int getNumberOfStoredClasses() { + public int getCachedClassesCount() { return cache.size(); } @Nonnull - protected Optional getAbstractClass(@Nonnull ClassType type) { - return inputLocations.stream() + protected Optional getClassSource(@Nonnull ClassType type) { + return inputLocations + .parallelStream() .map(location -> location.getClassSource(type, this)) .filter(Optional::isPresent) // like javas behaviour: if multiple matching Classes(ClassTypes) are found on the @@ -157,12 +180,12 @@ protected synchronized Optional buildClassFrom(AbstractClassSourc ClassType classType = classSource.getClassType(); JavaSootClass theClass; - if (!cache.hasClass(classType)) { + if (cache.hasClass(classType)) { + theClass = (JavaSootClass) cache.getClass(classType); + } else { theClass = (JavaSootClass) classSource.buildClass(sourceTypeSpecifier.sourceTypeFor(classSource)); cache.putClass(classType, theClass); - } else { - theClass = (JavaSootClass) cache.getClass(classType); } if (theClass.getType() instanceof AnnotationType) { @@ -172,29 +195,4 @@ protected synchronized Optional buildClassFrom(AbstractClassSourc return Optional.of(theClass); } - - @Nonnull - protected synchronized Collection resolveAll() { - if (isFullyResolved && cache instanceof FullCache) { - return cache.getClasses().stream() - .map(clazz -> (JavaSootClass) clazz) - .collect(Collectors.toList()); - } - - Collection> resolvedClassesOpts = - inputLocations.stream() - .flatMap(location -> location.getClassSources(this).stream()) - .map(this::buildClassFrom) - .collect(Collectors.toList()); - - Collection resolvedClasses = - resolvedClassesOpts.stream() - .filter(Optional::isPresent) - .map(Optional::get) - .collect(Collectors.toList()); - - isFullyResolved = true; - - return resolvedClasses; - } } diff --git a/sootup.tests/src/test/java/sootup/tests/CacheTest.java b/sootup.tests/src/test/java/sootup/tests/CacheTest.java index c1fc1ab7dde..258cdfed766 100644 --- a/sootup.tests/src/test/java/sootup/tests/CacheTest.java +++ b/sootup.tests/src/test/java/sootup/tests/CacheTest.java @@ -39,41 +39,41 @@ public static void setupProject() { @Test public void fullCacheTest() { JavaView view = new JavaView(inputLocations, new FullCacheProvider()); - assertEquals(0, view.getNumberOfStoredClasses()); + assertEquals(0, view.getCachedClassesCount()); ClassType miniAppClassType = view.getIdentifierFactory().getClassType("MiniApp"); view.getClass(miniAppClassType); - assertEquals(1, view.getNumberOfStoredClasses()); + assertEquals(1, view.getCachedClassesCount()); ClassType utilsOperationClassType = view.getIdentifierFactory().getClassType("utils.Operations"); view.getClass(utilsOperationClassType); - assertEquals(2, view.getNumberOfStoredClasses()); + assertEquals(2, view.getCachedClassesCount()); view.getClasses(); - assertEquals(6, view.getNumberOfStoredClasses()); + assertEquals(6, view.getCachedClassesCount()); } /** Test the {@link sootup.core.cache.LRUCache} class */ @Test public void lruCacheTest() { JavaView view = new JavaView(inputLocations, new LRUCacheProvider(1)); - assertEquals(0, view.getNumberOfStoredClasses()); + assertEquals(0, view.getCachedClassesCount()); ClassType miniAppClassType = view.getIdentifierFactory().getClassType("MiniApp"); view.getClass(miniAppClassType); - assertEquals(1, view.getNumberOfStoredClasses()); + assertEquals(1, view.getCachedClassesCount()); ClassType utilsOperationClassType = view.getIdentifierFactory().getClassType("utils.Operations"); view.getClass(utilsOperationClassType); - assertEquals(1, view.getNumberOfStoredClasses()); + assertEquals(1, view.getCachedClassesCount()); view.getClasses(); - assertEquals(1, view.getNumberOfStoredClasses()); + assertEquals(1, view.getCachedClassesCount()); JavaView newView = new JavaView(inputLocations, new LRUCacheProvider()); newView.getClasses(); - assertEquals(6, newView.getNumberOfStoredClasses()); + assertEquals(6, newView.getCachedClassesCount()); } }