From a11d106e536ba2ee5c171da57ba4eb02a024f9c2 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Thu, 2 Nov 2023 17:29:58 +0100 Subject: [PATCH 01/57] add single file testcase for having a packagename --- .../ClassWithPackageName.class | Bin 0 -> 251 bytes .../ClassWithPackageName.java | 44 ++++++++++++++++++ .../PathBasedAnalysisInputLocationTest.java | 38 +++++++++------ 3 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 shared-test-resources/ClassWithPackageName.class create mode 100644 shared-test-resources/ClassWithPackageName.java diff --git a/shared-test-resources/ClassWithPackageName.class b/shared-test-resources/ClassWithPackageName.class new file mode 100644 index 0000000000000000000000000000000000000000..1e2f8516a00fe61ace6342f0e6dbdb875fbe51c5 GIT binary patch literal 251 zcmZuryAA{MBGm~~bhK0x;@t}*Hu7&6wGb7*`4yO=c7 literal 0 HcmV?d00001 diff --git a/shared-test-resources/ClassWithPackageName.java b/shared-test-resources/ClassWithPackageName.java new file mode 100644 index 00000000000..472d74885c6 --- /dev/null +++ b/shared-test-resources/ClassWithPackageName.java @@ -0,0 +1,44 @@ +/* + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html. + * + * This file is a derivative of code released by the University of + * California under the terms listed below. + * + * WALA JDT Frontend is Copyright (c) 2008 The Regents of the + * University of California (Regents). Provided that this notice and + * the following two paragraphs are included in any distribution of + * Refinement Analysis Tools or its derivative work, Regents agrees + * not to assert any of Regents' copyright rights in Refinement + * Analysis Tools against recipient for recipient's reproduction, + * preparation of derivative works, public display, public + * performance, distribution or sublicensing of Refinement Analysis + * Tools and derivative works, in source code and object code form. + * This agreement not to assert does not confer, by implication, + * estoppel, or otherwise any license or rights in any intellectual + * property of Regents, including, but not limited to, any patents + * of Regents or Regents' employees. + * + * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, + * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, + * INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE + * AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE AND FURTHER DISCLAIMS ANY STATUTORY + * WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE AND ACCOMPANYING + * DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS + * IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, + * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ +package ClassesPackageName; + +// need inner classes to run this test + +public class ClassWithPackageName { + int foo; +} \ No newline at end of file diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java index d9123df9dee..e143ca55366 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java @@ -70,31 +70,31 @@ public void multiReleaseJar() { final JavaProject project_min = JavaProject.builder(new JavaLanguage(Integer.MIN_VALUE)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, null)) + .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) .build(); final JavaView view_min = project_min.createView(); final JavaProject project_8 = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, null)) + .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) .build(); final JavaView view_8 = project_8.createView(); final JavaProject project_9 = JavaProject.builder(new JavaLanguage(9)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, null)) + .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) .build(); final JavaView view_9 = project_9.createView(); final JavaProject project_10 = JavaProject.builder(new JavaLanguage(10)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, null)) + .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) .build(); final JavaView view_10 = project_10.createView(); final JavaProject project_max = JavaProject.builder(new JavaLanguage(Integer.MAX_VALUE)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, null)) + .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) .build(); final JavaView view_max = project_max.createView(); @@ -184,7 +184,7 @@ public void modularMultiReleaseJar() { final JavaProject project_8 = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mmrj, null)) + .addInputLocation(PathBasedAnalysisInputLocation.create(mmrj, SourceType.Application)) .build(); final JavaView view_8 = project_8.createView(); @@ -194,7 +194,7 @@ public void modularMultiReleaseJar() { .enableModules() .addInputLocation( (ModuleInfoAnalysisInputLocation) - PathBasedAnalysisInputLocation.create(mmrj, null)) + PathBasedAnalysisInputLocation.create(mmrj, SourceType.Application)) .build(); final JavaModuleView view_9 = project_9.createView(); @@ -271,7 +271,7 @@ public void modularMultiReleaseJar() { @Test public void testApk() { PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(apk, null); + PathBasedAnalysisInputLocation.create(apk, SourceType.Application); final ClassType mainClass = getIdentifierFactory().getClassType("de.upb.futuresoot.fields.MainActivity"); testClassReceival(pathBasedNamespace, Collections.singletonList(mainClass), 1392); @@ -280,7 +280,7 @@ public void testApk() { @Test public void testSingleClass() { PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(cls, null); + PathBasedAnalysisInputLocation.create(cls, SourceType.Application); ArrayList sigs = new ArrayList<>(); sigs.add(getIdentifierFactory().getClassType("Employee")); testClassReceival(pathBasedNamespace, sigs, 1); @@ -289,13 +289,25 @@ public void testSingleClass() { @Test(expected = IllegalArgumentException.class) public void testSingleClassDoesNotExist() { PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(Paths.get("NonExisting.class"), null); + PathBasedAnalysisInputLocation.create( + Paths.get("NonExisting.class"), SourceType.Application); + } + + @Test + public void testSingleClassWPackageName() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create( + Paths.get("../shared-test-resources/ClassWithPackageName.class"), + SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("ClassesPackageName.ClassWithPackageName")); + testClassReceival(pathBasedNamespace, sigs, 1); } @Test public void testJar() { PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(jar, null); + PathBasedAnalysisInputLocation.create(jar, SourceType.Application); ArrayList sigs = new ArrayList<>(); sigs.add(getIdentifierFactory().getClassType("Employee", "ds")); sigs.add(getIdentifierFactory().getClassType("MiniApp")); @@ -305,7 +317,7 @@ public void testJar() { @Test public void testWar() { PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(war, null); + PathBasedAnalysisInputLocation.create(war, SourceType.Application); final ClassType warClass1 = getIdentifierFactory().getClassType("SimpleWarRead"); testClassReceival(pathBasedNamespace, Collections.singletonList(warClass1), 19); } @@ -423,7 +435,7 @@ void runtimeContains(View view, String classname, String packageName) { public void testRuntimeJar() { PathBasedAnalysisInputLocation pathBasedNamespace = PathBasedAnalysisInputLocation.create( - Paths.get(System.getProperty("java.home") + "/lib/rt.jar"), null); + Paths.get(System.getProperty("java.home") + "/lib/rt.jar"), SourceType.Application); JavaView v = JavaProject.builder(new JavaLanguage(8)) From 51523af4cbdab4d8c6a6ec432157e0227d1bdc28 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Thu, 2 Nov 2023 18:12:56 +0100 Subject: [PATCH 02/57] progress --- .../java/sootup/core/IdentifierFactory.java | 10 --- .../common/expr/AbstractFloatBinopExpr.java | 5 +- .../JrtFileSystemAnalysisInputLocation.java | 16 ++++- .../PathBasedAnalysisInputLocation.java | 60 +++++++++++------ .../java/core/JavaIdentifierFactory.java | 18 ------ .../signatures/JavaIdentifierFactoryTest.java | 20 ------ .../parser/JimpleAnalysisInputLocation.java | 64 +++++++------------ 7 files changed, 82 insertions(+), 111 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/IdentifierFactory.java b/sootup.core/src/main/java/sootup/core/IdentifierFactory.java index cd747f44586..ec1370a861c 100644 --- a/sootup.core/src/main/java/sootup/core/IdentifierFactory.java +++ b/sootup.core/src/main/java/sootup/core/IdentifierFactory.java @@ -22,7 +22,6 @@ * #L% */ -import java.nio.file.Path; import java.util.List; import java.util.Optional; import javax.annotation.Nonnull; @@ -244,13 +243,4 @@ FieldSignature getFieldSignature( * @return the array type */ ArrayType getArrayType(Type baseType, int dim); - - /** - * Builds class type from path. - * - * @param file the file - * @param rootDirectory root directory in which the file is. - * @return the class type - */ - ClassType fromPath(Path rootDirectory, Path file); } diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/AbstractFloatBinopExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/AbstractFloatBinopExpr.java index 71383da7037..5c834a32808 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/AbstractFloatBinopExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/AbstractFloatBinopExpr.java @@ -24,7 +24,6 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; -import sootup.core.jimple.basic.Value; import sootup.core.types.PrimitiveType; import sootup.core.types.Type; import sootup.core.types.UnknownType; @@ -38,8 +37,8 @@ protected AbstractFloatBinopExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) @Nonnull @Override public Type getType() { - Value op1 = getOp1(); - Value op2 = getOp2(); + Immediate op1 = getOp1(); + Immediate op2 = getOp2(); Type op1t = op1.getType(); Type op2t = op2.getType(); diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java index d3803134f6f..f606b6670c4 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nonnull; +import org.apache.commons.io.FilenameUtils; import sootup.core.IdentifierFactory; import sootup.core.frontend.AbstractClassSource; import sootup.core.frontend.ClassProvider; @@ -212,7 +213,11 @@ private JavaClassType fromPath( // else use the module system and create fully class signature // we do not have a base directory here, the moduleDir is actually not a directory - JavaClassType sig = (JavaClassType) identifierFactory.fromPath(Paths.get(""), filename); + final Path rootDirectory = Paths.get(""); + + final String fullyQualifiedName = fromPath(rootDirectory, filename); + + JavaClassType sig = (JavaClassType) identifierFactory.getClassType(fullyQualifiedName); if (identifierFactory instanceof JavaModuleIdentifierFactory) { return ((JavaModuleIdentifierFactory) identifierFactory) @@ -223,6 +228,15 @@ private JavaClassType fromPath( return sig; } + @Nonnull + private static String fromPath(@Nonnull Path rootDirectory, @Nonnull Path filename) { + return FilenameUtils.removeExtension( + filename + .subpath(rootDirectory.getNameCount(), filename.getNameCount()) + .toString() + .replace(filename.getFileSystem().getSeparator(), ".")); + } + @Nonnull @Override public Optional getModuleInfo(ModuleSignature sig, View view) { diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index 36ba5d3b30f..a53a4cf7e0a 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -7,6 +7,7 @@ import com.googlecode.dex2jar.tools.Dex2jarCmd; import java.io.*; import java.nio.file.*; +import java.nio.file.FileSystem; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -14,6 +15,7 @@ import java.util.jar.JarInputStream; import java.util.jar.Manifest; import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.annotation.Nonnull; @@ -21,6 +23,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import org.apache.commons.io.FilenameUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -39,7 +42,10 @@ import sootup.core.views.View; import sootup.java.bytecode.frontend.AsmJavaClassProvider; import sootup.java.bytecode.frontend.AsmModuleSource; -import sootup.java.core.*; +import sootup.java.core.JavaModuleIdentifierFactory; +import sootup.java.core.JavaModuleInfo; +import sootup.java.core.JavaSootClass; +import sootup.java.core.ModuleInfoAnalysisInputLocation; import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.JavaClassType; import sootup.java.core.types.ModuleJavaClassType; @@ -145,18 +151,22 @@ Collection> walkDirectory( @Nonnull Path dirPath, @Nonnull IdentifierFactory factory, @Nonnull ClassProvider classProvider) { - try { - final FileType handledFileType = classProvider.getHandledFileType(); - final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; - return Files.walk(dirPath) - .filter( + + final FileType handledFileType = classProvider.getHandledFileType(); + final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; + try (final Stream walk = Files.walk(dirPath)) { + return walk.filter( filePath -> PathUtils.hasExtension(filePath, handledFileType) && !filePath.toString().endsWith(moduleInfoFilename)) .flatMap( - p -> - StreamUtils.optionalToStream( - classProvider.createClassSource(this, p, factory.fromPath(dirPath, p)))) + p -> { + final String fullyQualifiedName = fromPath(dirPath, p); + + return StreamUtils.optionalToStream( + classProvider.createClassSource( + this, p, factory.getClassType(fullyQualifiedName))); + }) .collect(Collectors.toList()); } catch (IOException e) { @@ -164,6 +174,15 @@ Collection> walkDirectory( } } + @Nonnull + private static String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClass) { + return FilenameUtils.removeExtension( + packageNamePathAndClass + .subpath(baseDirPath.getNameCount(), packageNamePathAndClass.getNameCount()) + .toString() + .replace(packageNamePathAndClass.getFileSystem().getSeparator(), ".")); + } + @Nonnull protected Optional> getClassSourceInternal( @Nonnull JavaClassType signature, @@ -220,8 +239,11 @@ public Collection> getClassSources( AsmJavaClassProvider classProvider = new AsmJavaClassProvider(view); IdentifierFactory factory = view.getIdentifierFactory(); Path dirPath = this.path.getParent(); + + final String fullyQualifiedName = fromPath(dirPath, path); + Optional> classSource = - classProvider.createClassSource(this, path, factory.fromPath(dirPath, path)); + classProvider.createClassSource(this, path, factory.getClassType(fullyQualifiedName)); return Collections.singletonList(classSource.get()); } } @@ -272,18 +294,20 @@ private MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nullable Sourc try { FileSystem fs = fileSystemCache.get(path); final Path archiveRoot = fs.getPath("/"); - tmp = - Files.list(archiveRoot.getFileSystem().getPath("/META-INF/versions/")) - .map(dir -> dir.getFileName().toString().replace("/", "")) - .mapToInt(Integer::new) - .sorted() - .toArray(); + try (final Stream list = + Files.list(archiveRoot.getFileSystem().getPath("/META-INF/versions/"))) { + tmp = + list.map(dir -> dir.getFileName().toString().replace("/", "")) + .mapToInt(Integer::new) + .sorted() + .toArray(); + } + } catch (IOException | ExecutionException e) { e.printStackTrace(); tmp = new int[] {}; } availableVersions = tmp; - discoverInputLocations(srcType); } @@ -293,7 +317,7 @@ private void discoverInputLocations(@Nullable SourceType srcType) { try { fs = fileSystemCache.get(path); } catch (ExecutionException e) { - e.printStackTrace(); + throw new RuntimeException(e); } final Path archiveRoot = fs.getPath("/"); final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java index 421ee70db9d..9c89e6fc0ac 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java +++ b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java @@ -25,13 +25,11 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.Maps; -import java.nio.file.Path; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.annotation.Nonnull; -import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.ClassUtils; import sootup.core.IdentifierFactory; import sootup.core.signatures.FieldSignature; @@ -229,22 +227,6 @@ public AnnotationType getAnnotationType(final String fullyQualifiedClassName) { (k) -> new AnnotationType(className, getPackageName(packageName))); } - @Override - @Nonnull - public JavaClassType fromPath(@Nonnull final Path rootDirectory, @Nonnull final Path file) { - - final int nameCountBaseDir = - rootDirectory.toString().isEmpty() ? 0 : rootDirectory.getNameCount(); - - String fullyQualifiedName = - FilenameUtils.removeExtension( - file.subpath(nameCountBaseDir, file.getNameCount()) - .toString() - .replace(file.getFileSystem().getSeparator(), ".")); - - return getClassType(fullyQualifiedName); - } - /** * Returns a unique PackageName. The method looks up a cache if it already contains a signature * with the given package name. If the cache lookup fails a new signature is created. diff --git a/sootup.java.core/src/test/java/sootup/java/core/signatures/JavaIdentifierFactoryTest.java b/sootup.java.core/src/test/java/sootup/java/core/signatures/JavaIdentifierFactoryTest.java index c3cc1cf74d4..4e733dc9661 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/signatures/JavaIdentifierFactoryTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/signatures/JavaIdentifierFactoryTest.java @@ -25,8 +25,6 @@ import static org.junit.Assert.*; import categories.Java8Test; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -113,24 +111,6 @@ public void getCompareClassSignature() { assertNotEquals(classSignature1, classSignature2); } - @Test - public void sigFromPath() { - JavaIdentifierFactory typeFactory = JavaIdentifierFactory.getInstance(); - Path rootDirectory = Paths.get(""); - Path p = Paths.get("java/lang/System.class"); - ClassType classSignature = typeFactory.fromPath(rootDirectory, p); - assertEquals(classSignature.toString(), "java.lang.System"); - } - - @Test - public void sigFromPathStartsWithSlash() { - JavaIdentifierFactory typeFactory = JavaIdentifierFactory.getInstance(); - Path rootDirectory = Paths.get("/"); - Path p = Paths.get("/java/lang/System.class"); - ClassType classSignature = typeFactory.fromPath(rootDirectory, p); - assertEquals(classSignature.toString(), "java.lang.System"); - } - @Test public void getClassSignatureEmptyPackage() { JavaIdentifierFactory typeFactory = JavaIdentifierFactory.getInstance(); diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java index 6b4c77f9e5b..c428b864c1a 100644 --- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java +++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java @@ -5,19 +5,18 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; -import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.apache.commons.io.FilenameUtils; import sootup.core.IdentifierFactory; -import sootup.core.frontend.AbstractClassSource; import sootup.core.frontend.ClassProvider; import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.inputlocation.FileType; -import sootup.core.model.AbstractClass; import sootup.core.model.SootClass; import sootup.core.model.SourceType; import sootup.core.types.ClassType; @@ -31,19 +30,10 @@ public class JimpleAnalysisInputLocation>> walkDirectory( - @Nonnull Path dirPath, - @Nonnull IdentifierFactory factory, - @Nonnull ClassProvider> classProvider) { - try { - final FileType handledFileType = classProvider.getHandledFileType(); - return Files.walk(dirPath) - .filter(filePath -> PathUtils.hasExtension(filePath, handledFileType)) + public Collection> getClassSources(@Nonnull View view) { + IdentifierFactory factory = view.getIdentifierFactory(); + ClassProvider classProvider = new JimpleClassProvider<>(view.getBodyInterceptors(this)); + final FileType handledFileType = classProvider.getHandledFileType(); + + try (final Stream walk = Files.walk(path)) { + return walk.filter(filePath -> PathUtils.hasExtension(filePath, handledFileType)) .flatMap( - p -> - StreamUtils.optionalToStream( - classProvider.createClassSource(this, p, factory.fromPath(dirPath, p)))) + p -> { + String fullyQualifiedName = + FilenameUtils.removeExtension( + p.subpath(path.getNameCount(), p.getNameCount()) + .toString() + .replace(p.getFileSystem().getSeparator(), ".")); + + return StreamUtils.optionalToStream( + classProvider.createClassSource( + this, p, factory.getClassType(fullyQualifiedName))); + }) .collect(Collectors.toList()); } catch (IOException e) { @@ -93,13 +82,6 @@ List>> walkDirectory( } } - @Override - @Nonnull - public Collection> getClassSources(@Nonnull View view) { - return walkDirectory( - path, view.getIdentifierFactory(), new JimpleClassProvider(view.getBodyInterceptors(this))); - } - @Override @Nonnull public Optional> getClassSource( From e2313b897daf4201ad2438f4a9e661f179949d48 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Sat, 7 Oct 2023 15:33:26 +0200 Subject: [PATCH 03/57] add check that we load a compilation unit which has indeed the requested signature/fqdn/classtype --- .../java/bytecode/frontend/AsmJavaClassProvider.java | 11 ++++++++++- .../java/sootup/java/bytecode/frontend/AsmUtil.java | 5 +++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java index e6bb38027a2..3c59658dd48 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java @@ -59,7 +59,15 @@ public Optional> createClassSource( SootClassNode classNode = new SootClassNode(analysisInputLocation); try { - AsmUtil.initAsmClassSource(sourcePath, classNode); + final String actualClassSignature = AsmUtil.initAsmClassSource(sourcePath, classNode); + if (!actualClassSignature.replace('/', '.').equals(classType.toString())) { + throw new IllegalArgumentException( + "The given Classtype '" + + classType + + "' did not match the found ClassType in the compilation unit '" + + actualClassSignature + + "'. Possibly the AnalysisInputLocation points to a subfolder already including the PackageName directory while the ClassType you wanted to retrieve is missing a PackageName."); + } } catch (IOException | IllegalArgumentException exception) { logger.warn( "ASM could not resolve class source of " @@ -72,6 +80,7 @@ public Optional> createClassSource( } JavaClassType klassType = (JavaClassType) classType; + if (klassType instanceof ModuleJavaClassType && klassType.getClassName().equals(JavaModuleIdentifierFactory.MODULE_INFO_FILE)) { logger.warn("Can not create ClassSource from a module info descriptor! path:" + sourcePath); diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmUtil.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmUtil.java index ed306a13093..32800db7447 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmUtil.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmUtil.java @@ -67,13 +67,14 @@ private AsmUtil() {} * * @param classSource The source. * @param classNode The node to initialize + * @return the actual class signature found in the compilation unit */ - protected static void initAsmClassSource( + protected static String initAsmClassSource( @Nonnull Path classSource, @Nonnull ClassVisitor classNode) throws IOException { try (InputStream sourceFileInputStream = Files.newInputStream(classSource)) { ClassReader clsr = new ClassReader(sourceFileInputStream); - clsr.accept(classNode, ClassReader.SKIP_FRAMES); + return clsr.getClassName(); } } From f1d4487cc7af74895e1bfeab25e1ff491c3e29c7 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Wed, 8 Nov 2023 13:49:44 +0100 Subject: [PATCH 04/57] simplify --- .../inputlocation/PathBasedAnalysisInputLocation.java | 5 ++--- .../java/bytecode/interceptors/UnusedLocalEliminator.java | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index a53a4cf7e0a..57c692d40f7 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -704,7 +704,7 @@ public Optional> getClassSource( * * @param warFilePath The path to war file to be extracted */ - protected void extractWarFile(Path warFilePath, final Path destDirectory) { + private void extractWarFile(Path warFilePath, final Path destDirectory) { int extractedSize = 0; try { File dest = destDirectory.toFile(); @@ -716,8 +716,7 @@ protected void extractWarFile(Path warFilePath, final Path destDirectory) { dest.deleteOnExit(); } - ZipInputStream zis = - new ZipInputStream(Files.newInputStream(Paths.get(warFilePath.toString()))); + ZipInputStream zis = new ZipInputStream(Files.newInputStream(warFilePath)); ZipEntry zipEntry; while ((zipEntry = zis.getNextEntry()) != null) { Path filepath = destDirectory.resolve(zipEntry.getName()); diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/UnusedLocalEliminator.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/UnusedLocalEliminator.java index 078c8820de5..1a11da3f20e 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/UnusedLocalEliminator.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/UnusedLocalEliminator.java @@ -52,7 +52,7 @@ public void interceptBody(@Nonnull Body.BodyBuilder builder, @Nonnull View vi Set locals = new LinkedHashSet<>(); // Traverse statements copying all used uses and defs - for (Stmt stmt : builder.getStmtGraph()) { + for (Stmt stmt : builder.getStmtGraph().getNodes()) { for (Value value : stmt.getUsesAndDefs()) { if (value instanceof Local) { Local local = (Local) value; From 2c5d73e6767009bde3cf7ba15631c8cef12a8c1a Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Wed, 22 Nov 2023 13:42:09 +0100 Subject: [PATCH 05/57] Body: cleanup validators (they will be implemented as a BodyInterceptor); dont copy StmtGrapg if already not mutable; --- .../core/graph/MutableBlockStmtGraph.java | 7 ++ .../src/main/java/sootup/core/model/Body.java | 89 ++++++------------- .../java/sootup/core/model/SootClass.java | 4 +- .../typeresolving/CastCounter.java | 2 +- .../typeresolving/TypeChecker.java | 4 +- .../typeresolving/TypeResolver.java | 1 - .../minimaltestsuite/java14/RecordTest.java | 3 +- .../java/core/JavaIdentifierFactory.java | 8 ++ 8 files changed, 47 insertions(+), 71 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java index aa961c2f61d..c8b53be8814 100644 --- a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java +++ b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java @@ -95,6 +95,13 @@ public MutableBlockStmtGraph(@Nonnull StmtGraph> graph) }); } + public static StmtGraph createUnmodifiableStmtGraph(StmtGraph stmtGraph) { + if (stmtGraph instanceof MutableStmtGraph) { + return ((MutableStmtGraph) stmtGraph).unmodifiableStmtGraph(); + } + return stmtGraph; + } + /** * Creates a Graph representation from the 'legacy' representation i.e. a List of Stmts and Traps. */ diff --git a/sootup.core/src/main/java/sootup/core/model/Body.java b/sootup.core/src/main/java/sootup/core/model/Body.java index 706d8e7e8d8..0a96ab501fd 100644 --- a/sootup.core/src/main/java/sootup/core/model/Body.java +++ b/sootup.core/src/main/java/sootup/core/model/Body.java @@ -35,7 +35,6 @@ import sootup.core.signatures.MethodSignature; import sootup.core.util.Copyable; import sootup.core.util.EscapedWriter; -import sootup.core.util.ImmutableUtils; import sootup.core.util.printer.JimplePrinter; import sootup.core.validation.*; @@ -57,20 +56,6 @@ public class Body implements Copyable { /** The MethodSignature associated with this Body. */ @Nonnull private final MethodSignature methodSignature; - /** An array containing some validators in order to validate the JimpleBody */ - @Nonnull - private static final List validators = - ImmutableUtils.immutableList( - new LocalsValidator(), - new TrapsValidator(), - new StmtsValidator(), - new UsesValidator(), - new ValuesValidator(), - new CheckInitValidator(), - new CheckTypesValidator(), - new CheckVoidLocalesValidator(), - new CheckEscapingValidator()); - /** * Creates an body which is not associated to any method. * @@ -83,10 +68,8 @@ private Body( @Nonnull Position position) { this.methodSignature = methodSignature; this.locals = Collections.unmodifiableSet(locals); - this.graph = /* FIXME: [ms] make immutable when availabe */ - new MutableBlockStmtGraph(stmtGraph).unmodifiableStmtGraph(); + this.graph = MutableBlockStmtGraph.createUnmodifiableStmtGraph(stmtGraph); this.position = position; - checkInit(); } /** @@ -98,7 +81,7 @@ public static Local getThisLocal(StmtGraph stmtGraph) { for (Stmt stmt : stmtGraph.getNodes()) { if (stmt instanceof JIdentityStmt && ((JIdentityStmt) stmt).getRightOp() instanceof JThisRef) { - return (Local) ((JIdentityStmt) stmt).getLeftOp(); + return ((JIdentityStmt) stmt).getLeftOp(); } } throw new RuntimeException("couldn't find *this* assignment"); @@ -119,36 +102,18 @@ public int getLocalCount() { return locals.size(); } - private void runValidation(BodyValidator validator) { - final List exceptionList = new ArrayList<>(); - validator.validate(this, exceptionList); - if (!exceptionList.isEmpty()) { - throw exceptionList.get(0); - } - } - - /** Verifies that a Value is not used in more than one place. */ - // TODO: #535 implement validator public void validateValues() { runValidation(new - // ValuesValidator());} - - /** Verifies that each Local of getUsesAndDefs() is in this body's locals Chain. */ - // TODO: #535 implement validator public void validateLocals() {runValidation(new - // LocalsValidator());} - - /** Verifies that each use in this Body has a def. */ - // TODO: #535 implement validator public void validateUses() { runValidation(new - // UsesValidator()); } - private void checkInit() { - runValidation(new CheckInitValidator()); - } - /** Returns a backed chain of the locals declared in this Body. */ public Set getLocals() { return locals; } - /** Returns an unmodifiable view of the traps found in this Body. */ + /** + * Returns an unmodifiable view of the traps found in this Body. @Deprecated the exceptional flow + * information is already integrated into the StmtGraphs BasicBlocks.getExceptionalFlows() - + * exists to make porting tools from Soot easier + */ @Nonnull + @Deprecated() public List getTraps() { return graph.getTraps(); } @@ -156,18 +121,18 @@ public List getTraps() { /** Return unit containing the \@this-assignment * */ @Nullable public Stmt getThisStmt() { - for (Stmt u : getStmts()) { - if (u instanceof JIdentityStmt) { - if (((JIdentityStmt) u).getRightOp() instanceof JThisRef) { - return u; + for (Stmt stmt : graph) { + if (stmt instanceof JIdentityStmt) { + if (((JIdentityStmt) stmt).getRightOp() instanceof JThisRef) { + return stmt; } } else { - // TODO: possible optimization see getParameterLocals() + // TODO: possible optimisation see getParameterLocals() // break; } } return null; - // throw new RuntimeException("couldn't find this-assignment!" + " in " + + // throw new IllegalArgumentException("couldn't find this-assignment!" + " in " + // getMethodSignature()); } @@ -178,24 +143,22 @@ public Local getThisLocal() { if (thisStmt == null) { return null; } - return (Local) thisStmt.getLeftOp(); + return thisStmt.getLeftOp(); } /** Return LHS of the first identity stmt assigning from \@parameter i. */ @Nonnull public Local getParameterLocal(int i) { - for (Stmt s : getStmts()) { - if (s instanceof JIdentityStmt) { - if (((JIdentityStmt) s).getRightOp() instanceof JParameterRef) { - JIdentityStmt idStmt = (JIdentityStmt) s; + for (Stmt stmt : graph) { + // TODO: possible optimisation see getParameterLocals() + if (stmt instanceof JIdentityStmt) { + if (((JIdentityStmt) stmt).getRightOp() instanceof JParameterRef) { + JIdentityStmt idStmt = (JIdentityStmt) stmt; JParameterRef pr = (JParameterRef) idStmt.getRightOp(); if (pr.getIndex() == i) { - return (Local) idStmt.getLeftOp(); + return idStmt.getLeftOp(); } } - } else { - // TODO: possible optimization see getParameterLocals() - // break; } } throw new IllegalArgumentException("There exists no Parameter Local with index " + i + "!"); @@ -213,7 +176,7 @@ public Collection getParameterLocals() { final List retVal = new ArrayList<>(); // TODO: [ms] performance: don't iterate over all stmt -> lazy vs freedom/error tolerance -> use // fixed index positions at the beginning? - for (Stmt u : graph.getNodes()) { + for (Stmt u : graph) { if (u instanceof JIdentityStmt) { JIdentityStmt idStmt = (JIdentityStmt) u; if (idStmt.getRightOp() instanceof JParameterRef) { @@ -232,7 +195,9 @@ public Collection getParameterLocals() { } /** - * returns the control flow graph that represents this body into a linear List of statements. + * returns the control flow graph that represents this body into a linear List of statements. for + * more detailed information of the underlying CFG - or just parts of it - have a look at + * getStmtGraph() * * @return the statements in this Body */ @@ -276,10 +241,6 @@ public boolean isStmtBranchTarget(@Nonnull Stmt targetStmt) { return getStmtGraph().isStmtBranchTarget(targetStmt); } - public void validateIdentityStatements() { - runValidation(new IdentityStatementsValidator()); - } - /** Returns the first non-identity stmt in this body. */ @Nonnull public Stmt getFirstNonIdentityStmt() { diff --git a/sootup.core/src/main/java/sootup/core/model/SootClass.java b/sootup.core/src/main/java/sootup/core/model/SootClass.java index a3e8155d431..9ff92b69ef0 100644 --- a/sootup.core/src/main/java/sootup/core/model/SootClass.java +++ b/sootup.core/src/main/java/sootup/core/model/SootClass.java @@ -225,12 +225,12 @@ public String print() { /** Returns true if this class is an application class. */ public boolean isApplicationClass() { - return sourceType.equals(SourceType.Application); + return sourceType == SourceType.Application; } /** Returns true if this class is a library class. */ public boolean isLibraryClass() { - return sourceType.equals(SourceType.Library); + return sourceType == SourceType.Library; } /** Convenience method returning true if this class is private. */ diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/CastCounter.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/CastCounter.java index 658c07e1408..2677c6e516c 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/CastCounter.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/CastCounter.java @@ -143,7 +143,7 @@ public void visit(@Nonnull Value value, @Nonnull Type stdType, @Nonnull Stmt stm newStmt = ((AbstractDefinitionStmt) stmt).withNewDef(new_local); } if (graph.containsNode(stmt)) { - builder.replaceStmt(stmt, newStmt); + graph.replaceNode(stmt, newStmt); this.stmt2NewStmt.put(oriStmt, newStmt); } } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/TypeChecker.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/TypeChecker.java index 1e895254001..887bbba2c31 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/TypeChecker.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/TypeChecker.java @@ -27,7 +27,7 @@ import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sootup.core.graph.StmtGraph; +import sootup.core.graph.MutableStmtGraph; import sootup.core.jimple.basic.LValue; import sootup.core.jimple.basic.Local; import sootup.core.jimple.basic.Value; @@ -56,7 +56,7 @@ public abstract class TypeChecker extends AbstractStmtVisitor { private Typing typing; protected final Body.BodyBuilder builder; - protected final StmtGraph graph; + protected final MutableStmtGraph graph; private static final Logger logger = LoggerFactory.getLogger(TypeChecker.class); diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/TypeResolver.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/TypeResolver.java index be3358008ae..098a1defa70 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/TypeResolver.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/typeresolving/TypeResolver.java @@ -195,7 +195,6 @@ private Collection applyAssignmentConstraint( Type t_old = actualTyping.getType(local); Type t_right = evalFunction.evaluate(actualTyping, defStmt.getRightOp(), defStmt, graph); if (t_right == null) { - // TODO: ms: is this correct to handle: null? workQueue.removeFirst(); continue; } diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java index 61fa413bd4e..e7a57def441 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java14/RecordTest.java @@ -48,7 +48,8 @@ public List expectedBodyStmts() { return Stream.of( "$l0 := @this: RecordTest", "$l1 := @parameter0: java.lang.Object", - "$stack2 = dynamicinvoke \"equals\" ($l0, $l1) (class \"LRecordTest;\", \"a;b\", methodhandle: \"REF_GET_FIELD\" , methodhandle: \"REF_GET_FIELD\" )", + "$stack2 = dynamicinvoke \"equals" + + "\" ($l0, $l1) (class \"LRecordTest;\", \"a;b\", methodhandle: \"REF_GET_FIELD\" , methodhandle: \"REF_GET_FIELD\" )", "return $stack2") .collect(Collectors.toCollection(ArrayList::new)); } diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java index 9c89e6fc0ac..727b6e4de22 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java +++ b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java @@ -54,6 +54,14 @@ public class JavaIdentifierFactory implements IdentifierFactory { @Nonnull private static final JavaIdentifierFactory INSTANCE = new JavaIdentifierFactory(); + @Nonnull + public final MethodSubSignature CTOR = + new MethodSubSignature("", Collections.emptyList(), VoidType.getInstance()); + + @Nonnull + public final MethodSubSignature STATIC_INITIALIZER = + new MethodSubSignature("", Collections.emptyList(), VoidType.getInstance()); + /** Caches the created PackageNames for packages. */ @Nonnull protected final Cache packageCache = From 68285809264cae4402f53d34f621484cfdc74759 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Thu, 23 Nov 2023 22:20:55 +0100 Subject: [PATCH 06/57] improve isCtor --- sootup.core/src/main/java/sootup/core/IdentifierFactory.java | 2 +- .../sootup/java/bytecode/frontend/AsmMethodSourceTest.java | 2 +- .../main/java/sootup/java/core/JavaIdentifierFactory.java | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/IdentifierFactory.java b/sootup.core/src/main/java/sootup/core/IdentifierFactory.java index 465dee44fec..eb3447d4b7d 100644 --- a/sootup.core/src/main/java/sootup/core/IdentifierFactory.java +++ b/sootup.core/src/main/java/sootup/core/IdentifierFactory.java @@ -246,7 +246,7 @@ FieldSignature getFieldSignature( boolean isStaticInitializerSubSignature(@Nonnull MethodSubSignature methodSubSignature); - boolean isConstructorSubSignature(@Nonnull MethodSubSignature methodSubSignature); + boolean isConstructorSubSignature(@Nonnull MethodSignature methodSignature); boolean isMainSubSignature(@Nonnull MethodSubSignature methodSubSignature); } diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/AsmMethodSourceTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/AsmMethodSourceTest.java index d5f54b0bacb..731a84d7ace 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/AsmMethodSourceTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/AsmMethodSourceTest.java @@ -46,7 +46,7 @@ public void testFix_StackUnderrun_convertPutFieldInsn_init() { Arrays.asList( "java.util.concurrent.Executor", "javax.management.MBeanNotificationInfo[]")); - assertTrue(idf.isConstructorSubSignature(mainMethodSignature.getSubSignature())); + assertTrue(idf.isConstructorSubSignature(mainMethodSignature)); final SootClass abstractClass = view.getClass(mainClassSignature).get(); diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java index e94f5ca0885..36901bd1948 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java +++ b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java @@ -66,8 +66,9 @@ public boolean isStaticInitializerSubSignature(@Nonnull MethodSubSignature metho } @Override - public boolean isConstructorSubSignature(@Nonnull MethodSubSignature methodSubSignature) { - return methodSubSignature.getName().equals(""); + public boolean isConstructorSubSignature(@Nonnull MethodSignature methodSignature) { + return methodSignature.getName().equals("") + && methodSignature.getType() == methodSignature.getDeclClassType(); } @Override From 6c49d803a629485b6e4922ef5d910ad41bf95c06 Mon Sep 17 00:00:00 2001 From: Markus Schmidt Date: Mon, 27 Nov 2023 18:11:31 +0100 Subject: [PATCH 07/57] fix tests where the bodybuilder was not copied anymore --- .../bytecode/inputlocation/PathBasedAnalysisInputLocation.java | 2 +- .../inputlocation/PathBasedAnalysisInputLocationTest.java | 2 +- .../bytecode/interceptors/ConstantPropagatorAndFolderTest.java | 2 ++ .../sootup/java/bytecode/interceptors/NopEliminatorTest.java | 1 + .../src/main/java/sootup/java/core/JavaIdentifierFactory.java | 2 +- 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index f89cfbdf0a6..40094b2c75b 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -231,7 +231,7 @@ protected Optional> getSingleClass( return classProvider.createClassSource(this, pathToClass, signature); } - private static class ClassFileBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { + public static class ClassFileBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { public ClassFileBasedAnalysisInputLocation( @Nonnull Path classFilePath, @Nonnull SourceType srcType) { super(classFilePath, srcType); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java index 98e48b7a62f..e6371aba3cc 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java @@ -296,7 +296,7 @@ public void testSingleClassDoesNotExist() { @Test public void testSingleClassWPackageName() { PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create( + new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( Paths.get("../shared-test-resources/ClassWithPackageName.class"), SourceType.Application); ArrayList sigs = new ArrayList<>(); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConstantPropagatorAndFolderTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConstantPropagatorAndFolderTest.java index 0115027299e..324e30bb444 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConstantPropagatorAndFolderTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConstantPropagatorAndFolderTest.java @@ -39,6 +39,8 @@ public class ConstantPropagatorAndFolderTest { public void testModification() { Body.BodyBuilder testBuilder = createBody(true); Body testBody = testBuilder.build(); + + testBuilder = Body.builder(testBody, testBuilder.getModifiers()); new ConstantPropagatorAndFolder().interceptBody(testBuilder, null); Body processedBody = testBuilder.build(); List originalStmts = testBody.getStmts(); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/NopEliminatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/NopEliminatorTest.java index b31546f57ac..87db95c41bd 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/NopEliminatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/NopEliminatorTest.java @@ -37,6 +37,7 @@ public void testJNopEnd() { Body.BodyBuilder builder = createBody(true); Body testBody = builder.build(); + builder = Body.builder(testBody, builder.getModifiers()); new NopEliminator().interceptBody(builder, null); Body processedBody = builder.build(); diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java index 36901bd1948..c3286ed3135 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java +++ b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java @@ -68,7 +68,7 @@ public boolean isStaticInitializerSubSignature(@Nonnull MethodSubSignature metho @Override public boolean isConstructorSubSignature(@Nonnull MethodSignature methodSignature) { return methodSignature.getName().equals("") - && methodSignature.getType() == methodSignature.getDeclClassType(); + && methodSignature.getType() == VoidType.getInstance(); } @Override From 82d58b9005ab04490a755460b043c472cc0b6513 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Thu, 11 Jan 2024 15:11:41 +0100 Subject: [PATCH 08/57] merge fixes --- .../PathBasedAnalysisInputLocation.java | 373 +-------- .../PathBasedAnalysisInputLocationTest.java | 737 +++++++++--------- .../parser/JimpleAnalysisInputLocation.java | 22 +- 3 files changed, 383 insertions(+), 749 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index 228297a614a..33921a76266 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -4,6 +4,7 @@ import java.nio.file.*; import java.nio.file.FileSystem; import java.util.*; +import java.util.concurrent.ExecutionException; import java.util.jar.Attributes; import java.util.jar.JarInputStream; import java.util.jar.Manifest; @@ -23,6 +24,7 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import sootup.core.IdentifierFactory; +import sootup.core.frontend.AbstractClassSource; import sootup.core.frontend.ClassProvider; import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; @@ -34,7 +36,9 @@ import sootup.core.util.StreamUtils; import sootup.core.views.View; import sootup.java.bytecode.frontend.AsmJavaClassProvider; +import sootup.java.bytecode.frontend.AsmModuleSource; import sootup.java.core.*; +import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.JavaClassType; /*- @@ -168,7 +172,7 @@ private static boolean isMultiReleaseJar(Path path) { Collection walkDirectory( @Nonnull Path dirPath, @Nonnull IdentifierFactory factory, - @Nonnull ClassProvider classProvider) { + @Nonnull ClassProvider classProvider) { final FileType handledFileType = classProvider.getHandledFileType(); final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; @@ -185,7 +189,8 @@ Collection walkDirectory( classProvider.createClassSource( this, p, factory.getClassType(fullyQualifiedName))); }) - .collect(Collectors.toList()); + .map(src -> (JavaSootClassSource) src) + .collect(Collectors.toList()); } catch (IOException e) { throw new IllegalArgumentException(e); @@ -237,6 +242,7 @@ protected Optional getSingleClass( } public static class ClassFileBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { + public ClassFileBasedAnalysisInputLocation( @Nonnull Path classFilePath, @Nonnull SourceType srcType) { this(classFilePath, srcType, Collections.emptyList()); @@ -265,8 +271,8 @@ public Collection getClassSources(@Nonnull View view) { final String fullyQualifiedName = fromPath(dirPath, path); - Optional> classSource = - classProvider.createClassSource(this, path, factory.getClassType(fullyQualifiedName)); + Optional classSource = + classProvider.createClassSource(this, path, factory.getClassType(fullyQualifiedName)) .map(src -> (JavaSootClassSource) src); return Collections.singletonList(classSource.get()); } } @@ -298,363 +304,6 @@ public Optional getClassSource( } } - public static class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation - implements ModuleInfoAnalysisInputLocation { - - @Nonnull private final int[] availableVersions; - - @Nonnull - private final Map> moduleInfoMap = - new HashMap<>(); - - @Nonnull - private final Map>> inputLocations = - new HashMap<>(); - - @Nonnull - private final List> baseInputLocations = new ArrayList<>(); - - boolean isResolved = false; - - private MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { - super(path, srcType); - - int[] tmp; - try { - FileSystem fs = fileSystemCache.get(path); - final Path archiveRoot = fs.getPath("/"); - try (final Stream list = - Files.list(archiveRoot.getFileSystem().getPath("/META-INF/versions/"))) { - tmp = - list.map(dir -> dir.getFileName().toString().replace("/", "")) - .mapToInt(Integer::new) - .sorted() - .toArray(); - } - - } catch (IOException | ExecutionException e) { - e.printStackTrace(); - tmp = new int[] {}; - } - availableVersions = tmp; - discoverInputLocations(srcType); - } - - /** Discovers all input locations for different java versions in this multi release jar */ - private void discoverInputLocations(@Nonnull SourceType srcType) { - FileSystem fs = null; - try { - fs = fileSystemCache.get(path); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } - final Path archiveRoot = fs.getPath("/"); - final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; - - baseInputLocations.add(PathBasedAnalysisInputLocation.create(archiveRoot, srcType)); - - String sep = archiveRoot.getFileSystem().getSeparator(); - - if (!isResolved) { - - for (int i = availableVersions.length - 1; i >= 0; i--) { - inputLocations.put(availableVersions[i], new ArrayList<>()); - - final Path versionRoot = - archiveRoot - .getFileSystem() - .getPath("/META-INF/versions/" + availableVersions[i] + sep); - - // only versions >= 9 support java modules - if (availableVersions[i] > 8) { - moduleInfoMap.put(availableVersions[i], new HashMap<>()); - try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { - for (Path entry : stream) { - - Path mi = path.resolve(moduleInfoFilename); - - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - - inputLocations.get(availableVersions[i]).add(inputLocation); - moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); - } - - if (Files.isDirectory(entry)) { - mi = versionRoot.resolve(moduleInfoFilename); - - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - - inputLocations.get(availableVersions[i]).add(inputLocation); - moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); - } - // else TODO [bh] can we have automatic modules here? - } - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - // if there was no module or the version is not > 8, we just add a directory based input - // location - if (inputLocations.get(availableVersions[i]).size() == 0) { - inputLocations - .get(availableVersions[i]) - .add(PathBasedAnalysisInputLocation.create(versionRoot, srcType)); - } - } - } - - isResolved = true; - } - - @Override - @Nonnull - public Optional> getClassSource( - @Nonnull ClassType type, @Nonnull View view) { - - Collection> il = - getBestMatchingInputLocationsRaw(view.getProject().getLanguage().getVersion()); - - Collection> baseIl = getBaseInputLocations(); - - if (type instanceof ModuleJavaClassType) { - il = - il.stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .collect(Collectors.toList()); - baseIl = - baseIl.stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .collect(Collectors.toList()); - } else { - il = - il.stream() - .filter(location -> !(location instanceof ModuleInfoAnalysisInputLocation)) - .collect(Collectors.toList()); - baseIl = - baseIl.stream() - .filter(location -> !(location instanceof ModuleInfoAnalysisInputLocation)) - .collect(Collectors.toList()); - } - - Optional> foundClass = - il.stream() - .map(location -> location.getClassSource(type, view)) - .filter(Optional::isPresent) - .limit(1) - .map(Optional::get) - .findAny(); - - if (foundClass.isPresent()) { - return foundClass; - } else { - return baseIl.stream() - .map(location -> location.getClassSource(type, view)) - .filter(Optional::isPresent) - .limit(1) - .map(Optional::get) - .findAny(); - } - } - - @Nonnull - @Override - public Collection> getModulesClassSources( - @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { - return inputLocations.get(view.getProject().getLanguage().getVersion()).stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .map( - location -> - ((ModuleInfoAnalysisInputLocation) location) - .getModulesClassSources(moduleSignature, view)) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } - - /** - * Returns the best matching input locations or the base input location. - * - * @param javaVersion version to find best match to - * @return best match or base input locations - */ - private Collection> getBestMatchingInputLocationsRaw( - int javaVersion) { - for (int i = availableVersions.length - 1; i >= 0; i--) { - - if (availableVersions[i] > javaVersion) continue; - - return new ArrayList<>(inputLocations.get(availableVersions[i])); - } - - return getBaseInputLocations(); - } - - private Collection> getBaseInputLocations() { - return baseInputLocations; - } - - @Override - @Nonnull - public Collection> getClassSources( - @Nonnull View view) { - Collection> il = - getBestMatchingInputLocationsRaw(view.getProject().getLanguage().getVersion()); - - Collection> result = - il.stream() - .map(location -> location.getClassSources(view)) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - if (il != getBaseInputLocations()) { - - Collection> baseSources = - getBaseInputLocations().stream() - .map(location -> location.getClassSources(view)) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - baseSources.forEach( - cs -> { - // do not add duplicate class sources - if (result.stream() - .noneMatch( - bestMatchCS -> - bestMatchCS - .getClassType() - .getFullyQualifiedName() - .equals(cs.getClassType().getFullyQualifiedName()))) { - result.add(cs); - } - }); - } - - return result; - } - - @Nonnull - @Override - public Optional getModuleInfo(ModuleSignature sig, View view) { - return Optional.ofNullable( - moduleInfoMap.get(view.getProject().getLanguage().getVersion()).get(sig)); - } - - @Nonnull - @Override - public Set getModules(View view) { - return inputLocations.get(view.getProject().getLanguage().getVersion()).stream() - .filter(e -> e instanceof ModuleInfoAnalysisInputLocation) - .map(e -> ((ModuleInfoAnalysisInputLocation) e).getModules(view)) - .flatMap(Set::stream) - .collect(Collectors.toSet()); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof PathBasedAnalysisInputLocation)) { - return false; - } - return path.equals(((PathBasedAnalysisInputLocation) o).path); - } - - @Override - public int hashCode() { - return path.hashCode(); - } - } - - private static class ApkAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation { - - private ApkAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { - super(path, srcType); - String jarPath = dex2jar(path); - this.path = Paths.get(jarPath); - } - - private String dex2jar(Path path) { - String apkPath = path.toAbsolutePath().toString(); - String outDir = "./tmp/"; - int start = apkPath.lastIndexOf(File.separator); - int end = apkPath.lastIndexOf(".apk"); - String outputFile = outDir + apkPath.substring(start + 1, end) + ".jar"; - Dex2jarCmd.main("-f", apkPath, "-o", outputFile); - return outputFile; - } - } - - static class ArchiveBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { - - // We cache the FileSystem instances as their creation is expensive. - // The Guava Cache is thread-safe (see JavaDoc of LoadingCache) hence this - // cache can be safely shared in a static variable. - protected static final LoadingCache fileSystemCache = - CacheBuilder.newBuilder() - .removalListener( - (RemovalNotification removalNotification) -> { - try { - removalNotification.getValue().close(); - } catch (IOException e) { - throw new RuntimeException( - "Could not close file system of " + removalNotification.getKey(), e); - } - }) - .expireAfterAccess(1, TimeUnit.SECONDS) - .build( - CacheLoader.from( - path -> { - try { - return FileSystems.newFileSystem( - Objects.requireNonNull(path), (ClassLoader) null); - } catch (IOException e) { - throw new RuntimeException("Could not open file system of " + path, e); - } - })); - - ArchiveBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { - super(path, srcType); - } - - @Override - @Nonnull - public Optional> getClassSource( - @Nonnull ClassType type, @Nonnull View view) { - try { - FileSystem fs = fileSystemCache.get(path); - final Path archiveRoot = fs.getPath("/"); - return getClassSourceInternal( - (JavaClassType) type, archiveRoot, new AsmJavaClassProvider(view)); - } catch (ExecutionException e) { - throw new RuntimeException("Failed to retrieve file system from cache for " + path, e); - } - } - - @Override - @Nonnull - public Collection> getClassSources( - @Nonnull View view) { - // we don't use the filesystem cache here as it could close the filesystem after the timeout - // while we are still iterating - try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) { - final Path archiveRoot = fs.getPath("/"); - return walkDirectory( - archiveRoot, view.getProject().getIdentifierFactory(), new AsmJavaClassProvider(view)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - private static final class WarArchiveAnalysisInputLocation extends DirectoryBasedAnalysisInputLocation { public List containedInputLocations = new ArrayList<>(); @@ -740,7 +389,7 @@ public Optional getClassSource( * * @param warFilePath The path to war file to be extracted */ - private void extractWarFile(Path warFilePath, final Path destDirectory) { + protected void extractWarFile(Path warFilePath, final Path destDirectory) { int extractedSize = 0; try { File dest = destDirectory.toFile(); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java index b416ba2ae3d..19ba99dff91 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java @@ -22,27 +22,36 @@ * #L% */ -import static junit.framework.TestCase.assertEquals; -import static org.junit.Assert.*; -import static org.junit.Assert.assertTrue; - import categories.Java8Test; -import java.io.File; -import java.nio.file.Paths; -import java.util.*; +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; +import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.inputlocation.EagerInputLocation; import sootup.core.jimple.basic.NoPositionInformation; -import sootup.core.model.*; +import sootup.core.model.ClassModifier; +import sootup.core.model.FieldModifier; +import sootup.core.model.SootClass; +import sootup.core.model.SourceType; import sootup.core.signatures.FieldSubSignature; import sootup.core.signatures.MethodSubSignature; import sootup.core.types.ClassType; import sootup.core.views.View; import sootup.java.core.*; +import sootup.java.core.language.JavaLanguage; +import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.JavaClassType; +import sootup.java.core.types.ModuleJavaClassType; +import sootup.java.core.views.JavaModuleView; import sootup.java.core.views.JavaView; +import java.io.File; +import java.nio.file.Paths; +import java.util.*; + +import static junit.framework.TestCase.assertEquals; +import static org.junit.Assert.*; + /** * @author Manuel Benz created on 06.06.18 * @author Kaustubh Kelkar updated on 16.04.2020 @@ -50,375 +59,349 @@ @Category(Java8Test.class) public class PathBasedAnalysisInputLocationTest extends AnalysisInputLocationTest { - @Test - public void multiReleaseJar() { - final ClassType classType = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - - final JavaProject project_min = - JavaProject.builder(new JavaLanguage(Integer.MIN_VALUE)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_min = project_min.createView(); - - final JavaProject project_8 = - JavaProject.builder(new JavaLanguage(8)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_8 = project_8.createView(); - - final JavaProject project_9 = - JavaProject.builder(new JavaLanguage(9)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_9 = project_9.createView(); - - final JavaProject project_10 = - JavaProject.builder(new JavaLanguage(10)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_10 = project_10.createView(); - - final JavaProject project_max = - JavaProject.builder(new JavaLanguage(Integer.MAX_VALUE)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_max = project_max.createView(); - - // for java10 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_10.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_10.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // assert that method is correctly resolved - Assert.assertTrue( - view_10 - .getClass(classType) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 9")); - - // for java 9 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_9.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // for java 8 - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_8 - .getClass(classType) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); - - // for max int - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_max.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // for min int - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_min.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_min.getClass(classType2).get().getClassSource().getSourcePath().toString()); - } - - @Test - public void modularMultiReleaseJar() { - final ClassType utilityNoModule = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - - final ModuleJavaClassType utilityModule = - JavaModuleIdentifierFactory.getInstance() - .getClassType("de.upb.swt.multirelease/de.upb.swt.multirelease.Utility"); - - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - - final JavaProject project_8 = - JavaProject.builder(new JavaLanguage(8)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mmrj, SourceType.Application)) - .build(); - final JavaView view_8 = project_8.createView(); - - final JavaModuleProject project_9 = - (JavaModuleProject) - JavaModuleProject.builder(new JavaLanguage(9)) - .enableModules() - .addInputLocation( - (ModuleInfoAnalysisInputLocation) - PathBasedAnalysisInputLocation.create(mmrj, SourceType.Application)) - .build(); - - final JavaModuleView view_9 = project_9.createView(); - - ModuleSignature moduleSignature = - JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); - - Assert.assertEquals(Collections.singleton(moduleSignature), view_9.getNamedModules()); - - Assert.assertTrue(view_9.getModuleInfo(moduleSignature).isPresent()); - - Assert.assertEquals(1, view_9.getModuleClasses(moduleSignature).size()); - - Assert.assertEquals( - "de.upb.swt.multirelease.Utility", - view_9.getModuleClasses(moduleSignature).stream() - .findAny() - .get() - .getType() - .getFullyQualifiedName()); - - // for java 9 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityModule).get().getClassSource().getSourcePath().toString()); - // different class will be returned if no module is specified - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_9 - .getClass(utilityModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 9")); - - // for java 8 - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - assertFalse(view_8.getClass(utilityModule).isPresent()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_8 - .getClass(utilityNoModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); - } - - @Test - public void testApk() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(apk, SourceType.Application); - final ClassType mainClass = - getIdentifierFactory().getClassType("de.upb.futuresoot.fields.MainActivity"); - testClassReceival(pathBasedNamespace, Collections.singletonList(mainClass), 1392); - } - - @Test - public void testSingleClass() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(cls, SourceType.Application); - ArrayList sigs = new ArrayList<>(); - sigs.add(getIdentifierFactory().getClassType("Employee")); - testClassReceival(pathBasedNamespace, sigs, 1); - } - - @Test(expected = IllegalArgumentException.class) - public void testSingleClassDoesNotExist() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create( - Paths.get("NonExisting.class"), SourceType.Application); - } - - @Test - public void testSingleClassWPackageName() { - PathBasedAnalysisInputLocation pathBasedNamespace = - new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( - Paths.get("../shared-test-resources/ClassWithPackageName.class"), - SourceType.Application); - ArrayList sigs = new ArrayList<>(); - sigs.add(getIdentifierFactory().getClassType("ClassesPackageName.ClassWithPackageName")); - testClassReceival(pathBasedNamespace, sigs, 1); - } - - @Test - public void testJar() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(jar, SourceType.Application); - ArrayList sigs = new ArrayList<>(); - sigs.add(getIdentifierFactory().getClassType("Employee", "ds")); - sigs.add(getIdentifierFactory().getClassType("MiniApp")); - testClassReceival(pathBasedNamespace, sigs, 6); - } - - @Test - public void testWar() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(war, SourceType.Application); - final ClassType warClass1 = getIdentifierFactory().getClassType("SimpleWarRead"); - testClassReceival(pathBasedNamespace, Collections.singletonList(warClass1), 19); - } - - @Test - public void testClassInWar() { - - String warFile = "../shared-test-resources/java-warApp/dummyWarApp.war"; - - assertTrue("File " + warFile + " not found.", new File(warFile).exists()); - - // Get the view - JavaView view = new JavaView(new JavaClassPathAnalysisInputLocation(warFile)); - - assertEquals(19, view.getClasses().size()); - - // Create java class signature - ClassType utilsClassSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); - - // Resolve signature to `SootClass` - JavaSootClass utilsClass = view.getClass(utilsClassSignature).get(); - - // Parse sub-signature for "setEmpSalary" method - MethodSubSignature optionalToStreamMethodSubSignature = - JavaIdentifierFactory.getInstance().parseMethodSubSignature("void setEmpSalary(int)"); - - // Get method for sub-signature - JavaSootMethod foundMethod = utilsClass.getMethod(optionalToStreamMethodSubSignature).get(); - assertNotNull(foundMethod.getBody()); - - // Print method - assertTrue("setEmpSalary".equalsIgnoreCase(foundMethod.getName())); - assertEquals("void", foundMethod.getReturnType().toString()); - assertEquals(1, foundMethod.getParameterCount()); - assertTrue( - foundMethod.getParameterTypes().stream().anyMatch(type -> "int".equals(type.toString()))); - - // Parse sub-signature for "empName" field - FieldSubSignature nameFieldSubSignature = - JavaIdentifierFactory.getInstance().parseFieldSubSignature("java.lang.String empName"); - - // Create the class signature - JavaClassType classSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); - - JavaSootField field = - new JavaSootField( - JavaIdentifierFactory.getInstance() - .getFieldSignature(classSignature, nameFieldSubSignature), - Collections.singleton(FieldModifier.PUBLIC), - null, - NoPositionInformation.getInstance()); - - // Build a soot class - JavaSootClass c = - new JavaSootClass( - new OverridingJavaClassSource( - new EagerInputLocation(), - null, - classSignature, - null, - null, - null, - Collections.singleton(field), - Collections.emptySet(), - null, - EnumSet.of(ClassModifier.PUBLIC), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList()), - SourceType.Application); - - assertEquals("java.lang.String", c.getField(nameFieldSubSignature).get().getType().toString()); - assertEquals("empName", c.getField(nameFieldSubSignature).get().getName()); - } - - void runtimeContains(View view, String classname, String packageName) { - final ClassType sig = getIdentifierFactory().getClassType(classname, packageName); - assertTrue(sig + " is not found in rt.jar", view.getClass(sig).isPresent()); - } - - @Test - public void testRuntimeJar() { - PathBasedAnalysisInputLocation pathBasedNamespace = new DefaultRTJarAnalysisInputLocation(); - - JavaView v = new JavaView(pathBasedNamespace); - - // test some standard jre classes - runtimeContains(v, "Object", "java.lang"); - runtimeContains(v, "List", "java.util"); - runtimeContains(v, "Map", "java.util"); - runtimeContains(v, "ArrayList", "java.util"); - runtimeContains(v, "HashMap", "java.util"); - runtimeContains(v, "Collection", "java.util"); - runtimeContains(v, "Comparator", "java.util"); - } - - /** - * Test for JavaClassPathAnalysisInputLocation. Specifying jar file with source type as Library. - * Expected - All input classes are of source type Library. - */ - @Test - public void testInputLocationLibraryMode() { - JavaView view = new JavaView(new DefaultRTJarAnalysisInputLocation()); - - Collection classes = new HashSet<>(); // Set to track the classes to check - - for (SootClass aClass : view.getClasses()) { - if (!aClass.isLibraryClass()) { - classes.add(aClass); - } + @Test + public void multiReleaseJar() { + final ClassType classType = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); + final ClassType classType2 = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); + + final JavaView view_min = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(1))); + final JavaView view_8 = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(8))); + final JavaView view_9 = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(9))); + final JavaView view_10 = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(10))); + final JavaView view_max = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(Integer.MAX_VALUE))); + + // for java10 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_10.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_10.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // assert that method is correctly resolved + Assert.assertTrue( + view_10 + .getClass(classType) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 9")); + + // for java 9 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_9.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // for java 8 + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_8.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_8 + .getClass(classType) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 8")); + + // for max int + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_max.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // for min int + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_min.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_min.getClass(classType2).get().getClassSource().getSourcePath().toString()); + } + + @Test + public void modularMultiReleaseJar() { + final ClassType utilityNoModule = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); + + final ModuleJavaClassType utilityModule = + JavaModuleIdentifierFactory.getInstance() + .getClassType("de.upb.swt.multirelease/de.upb.swt.multirelease.Utility"); + + final ClassType classType2 = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); + + MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation = new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); + final JavaView view_8 = new JavaView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation)); + + final JavaModuleView view_9 = new JavaModuleView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation), Collections.emptyList()); + + ModuleSignature moduleSignature = + JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); + + Assert.assertEquals(Collections.singleton(moduleSignature), view_9.getNamedModules()); + + Assert.assertTrue(view_9.getModuleInfo(moduleSignature).isPresent()); + + Assert.assertEquals(1, view_9.getModuleClasses(moduleSignature).size()); + + Assert.assertEquals( + "de.upb.swt.multirelease.Utility", + view_9.getModuleClasses(moduleSignature).stream() + .findAny() + .get() + .getType() + .getFullyQualifiedName()); + + // for java 9 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_9.getClass(utilityModule).get().getClassSource().getSourcePath().toString()); + // different class will be returned if no module is specified + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_9.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_9 + .getClass(utilityModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 9")); + + // for java 8 + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_8.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); + assertFalse(view_8.getClass(utilityModule).isPresent()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_8 + .getClass(utilityNoModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 8")); + } + + @Test + public void testApk() { + PathBasedAnalysisInputLocation pathBasedNamespace = new ApkAnalysisInputLocation(apk, SourceType.Application); + final ClassType mainClass = + getIdentifierFactory().getClassType("de.upb.futuresoot.fields.MainActivity"); + testClassReceival(pathBasedNamespace, Collections.singletonList(mainClass), 1392); } - assertEquals("User Defined class found, expected none", 0, classes.size()); - } + @Test + public void testSingleClass() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create(cls, SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("Employee")); + testClassReceival(pathBasedNamespace, sigs, 1); + } + + @Test(expected = IllegalArgumentException.class) + public void testSingleClassDoesNotExist() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create( + Paths.get("NonExisting.class"), SourceType.Application); + } + + @Test + public void testPackageName() { + PathBasedAnalysisInputLocation pathBasedNamespace = + new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( + Paths.get("../shared-test-resources/ClassWithPackageName.class"), // FIXME: to issue example + SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("ClassesPackageName.ClassWithPackageName")); + + JavaView javaView = new JavaView(pathBasedNamespace); + assertTrue(javaView.getClasses().stream().allMatch( c -> c.getType().toString().equals("") && c.getType().toString().equals("") )); // FIXME + + } + + @Test + public void testSingleClassWPackageName() { + AnalysisInputLocation pathBasedNamespace = new JavaClassPathAnalysisInputLocation("../shared-test-resources/ClassWithPackageName.class", SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("ClassesPackageName.ClassWithPackageName")); + testClassReceival(pathBasedNamespace, sigs, 1); + } + + @Test + public void testJar() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create(jar, SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("Employee", "ds")); + sigs.add(getIdentifierFactory().getClassType("MiniApp")); + testClassReceival(pathBasedNamespace, sigs, 6); + } + + @Test + public void testWar() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create(war, SourceType.Application); + final ClassType warClass1 = getIdentifierFactory().getClassType("SimpleWarRead"); + testClassReceival(pathBasedNamespace, Collections.singletonList(warClass1), 19); + } + + @Test + public void testClassInWar() { + + String warFile = "../shared-test-resources/java-warApp/dummyWarApp.war"; + + assertTrue("File " + warFile + " not found.", new File(warFile).exists()); + + // Get the view + JavaView view = new JavaView(new JavaClassPathAnalysisInputLocation(warFile)); + + assertEquals(19, view.getClasses().size()); + + // Create java class signature + ClassType utilsClassSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); + + // Resolve signature to `SootClass` + JavaSootClass utilsClass = view.getClass(utilsClassSignature).get(); + + // Parse sub-signature for "setEmpSalary" method + MethodSubSignature optionalToStreamMethodSubSignature = + JavaIdentifierFactory.getInstance().parseMethodSubSignature("void setEmpSalary(int)"); + + // Get method for sub-signature + JavaSootMethod foundMethod = utilsClass.getMethod(optionalToStreamMethodSubSignature).get(); + assertNotNull(foundMethod.getBody()); + + // Print method + assertTrue("setEmpSalary".equalsIgnoreCase(foundMethod.getName())); + assertEquals("void", foundMethod.getReturnType().toString()); + assertEquals(1, foundMethod.getParameterCount()); + assertTrue( + foundMethod.getParameterTypes().stream().anyMatch(type -> "int".equals(type.toString()))); + + // Parse sub-signature for "empName" field + FieldSubSignature nameFieldSubSignature = + JavaIdentifierFactory.getInstance().parseFieldSubSignature("java.lang.String empName"); + + // Create the class signature + JavaClassType classSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); + + JavaSootField field = + new JavaSootField( + JavaIdentifierFactory.getInstance() + .getFieldSignature(classSignature, nameFieldSubSignature), + Collections.singleton(FieldModifier.PUBLIC), + null, + NoPositionInformation.getInstance()); + + // Build a soot class + JavaSootClass c = + new JavaSootClass( + new OverridingJavaClassSource( + new EagerInputLocation(), + null, + classSignature, + null, + null, + null, + Collections.singleton(field), + Collections.emptySet(), + null, + EnumSet.of(ClassModifier.PUBLIC), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList()), + SourceType.Application); + + assertEquals("java.lang.String", c.getField(nameFieldSubSignature).get().getType().toString()); + assertEquals("empName", c.getField(nameFieldSubSignature).get().getName()); + } + + void runtimeContains(View view, String classname, String packageName) { + final ClassType sig = getIdentifierFactory().getClassType(classname, packageName); + assertTrue(sig + " is not found in rt.jar", view.getClass(sig).isPresent()); + } + + @Test + public void testRuntimeJar() { + PathBasedAnalysisInputLocation pathBasedNamespace = new DefaultRTJarAnalysisInputLocation(); + + JavaView v = new JavaView(pathBasedNamespace); + + // test some standard jre classes + runtimeContains(v, "Object", "java.lang"); + runtimeContains(v, "List", "java.util"); + runtimeContains(v, "Map", "java.util"); + runtimeContains(v, "ArrayList", "java.util"); + runtimeContains(v, "HashMap", "java.util"); + runtimeContains(v, "Collection", "java.util"); + runtimeContains(v, "Comparator", "java.util"); + } + + /** + * Test for JavaClassPathAnalysisInputLocation. Specifying jar file with source type as Library. + * Expected - All input classes are of source type Library. + */ + @Test + public void testInputLocationLibraryMode() { + JavaView view = new JavaView(new DefaultRTJarAnalysisInputLocation()); + + Collection classes = new HashSet<>(); // Set to track the classes to check + + for (SootClass aClass : view.getClasses()) { + if (!aClass.isLibraryClass()) { + classes.add(aClass); + } + } + + assertEquals("User Defined class found, expected none", 0, classes.size()); + } } diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java index 6b154fa2ef8..07e3adf418a 100644 --- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java +++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java @@ -14,6 +14,7 @@ import sootup.core.frontend.ClassProvider; import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; +import sootup.core.inputlocation.FileType; import sootup.core.model.SourceType; import sootup.core.transform.BodyInterceptor; import sootup.core.types.ClassType; @@ -24,13 +25,13 @@ /** @author Markus Schmidt */ public class JimpleAnalysisInputLocation implements AnalysisInputLocation { final Path path; - private final List bodyInterceptors; - /** Variable to track if user has specified the SourceType. By default, it will be set to null. */ private final SourceType srcType; + @Nonnull + private final List bodyInterceptors; public JimpleAnalysisInputLocation(@Nonnull Path path) { - this(path, SourceType.Application); + this(path, SourceType.Application, Collections.emptyList()); } public JimpleAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { @@ -38,17 +39,18 @@ public JimpleAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcT } public JimpleAnalysisInputLocation( - @Nonnull Path path, - @Nullable SourceType srcType, - @Nonnull List bodyInterceptors) { - if (!Files.exists(path)) { - throw new IllegalArgumentException( + @Nonnull Path path, + @Nullable SourceType srcType, + @Nonnull List bodyInterceptors) { + if (!Files.exists(path)) { + throw new IllegalArgumentException( "The configured path '" + path + "' pointing to '" + path.toAbsolutePath() + "' does not exist."); - } + } + this.bodyInterceptors = bodyInterceptors; this.path = path; this.srcType = srcType; } @@ -71,7 +73,7 @@ List walkDirectory( @Nonnull ClassProvider classProvider) { try (final Stream walk = Files.walk(path)) { - return walk.filter(filePath -> PathUtils.hasExtension(filePath, handledFileType)) + return walk.filter(filePath -> PathUtils.hasExtension(filePath, FileType.JIMPLE)) .flatMap( p -> { String fullyQualifiedName = From f8b8c1de5fed363007a43ed93d10eb16f4747480 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Thu, 11 Jan 2024 15:11:41 +0100 Subject: [PATCH 09/57] merge fixes --- .../PathBasedAnalysisInputLocation.java | 373 +-------- .../PathBasedAnalysisInputLocationTest.java | 723 +++++++++--------- .../parser/JimpleAnalysisInputLocation.java | 22 +- 3 files changed, 369 insertions(+), 749 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index 228297a614a..33921a76266 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -4,6 +4,7 @@ import java.nio.file.*; import java.nio.file.FileSystem; import java.util.*; +import java.util.concurrent.ExecutionException; import java.util.jar.Attributes; import java.util.jar.JarInputStream; import java.util.jar.Manifest; @@ -23,6 +24,7 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import sootup.core.IdentifierFactory; +import sootup.core.frontend.AbstractClassSource; import sootup.core.frontend.ClassProvider; import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; @@ -34,7 +36,9 @@ import sootup.core.util.StreamUtils; import sootup.core.views.View; import sootup.java.bytecode.frontend.AsmJavaClassProvider; +import sootup.java.bytecode.frontend.AsmModuleSource; import sootup.java.core.*; +import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.JavaClassType; /*- @@ -168,7 +172,7 @@ private static boolean isMultiReleaseJar(Path path) { Collection walkDirectory( @Nonnull Path dirPath, @Nonnull IdentifierFactory factory, - @Nonnull ClassProvider classProvider) { + @Nonnull ClassProvider classProvider) { final FileType handledFileType = classProvider.getHandledFileType(); final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; @@ -185,7 +189,8 @@ Collection walkDirectory( classProvider.createClassSource( this, p, factory.getClassType(fullyQualifiedName))); }) - .collect(Collectors.toList()); + .map(src -> (JavaSootClassSource) src) + .collect(Collectors.toList()); } catch (IOException e) { throw new IllegalArgumentException(e); @@ -237,6 +242,7 @@ protected Optional getSingleClass( } public static class ClassFileBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { + public ClassFileBasedAnalysisInputLocation( @Nonnull Path classFilePath, @Nonnull SourceType srcType) { this(classFilePath, srcType, Collections.emptyList()); @@ -265,8 +271,8 @@ public Collection getClassSources(@Nonnull View view) { final String fullyQualifiedName = fromPath(dirPath, path); - Optional> classSource = - classProvider.createClassSource(this, path, factory.getClassType(fullyQualifiedName)); + Optional classSource = + classProvider.createClassSource(this, path, factory.getClassType(fullyQualifiedName)) .map(src -> (JavaSootClassSource) src); return Collections.singletonList(classSource.get()); } } @@ -298,363 +304,6 @@ public Optional getClassSource( } } - public static class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation - implements ModuleInfoAnalysisInputLocation { - - @Nonnull private final int[] availableVersions; - - @Nonnull - private final Map> moduleInfoMap = - new HashMap<>(); - - @Nonnull - private final Map>> inputLocations = - new HashMap<>(); - - @Nonnull - private final List> baseInputLocations = new ArrayList<>(); - - boolean isResolved = false; - - private MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { - super(path, srcType); - - int[] tmp; - try { - FileSystem fs = fileSystemCache.get(path); - final Path archiveRoot = fs.getPath("/"); - try (final Stream list = - Files.list(archiveRoot.getFileSystem().getPath("/META-INF/versions/"))) { - tmp = - list.map(dir -> dir.getFileName().toString().replace("/", "")) - .mapToInt(Integer::new) - .sorted() - .toArray(); - } - - } catch (IOException | ExecutionException e) { - e.printStackTrace(); - tmp = new int[] {}; - } - availableVersions = tmp; - discoverInputLocations(srcType); - } - - /** Discovers all input locations for different java versions in this multi release jar */ - private void discoverInputLocations(@Nonnull SourceType srcType) { - FileSystem fs = null; - try { - fs = fileSystemCache.get(path); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } - final Path archiveRoot = fs.getPath("/"); - final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; - - baseInputLocations.add(PathBasedAnalysisInputLocation.create(archiveRoot, srcType)); - - String sep = archiveRoot.getFileSystem().getSeparator(); - - if (!isResolved) { - - for (int i = availableVersions.length - 1; i >= 0; i--) { - inputLocations.put(availableVersions[i], new ArrayList<>()); - - final Path versionRoot = - archiveRoot - .getFileSystem() - .getPath("/META-INF/versions/" + availableVersions[i] + sep); - - // only versions >= 9 support java modules - if (availableVersions[i] > 8) { - moduleInfoMap.put(availableVersions[i], new HashMap<>()); - try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { - for (Path entry : stream) { - - Path mi = path.resolve(moduleInfoFilename); - - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - - inputLocations.get(availableVersions[i]).add(inputLocation); - moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); - } - - if (Files.isDirectory(entry)) { - mi = versionRoot.resolve(moduleInfoFilename); - - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - - inputLocations.get(availableVersions[i]).add(inputLocation); - moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); - } - // else TODO [bh] can we have automatic modules here? - } - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - // if there was no module or the version is not > 8, we just add a directory based input - // location - if (inputLocations.get(availableVersions[i]).size() == 0) { - inputLocations - .get(availableVersions[i]) - .add(PathBasedAnalysisInputLocation.create(versionRoot, srcType)); - } - } - } - - isResolved = true; - } - - @Override - @Nonnull - public Optional> getClassSource( - @Nonnull ClassType type, @Nonnull View view) { - - Collection> il = - getBestMatchingInputLocationsRaw(view.getProject().getLanguage().getVersion()); - - Collection> baseIl = getBaseInputLocations(); - - if (type instanceof ModuleJavaClassType) { - il = - il.stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .collect(Collectors.toList()); - baseIl = - baseIl.stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .collect(Collectors.toList()); - } else { - il = - il.stream() - .filter(location -> !(location instanceof ModuleInfoAnalysisInputLocation)) - .collect(Collectors.toList()); - baseIl = - baseIl.stream() - .filter(location -> !(location instanceof ModuleInfoAnalysisInputLocation)) - .collect(Collectors.toList()); - } - - Optional> foundClass = - il.stream() - .map(location -> location.getClassSource(type, view)) - .filter(Optional::isPresent) - .limit(1) - .map(Optional::get) - .findAny(); - - if (foundClass.isPresent()) { - return foundClass; - } else { - return baseIl.stream() - .map(location -> location.getClassSource(type, view)) - .filter(Optional::isPresent) - .limit(1) - .map(Optional::get) - .findAny(); - } - } - - @Nonnull - @Override - public Collection> getModulesClassSources( - @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { - return inputLocations.get(view.getProject().getLanguage().getVersion()).stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .map( - location -> - ((ModuleInfoAnalysisInputLocation) location) - .getModulesClassSources(moduleSignature, view)) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } - - /** - * Returns the best matching input locations or the base input location. - * - * @param javaVersion version to find best match to - * @return best match or base input locations - */ - private Collection> getBestMatchingInputLocationsRaw( - int javaVersion) { - for (int i = availableVersions.length - 1; i >= 0; i--) { - - if (availableVersions[i] > javaVersion) continue; - - return new ArrayList<>(inputLocations.get(availableVersions[i])); - } - - return getBaseInputLocations(); - } - - private Collection> getBaseInputLocations() { - return baseInputLocations; - } - - @Override - @Nonnull - public Collection> getClassSources( - @Nonnull View view) { - Collection> il = - getBestMatchingInputLocationsRaw(view.getProject().getLanguage().getVersion()); - - Collection> result = - il.stream() - .map(location -> location.getClassSources(view)) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - if (il != getBaseInputLocations()) { - - Collection> baseSources = - getBaseInputLocations().stream() - .map(location -> location.getClassSources(view)) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - baseSources.forEach( - cs -> { - // do not add duplicate class sources - if (result.stream() - .noneMatch( - bestMatchCS -> - bestMatchCS - .getClassType() - .getFullyQualifiedName() - .equals(cs.getClassType().getFullyQualifiedName()))) { - result.add(cs); - } - }); - } - - return result; - } - - @Nonnull - @Override - public Optional getModuleInfo(ModuleSignature sig, View view) { - return Optional.ofNullable( - moduleInfoMap.get(view.getProject().getLanguage().getVersion()).get(sig)); - } - - @Nonnull - @Override - public Set getModules(View view) { - return inputLocations.get(view.getProject().getLanguage().getVersion()).stream() - .filter(e -> e instanceof ModuleInfoAnalysisInputLocation) - .map(e -> ((ModuleInfoAnalysisInputLocation) e).getModules(view)) - .flatMap(Set::stream) - .collect(Collectors.toSet()); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof PathBasedAnalysisInputLocation)) { - return false; - } - return path.equals(((PathBasedAnalysisInputLocation) o).path); - } - - @Override - public int hashCode() { - return path.hashCode(); - } - } - - private static class ApkAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation { - - private ApkAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { - super(path, srcType); - String jarPath = dex2jar(path); - this.path = Paths.get(jarPath); - } - - private String dex2jar(Path path) { - String apkPath = path.toAbsolutePath().toString(); - String outDir = "./tmp/"; - int start = apkPath.lastIndexOf(File.separator); - int end = apkPath.lastIndexOf(".apk"); - String outputFile = outDir + apkPath.substring(start + 1, end) + ".jar"; - Dex2jarCmd.main("-f", apkPath, "-o", outputFile); - return outputFile; - } - } - - static class ArchiveBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { - - // We cache the FileSystem instances as their creation is expensive. - // The Guava Cache is thread-safe (see JavaDoc of LoadingCache) hence this - // cache can be safely shared in a static variable. - protected static final LoadingCache fileSystemCache = - CacheBuilder.newBuilder() - .removalListener( - (RemovalNotification removalNotification) -> { - try { - removalNotification.getValue().close(); - } catch (IOException e) { - throw new RuntimeException( - "Could not close file system of " + removalNotification.getKey(), e); - } - }) - .expireAfterAccess(1, TimeUnit.SECONDS) - .build( - CacheLoader.from( - path -> { - try { - return FileSystems.newFileSystem( - Objects.requireNonNull(path), (ClassLoader) null); - } catch (IOException e) { - throw new RuntimeException("Could not open file system of " + path, e); - } - })); - - ArchiveBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { - super(path, srcType); - } - - @Override - @Nonnull - public Optional> getClassSource( - @Nonnull ClassType type, @Nonnull View view) { - try { - FileSystem fs = fileSystemCache.get(path); - final Path archiveRoot = fs.getPath("/"); - return getClassSourceInternal( - (JavaClassType) type, archiveRoot, new AsmJavaClassProvider(view)); - } catch (ExecutionException e) { - throw new RuntimeException("Failed to retrieve file system from cache for " + path, e); - } - } - - @Override - @Nonnull - public Collection> getClassSources( - @Nonnull View view) { - // we don't use the filesystem cache here as it could close the filesystem after the timeout - // while we are still iterating - try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) { - final Path archiveRoot = fs.getPath("/"); - return walkDirectory( - archiveRoot, view.getProject().getIdentifierFactory(), new AsmJavaClassProvider(view)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - private static final class WarArchiveAnalysisInputLocation extends DirectoryBasedAnalysisInputLocation { public List containedInputLocations = new ArrayList<>(); @@ -740,7 +389,7 @@ public Optional getClassSource( * * @param warFilePath The path to war file to be extracted */ - private void extractWarFile(Path warFilePath, final Path destDirectory) { + protected void extractWarFile(Path warFilePath, final Path destDirectory) { int extractedSize = 0; try { File dest = destDirectory.toFile(); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java index b416ba2ae3d..45e961c1963 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java @@ -22,27 +22,36 @@ * #L% */ -import static junit.framework.TestCase.assertEquals; -import static org.junit.Assert.*; -import static org.junit.Assert.assertTrue; - import categories.Java8Test; -import java.io.File; -import java.nio.file.Paths; -import java.util.*; +import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; +import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.inputlocation.EagerInputLocation; import sootup.core.jimple.basic.NoPositionInformation; -import sootup.core.model.*; +import sootup.core.model.ClassModifier; +import sootup.core.model.FieldModifier; +import sootup.core.model.SootClass; +import sootup.core.model.SourceType; import sootup.core.signatures.FieldSubSignature; import sootup.core.signatures.MethodSubSignature; import sootup.core.types.ClassType; import sootup.core.views.View; import sootup.java.core.*; +import sootup.java.core.language.JavaLanguage; +import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.JavaClassType; +import sootup.java.core.types.ModuleJavaClassType; +import sootup.java.core.views.JavaModuleView; import sootup.java.core.views.JavaView; +import java.io.File; +import java.nio.file.Paths; +import java.util.*; + +import static junit.framework.TestCase.assertEquals; +import static org.junit.Assert.*; + /** * @author Manuel Benz created on 06.06.18 * @author Kaustubh Kelkar updated on 16.04.2020 @@ -50,375 +59,335 @@ @Category(Java8Test.class) public class PathBasedAnalysisInputLocationTest extends AnalysisInputLocationTest { - @Test - public void multiReleaseJar() { - final ClassType classType = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - - final JavaProject project_min = - JavaProject.builder(new JavaLanguage(Integer.MIN_VALUE)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_min = project_min.createView(); - - final JavaProject project_8 = - JavaProject.builder(new JavaLanguage(8)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_8 = project_8.createView(); - - final JavaProject project_9 = - JavaProject.builder(new JavaLanguage(9)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_9 = project_9.createView(); - - final JavaProject project_10 = - JavaProject.builder(new JavaLanguage(10)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_10 = project_10.createView(); - - final JavaProject project_max = - JavaProject.builder(new JavaLanguage(Integer.MAX_VALUE)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mrj, SourceType.Application)) - .build(); - final JavaView view_max = project_max.createView(); - - // for java10 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_10.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_10.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // assert that method is correctly resolved - Assert.assertTrue( - view_10 - .getClass(classType) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 9")); - - // for java 9 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_9.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // for java 8 - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_8 - .getClass(classType) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); - - // for max int - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_max.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // for min int - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_min.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_min.getClass(classType2).get().getClassSource().getSourcePath().toString()); - } - - @Test - public void modularMultiReleaseJar() { - final ClassType utilityNoModule = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - - final ModuleJavaClassType utilityModule = - JavaModuleIdentifierFactory.getInstance() - .getClassType("de.upb.swt.multirelease/de.upb.swt.multirelease.Utility"); - - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - - final JavaProject project_8 = - JavaProject.builder(new JavaLanguage(8)) - .addInputLocation(PathBasedAnalysisInputLocation.create(mmrj, SourceType.Application)) - .build(); - final JavaView view_8 = project_8.createView(); - - final JavaModuleProject project_9 = - (JavaModuleProject) - JavaModuleProject.builder(new JavaLanguage(9)) - .enableModules() - .addInputLocation( - (ModuleInfoAnalysisInputLocation) - PathBasedAnalysisInputLocation.create(mmrj, SourceType.Application)) - .build(); - - final JavaModuleView view_9 = project_9.createView(); - - ModuleSignature moduleSignature = - JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); - - Assert.assertEquals(Collections.singleton(moduleSignature), view_9.getNamedModules()); - - Assert.assertTrue(view_9.getModuleInfo(moduleSignature).isPresent()); - - Assert.assertEquals(1, view_9.getModuleClasses(moduleSignature).size()); - - Assert.assertEquals( - "de.upb.swt.multirelease.Utility", - view_9.getModuleClasses(moduleSignature).stream() - .findAny() - .get() - .getType() - .getFullyQualifiedName()); - - // for java 9 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityModule).get().getClassSource().getSourcePath().toString()); - // different class will be returned if no module is specified - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_9 - .getClass(utilityModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 9")); - - // for java 8 - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - assertFalse(view_8.getClass(utilityModule).isPresent()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_8 - .getClass(utilityNoModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); - } - - @Test - public void testApk() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(apk, SourceType.Application); - final ClassType mainClass = - getIdentifierFactory().getClassType("de.upb.futuresoot.fields.MainActivity"); - testClassReceival(pathBasedNamespace, Collections.singletonList(mainClass), 1392); - } - - @Test - public void testSingleClass() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(cls, SourceType.Application); - ArrayList sigs = new ArrayList<>(); - sigs.add(getIdentifierFactory().getClassType("Employee")); - testClassReceival(pathBasedNamespace, sigs, 1); - } - - @Test(expected = IllegalArgumentException.class) - public void testSingleClassDoesNotExist() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create( - Paths.get("NonExisting.class"), SourceType.Application); - } - - @Test - public void testSingleClassWPackageName() { - PathBasedAnalysisInputLocation pathBasedNamespace = - new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( - Paths.get("../shared-test-resources/ClassWithPackageName.class"), - SourceType.Application); - ArrayList sigs = new ArrayList<>(); - sigs.add(getIdentifierFactory().getClassType("ClassesPackageName.ClassWithPackageName")); - testClassReceival(pathBasedNamespace, sigs, 1); - } - - @Test - public void testJar() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(jar, SourceType.Application); - ArrayList sigs = new ArrayList<>(); - sigs.add(getIdentifierFactory().getClassType("Employee", "ds")); - sigs.add(getIdentifierFactory().getClassType("MiniApp")); - testClassReceival(pathBasedNamespace, sigs, 6); - } - - @Test - public void testWar() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(war, SourceType.Application); - final ClassType warClass1 = getIdentifierFactory().getClassType("SimpleWarRead"); - testClassReceival(pathBasedNamespace, Collections.singletonList(warClass1), 19); - } - - @Test - public void testClassInWar() { - - String warFile = "../shared-test-resources/java-warApp/dummyWarApp.war"; - - assertTrue("File " + warFile + " not found.", new File(warFile).exists()); - - // Get the view - JavaView view = new JavaView(new JavaClassPathAnalysisInputLocation(warFile)); - - assertEquals(19, view.getClasses().size()); - - // Create java class signature - ClassType utilsClassSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); - - // Resolve signature to `SootClass` - JavaSootClass utilsClass = view.getClass(utilsClassSignature).get(); - - // Parse sub-signature for "setEmpSalary" method - MethodSubSignature optionalToStreamMethodSubSignature = - JavaIdentifierFactory.getInstance().parseMethodSubSignature("void setEmpSalary(int)"); - - // Get method for sub-signature - JavaSootMethod foundMethod = utilsClass.getMethod(optionalToStreamMethodSubSignature).get(); - assertNotNull(foundMethod.getBody()); - - // Print method - assertTrue("setEmpSalary".equalsIgnoreCase(foundMethod.getName())); - assertEquals("void", foundMethod.getReturnType().toString()); - assertEquals(1, foundMethod.getParameterCount()); - assertTrue( - foundMethod.getParameterTypes().stream().anyMatch(type -> "int".equals(type.toString()))); - - // Parse sub-signature for "empName" field - FieldSubSignature nameFieldSubSignature = - JavaIdentifierFactory.getInstance().parseFieldSubSignature("java.lang.String empName"); - - // Create the class signature - JavaClassType classSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); - - JavaSootField field = - new JavaSootField( - JavaIdentifierFactory.getInstance() - .getFieldSignature(classSignature, nameFieldSubSignature), - Collections.singleton(FieldModifier.PUBLIC), - null, - NoPositionInformation.getInstance()); - - // Build a soot class - JavaSootClass c = - new JavaSootClass( - new OverridingJavaClassSource( - new EagerInputLocation(), - null, - classSignature, - null, - null, - null, - Collections.singleton(field), - Collections.emptySet(), - null, - EnumSet.of(ClassModifier.PUBLIC), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList()), - SourceType.Application); - - assertEquals("java.lang.String", c.getField(nameFieldSubSignature).get().getType().toString()); - assertEquals("empName", c.getField(nameFieldSubSignature).get().getName()); - } - - void runtimeContains(View view, String classname, String packageName) { - final ClassType sig = getIdentifierFactory().getClassType(classname, packageName); - assertTrue(sig + " is not found in rt.jar", view.getClass(sig).isPresent()); - } - - @Test - public void testRuntimeJar() { - PathBasedAnalysisInputLocation pathBasedNamespace = new DefaultRTJarAnalysisInputLocation(); - - JavaView v = new JavaView(pathBasedNamespace); - - // test some standard jre classes - runtimeContains(v, "Object", "java.lang"); - runtimeContains(v, "List", "java.util"); - runtimeContains(v, "Map", "java.util"); - runtimeContains(v, "ArrayList", "java.util"); - runtimeContains(v, "HashMap", "java.util"); - runtimeContains(v, "Collection", "java.util"); - runtimeContains(v, "Comparator", "java.util"); - } - - /** - * Test for JavaClassPathAnalysisInputLocation. Specifying jar file with source type as Library. - * Expected - All input classes are of source type Library. - */ - @Test - public void testInputLocationLibraryMode() { - JavaView view = new JavaView(new DefaultRTJarAnalysisInputLocation()); - - Collection classes = new HashSet<>(); // Set to track the classes to check - - for (SootClass aClass : view.getClasses()) { - if (!aClass.isLibraryClass()) { - classes.add(aClass); - } + @Test + public void multiReleaseJar() { + final ClassType classType = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); + final ClassType classType2 = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); + + final JavaView view_min = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(1))); + final JavaView view_8 = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(8))); + final JavaView view_9 = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(9))); + final JavaView view_10 = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(10))); + final JavaView view_max = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(Integer.MAX_VALUE))); + + // for java10 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_10.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_10.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // assert that method is correctly resolved + Assert.assertTrue( + view_10 + .getClass(classType) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 9")); + + // for java 9 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_9.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // for java 8 + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_8.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_8 + .getClass(classType) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 8")); + + // for max int + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_max.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // for min int + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_min.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_min.getClass(classType2).get().getClassSource().getSourcePath().toString()); + } + + @Test + public void modularMultiReleaseJar() { + final ClassType utilityNoModule = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); + + final ModuleJavaClassType utilityModule = + JavaModuleIdentifierFactory.getInstance() + .getClassType("de.upb.swt.multirelease/de.upb.swt.multirelease.Utility"); + + final ClassType classType2 = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); + + MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation = new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); + final JavaView view_8 = new JavaView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation)); + + final JavaModuleView view_9 = new JavaModuleView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation), Collections.emptyList()); + + ModuleSignature moduleSignature = + JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); + + Assert.assertEquals(Collections.singleton(moduleSignature), view_9.getNamedModules()); + + Assert.assertTrue(view_9.getModuleInfo(moduleSignature).isPresent()); + + Assert.assertEquals(1, view_9.getModuleClasses(moduleSignature).size()); + + Assert.assertEquals( + "de.upb.swt.multirelease.Utility", + view_9.getModuleClasses(moduleSignature).stream() + .findAny() + .get() + .getType() + .getFullyQualifiedName()); + + // for java 9 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_9.getClass(utilityModule).get().getClassSource().getSourcePath().toString()); + // different class will be returned if no module is specified + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_9.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_9 + .getClass(utilityModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 9")); + + // for java 8 + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_8.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); + assertFalse(view_8.getClass(utilityModule).isPresent()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_8 + .getClass(utilityNoModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 8")); } - assertEquals("User Defined class found, expected none", 0, classes.size()); - } + @Test + public void testApk() { + PathBasedAnalysisInputLocation pathBasedNamespace = new ApkAnalysisInputLocation(apk, SourceType.Application); + final ClassType mainClass = + getIdentifierFactory().getClassType("de.upb.futuresoot.fields.MainActivity"); + testClassReceival(pathBasedNamespace, Collections.singletonList(mainClass), 1392); + } + + @Test + public void testSingleClass() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create(cls, SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("Employee")); + testClassReceival(pathBasedNamespace, sigs, 1); + } + + @Test(expected = IllegalArgumentException.class) + public void testSingleClassDoesNotExist() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create( + Paths.get("NonExisting.class"), SourceType.Application); + } + + @Test + public void testSingleClassWPackageName() { + AnalysisInputLocation pathBasedNamespace = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(Paths.get("../shared-test-resources/ClassWithPackageName.class"), SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("ClassesPackageName.ClassWithPackageName")); + testClassReceival(pathBasedNamespace, sigs, 1); + } + + @Test + public void testJar() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create(jar, SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("Employee", "ds")); + sigs.add(getIdentifierFactory().getClassType("MiniApp")); + testClassReceival(pathBasedNamespace, sigs, 6); + } + + @Test + public void testWar() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create(war, SourceType.Application); + final ClassType warClass1 = getIdentifierFactory().getClassType("SimpleWarRead"); + testClassReceival(pathBasedNamespace, Collections.singletonList(warClass1), 19); + } + + @Test + public void testClassInWar() { + + String warFile = "../shared-test-resources/java-warApp/dummyWarApp.war"; + + assertTrue("File " + warFile + " not found.", new File(warFile).exists()); + + // Get the view + JavaView view = new JavaView(new JavaClassPathAnalysisInputLocation(warFile)); + + assertEquals(19, view.getClasses().size()); + + // Create java class signature + ClassType utilsClassSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); + + // Resolve signature to `SootClass` + JavaSootClass utilsClass = view.getClass(utilsClassSignature).get(); + + // Parse sub-signature for "setEmpSalary" method + MethodSubSignature optionalToStreamMethodSubSignature = + JavaIdentifierFactory.getInstance().parseMethodSubSignature("void setEmpSalary(int)"); + + // Get method for sub-signature + JavaSootMethod foundMethod = utilsClass.getMethod(optionalToStreamMethodSubSignature).get(); + assertNotNull(foundMethod.getBody()); + + // Print method + assertTrue("setEmpSalary".equalsIgnoreCase(foundMethod.getName())); + assertEquals("void", foundMethod.getReturnType().toString()); + assertEquals(1, foundMethod.getParameterCount()); + assertTrue( + foundMethod.getParameterTypes().stream().anyMatch(type -> "int".equals(type.toString()))); + + // Parse sub-signature for "empName" field + FieldSubSignature nameFieldSubSignature = + JavaIdentifierFactory.getInstance().parseFieldSubSignature("java.lang.String empName"); + + // Create the class signature + JavaClassType classSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); + + JavaSootField field = + new JavaSootField( + JavaIdentifierFactory.getInstance() + .getFieldSignature(classSignature, nameFieldSubSignature), + Collections.singleton(FieldModifier.PUBLIC), + null, + NoPositionInformation.getInstance()); + + // Build a soot class + JavaSootClass c = + new JavaSootClass( + new OverridingJavaClassSource( + new EagerInputLocation(), + null, + classSignature, + null, + null, + null, + Collections.singleton(field), + Collections.emptySet(), + null, + EnumSet.of(ClassModifier.PUBLIC), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList()), + SourceType.Application); + + assertEquals("java.lang.String", c.getField(nameFieldSubSignature).get().getType().toString()); + assertEquals("empName", c.getField(nameFieldSubSignature).get().getName()); + } + + void runtimeContains(View view, String classname, String packageName) { + final ClassType sig = getIdentifierFactory().getClassType(classname, packageName); + assertTrue(sig + " is not found in rt.jar", view.getClass(sig).isPresent()); + } + + @Test + public void testRuntimeJar() { + PathBasedAnalysisInputLocation pathBasedNamespace = new DefaultRTJarAnalysisInputLocation(); + + JavaView v = new JavaView(pathBasedNamespace); + + // test some standard jre classes + runtimeContains(v, "Object", "java.lang"); + runtimeContains(v, "List", "java.util"); + runtimeContains(v, "Map", "java.util"); + runtimeContains(v, "ArrayList", "java.util"); + runtimeContains(v, "HashMap", "java.util"); + runtimeContains(v, "Collection", "java.util"); + runtimeContains(v, "Comparator", "java.util"); + } + + /** + * Test for JavaClassPathAnalysisInputLocation. Specifying jar file with source type as Library. + * Expected - All input classes are of source type Library. + */ + @Test + public void testInputLocationLibraryMode() { + JavaView view = new JavaView(new DefaultRTJarAnalysisInputLocation()); + + Collection classes = new HashSet<>(); // Set to track the classes to check + + for (SootClass aClass : view.getClasses()) { + if (!aClass.isLibraryClass()) { + classes.add(aClass); + } + } + + assertEquals("User Defined class found, expected none", 0, classes.size()); + } } diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java index 6b154fa2ef8..07e3adf418a 100644 --- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java +++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java @@ -14,6 +14,7 @@ import sootup.core.frontend.ClassProvider; import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; +import sootup.core.inputlocation.FileType; import sootup.core.model.SourceType; import sootup.core.transform.BodyInterceptor; import sootup.core.types.ClassType; @@ -24,13 +25,13 @@ /** @author Markus Schmidt */ public class JimpleAnalysisInputLocation implements AnalysisInputLocation { final Path path; - private final List bodyInterceptors; - /** Variable to track if user has specified the SourceType. By default, it will be set to null. */ private final SourceType srcType; + @Nonnull + private final List bodyInterceptors; public JimpleAnalysisInputLocation(@Nonnull Path path) { - this(path, SourceType.Application); + this(path, SourceType.Application, Collections.emptyList()); } public JimpleAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { @@ -38,17 +39,18 @@ public JimpleAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcT } public JimpleAnalysisInputLocation( - @Nonnull Path path, - @Nullable SourceType srcType, - @Nonnull List bodyInterceptors) { - if (!Files.exists(path)) { - throw new IllegalArgumentException( + @Nonnull Path path, + @Nullable SourceType srcType, + @Nonnull List bodyInterceptors) { + if (!Files.exists(path)) { + throw new IllegalArgumentException( "The configured path '" + path + "' pointing to '" + path.toAbsolutePath() + "' does not exist."); - } + } + this.bodyInterceptors = bodyInterceptors; this.path = path; this.srcType = srcType; } @@ -71,7 +73,7 @@ List walkDirectory( @Nonnull ClassProvider classProvider) { try (final Stream walk = Files.walk(path)) { - return walk.filter(filePath -> PathUtils.hasExtension(filePath, handledFileType)) + return walk.filter(filePath -> PathUtils.hasExtension(filePath, FileType.JIMPLE)) .flatMap( p -> { String fullyQualifiedName = From ba1be79b75e554b382d596461d0242afb208718f Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Thu, 11 Jan 2024 22:40:47 +0100 Subject: [PATCH 10/57] fix ClassBasedAnalysisInputLocation via fromPath --- .../MultiReleaseJarAnalysisInputLocation.java | 33 ++++++++ .../PathBasedAnalysisInputLocation.java | 79 +++++++------------ .../PathBasedAnalysisInputLocationTest.java | 5 +- 3 files changed, 65 insertions(+), 52 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index 516257aed8d..3f885fb374c 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -22,6 +22,8 @@ * #L% */ +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.FileSystem; @@ -29,6 +31,9 @@ import java.nio.file.Path; import java.util.*; import java.util.concurrent.ExecutionException; +import java.util.jar.Attributes; +import java.util.jar.JarInputStream; +import java.util.jar.Manifest; import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -319,4 +324,32 @@ public boolean equals(Object o) { public int hashCode() { return path.hashCode(); } + + + @Nonnull + @Override + protected String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClass) { + // FIXME: [ms] implement specific handling of the versioned path + return super.fromPath(baseDirPath, packageNamePathAndClass); + } + + private static boolean isMultiReleaseJar(Path path) { + try { + FileInputStream inputStream = new FileInputStream(path.toFile()); + JarInputStream jarStream = new JarInputStream(inputStream); + Manifest mf = jarStream.getManifest(); + + if (mf == null) { + return false; + } + + Attributes attributes = mf.getMainAttributes(); + + String value = attributes.getValue("Multi-Release"); + + return Boolean.parseBoolean(value); + } catch (IOException e) { + throw new IllegalArgumentException("File not found.", e); + } + } } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index 33921a76266..392da6b6199 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -115,57 +115,23 @@ public static PathBasedAnalysisInputLocation create( @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull List bodyInterceptors) { - final PathBasedAnalysisInputLocation inputLocation; if (Files.isDirectory(path)) { - inputLocation = new DirectoryBasedAnalysisInputLocation(path, srcType, bodyInterceptors); + return new DirectoryBasedAnalysisInputLocation(path, srcType, bodyInterceptors); } else if (PathUtils.isArchive(path)) { if (PathUtils.hasExtension(path, FileType.JAR)) { - inputLocation = new ArchiveBasedAnalysisInputLocation(path, srcType, bodyInterceptors); + return new ArchiveBasedAnalysisInputLocation(path, srcType, bodyInterceptors); } else if (PathUtils.hasExtension(path, FileType.WAR)) { try { - inputLocation = new WarArchiveAnalysisInputLocation(path, srcType, bodyInterceptors); + return new WarArchiveAnalysisInputLocation(path, srcType, bodyInterceptors); } catch (IOException e) { throw new RuntimeException(e); } - } else { - throw new IllegalArgumentException( - "Path '" - + path.toAbsolutePath() - + "' has to be pointing to the root of a class container, e.g. directory, jar, zip, apk, war etc."); } - } else if (PathUtils.hasExtension(path, FileType.CLASS)) { - inputLocation = new ClassFileBasedAnalysisInputLocation(path, srcType, bodyInterceptors); - } else { - throw new IllegalArgumentException( + } + throw new IllegalArgumentException( "Path '" + path.toAbsolutePath() + "' has to be pointing to the root of a class container, e.g. directory, jar, zip, apk, war etc."); - } - return inputLocation; - } - - private static boolean isMultiReleaseJar(Path path) { - try { - FileInputStream inputStream = new FileInputStream(path.toFile()); - JarInputStream jarStream = new JarInputStream(inputStream); - Manifest mf = jarStream.getManifest(); - - if (mf == null) { - return false; - } - - Attributes attributes = mf.getMainAttributes(); - - String value = attributes.getValue("Multi-Release"); - - return Boolean.parseBoolean(value); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - return false; } @Nonnull @@ -198,7 +164,7 @@ Collection walkDirectory( } @Nonnull - private static String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClass) { + protected String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClass) { return FilenameUtils.removeExtension( packageNamePathAndClass .subpath(baseDirPath.getNameCount(), packageNamePathAndClass.getNameCount()) @@ -216,9 +182,6 @@ protected Optional getClassSourceInternal( .getPath( signature.getFullyQualifiedName().replace('.', '/') + classProvider.getHandledFileType().getExtensionWithDot())); - if (!Files.exists(pathToClass)) { - return Optional.empty(); - } Optional classSource = classProvider.createClassSource(this, pathToClass, signature); @@ -231,10 +194,6 @@ protected Optional getSingleClass( Path pathToClass = Paths.get(path.toString()); - if (!Files.exists(pathToClass)) { - return Optional.empty(); - } - Optional classSource = classProvider.createClassSource(this, pathToClass, signature); @@ -243,16 +202,26 @@ protected Optional getSingleClass( public static class ClassFileBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { + @Nonnull + private final String omittedPackageName; + public ClassFileBasedAnalysisInputLocation( - @Nonnull Path classFilePath, @Nonnull SourceType srcType) { - this(classFilePath, srcType, Collections.emptyList()); + @Nonnull Path classFilePath, @Nonnull String omittedPackageName, @Nonnull SourceType srcType) { + this(classFilePath, omittedPackageName, srcType, Collections.emptyList()); } public ClassFileBasedAnalysisInputLocation( @Nonnull Path classFilePath, + @Nonnull String omittedPackageName, @Nonnull SourceType srcType, @Nonnull List bodyInterceptors) { super(classFilePath, srcType, bodyInterceptors); + this.omittedPackageName = omittedPackageName; + + if (!Files.isRegularFile(classFilePath) || Files.isDirectory(classFilePath)) { + throw new IllegalArgumentException("Needs to point to a regular file - not to a directory."); + } + } @Override @@ -275,6 +244,18 @@ public Collection getClassSources(@Nonnull View view) { classProvider.createClassSource(this, path, factory.getClassType(fullyQualifiedName)) .map(src -> (JavaSootClassSource) src); return Collections.singletonList(classSource.get()); } + + @Nonnull + protected String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClass) { + String str = FilenameUtils.removeExtension( + packageNamePathAndClass + .subpath(baseDirPath.getNameCount(), packageNamePathAndClass.getNameCount()) + .toString() + .replace(packageNamePathAndClass.getFileSystem().getSeparator(), ".")); + + return omittedPackageName.isEmpty() ? str : omittedPackageName + "." + str; + } + } private static class DirectoryBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java index 45e961c1963..92b85ba9d18 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java @@ -240,8 +240,7 @@ public void testApk() { @Test public void testSingleClass() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(cls, SourceType.Application); + PathBasedAnalysisInputLocation pathBasedNamespace = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(cls,"", SourceType.Application); ArrayList sigs = new ArrayList<>(); sigs.add(getIdentifierFactory().getClassType("Employee")); testClassReceival(pathBasedNamespace, sigs, 1); @@ -256,7 +255,7 @@ public void testSingleClassDoesNotExist() { @Test public void testSingleClassWPackageName() { - AnalysisInputLocation pathBasedNamespace = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(Paths.get("../shared-test-resources/ClassWithPackageName.class"), SourceType.Application); + AnalysisInputLocation pathBasedNamespace = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(Paths.get("../shared-test-resources/ClassWithPackageName.class"),"ClassesPackageName", SourceType.Application); ArrayList sigs = new ArrayList<>(); sigs.add(getIdentifierFactory().getClassType("ClassesPackageName.ClassWithPackageName")); testClassReceival(pathBasedNamespace, sigs, 1); From 3a1ede9d7c86d7958c23a7e4aae83afb12ef4da1 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Thu, 11 Jan 2024 22:47:58 +0100 Subject: [PATCH 11/57] progress multireleasejarinputlocations --- .../MultiReleaseJarAnalysisInputLocation.java | 4 ++-- .../inputlocation/PathBasedAnalysisInputLocationTest.java | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index 3f885fb374c..e2e48c63991 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -299,7 +299,7 @@ public Optional getModuleInfo(ModuleSignature sig, View view) { @Nonnull @Override - public Set getModules(View view) { + public Set getModules(@Nonnull View view) { return inputLocations.get(language.getVersion()).stream() .filter(e -> e instanceof ModuleInfoAnalysisInputLocation) .map(e -> ((ModuleInfoAnalysisInputLocation) e).getModules(view)) @@ -329,7 +329,7 @@ public int hashCode() { @Nonnull @Override protected String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClass) { - // FIXME: [ms] implement specific handling of the versioned path + // FIXME: [ms] implement specific handling of the versioned path -> /META-INF/versions/{Java_Version}/ -> cut 3 directories return super.fromPath(baseDirPath, packageNamePathAndClass); } diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java index 92b85ba9d18..2c6e9694ab8 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java @@ -156,10 +156,12 @@ public void modularMultiReleaseJar() { final ClassType classType2 = getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation = new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); - final JavaView view_8 = new JavaView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation)); + MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation8 = new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); + final JavaView view_8 = new JavaView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation8)); - final JavaModuleView view_9 = new JavaModuleView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation), Collections.emptyList()); + + MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation9 = new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(9)); + final JavaModuleView view_9 = new JavaModuleView(Collections.emptyList(), Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation9)); ModuleSignature moduleSignature = JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); From f45e47bd56afb0403c9f815a75058d060493a662 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 12 Jan 2024 10:26:31 +0100 Subject: [PATCH 12/57] style + naming --- .../inputlocation/AnalysisInputLocation.java | 3 +- .../inputlocation/EagerInputLocation.java | 1 + .../ArchiveBasedAnalysisInputLocation.java | 5 +- .../JavaModulePathAnalysisInputLocation.java | 3 +- .../MultiReleaseJarAnalysisInputLocation.java | 93 ++-- .../PathBasedAnalysisInputLocation.java | 49 +- .../MultiReleaseJarInputLocationTest.java | 41 +- .../PathBasedAnalysisInputLocationTest.java | 512 ++++++------------ .../JavaSourcePathAnalysisInputLocation.java | 1 + .../parser/JimpleAnalysisInputLocation.java | 17 +- 10 files changed, 282 insertions(+), 443 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/inputlocation/AnalysisInputLocation.java b/sootup.core/src/main/java/sootup/core/inputlocation/AnalysisInputLocation.java index bfaa1600a77..a8cc3e7190a 100644 --- a/sootup.core/src/main/java/sootup/core/inputlocation/AnalysisInputLocation.java +++ b/sootup.core/src/main/java/sootup/core/inputlocation/AnalysisInputLocation.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.Optional; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import sootup.core.frontend.SootClassSource; import sootup.core.model.SootClass; import sootup.core.model.SourceType; @@ -71,7 +70,7 @@ public interface AnalysisInputLocation { * * @return returns null as source type */ - @Nullable + @Nonnull SourceType getSourceType(); @Nonnull diff --git a/sootup.core/src/main/java/sootup/core/inputlocation/EagerInputLocation.java b/sootup.core/src/main/java/sootup/core/inputlocation/EagerInputLocation.java index d74c1f1cac4..366afe42026 100644 --- a/sootup.core/src/main/java/sootup/core/inputlocation/EagerInputLocation.java +++ b/sootup.core/src/main/java/sootup/core/inputlocation/EagerInputLocation.java @@ -74,6 +74,7 @@ public Collection getClassSources(@Nullable View view) { return map.values(); } + @Nonnull @Override public SourceType getSourceType() { return sourceType; diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ArchiveBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ArchiveBasedAnalysisInputLocation.java index e4a87e98eef..27d590ff466 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ArchiveBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ArchiveBasedAnalysisInputLocation.java @@ -34,7 +34,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import sootup.core.model.SourceType; import sootup.core.transform.BodyInterceptor; import sootup.core.types.ClassType; @@ -71,13 +70,13 @@ public class ArchiveBasedAnalysisInputLocation extends PathBasedAnalysisInputLoc } })); - public ArchiveBasedAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { + public ArchiveBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { this(path, srcType, Collections.emptyList()); } public ArchiveBasedAnalysisInputLocation( @Nonnull Path path, - @Nullable SourceType srcType, + @Nonnull SourceType srcType, @Nonnull List bodyInterceptors) { super(path, srcType, bodyInterceptors); } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java index efefa73517f..c711e462815 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java @@ -27,7 +27,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import sootup.core.IdentifierFactory; import sootup.core.frontend.ClassProvider; import sootup.core.frontend.SootClassSource; @@ -120,7 +119,7 @@ public Collection getClassSources(@Nonnull View view) { .collect(Collectors.toList()); } - @Nullable + @Nonnull @Override public SourceType getSourceType() { return sourcetype; diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index e2e48c63991..c50ccf147a9 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -23,7 +23,6 @@ */ import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.FileSystem; @@ -35,15 +34,18 @@ import java.util.jar.JarInputStream; import java.util.jar.Manifest; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import sootup.core.Language; import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.model.SourceType; import sootup.core.types.ClassType; import sootup.core.views.View; import sootup.java.bytecode.frontend.AsmModuleSource; -import sootup.java.core.*; +import sootup.java.core.JavaModuleIdentifierFactory; +import sootup.java.core.JavaModuleInfo; +import sootup.java.core.JavaSootClassSource; +import sootup.java.core.ModuleInfoAnalysisInputLocation; import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.ModuleJavaClassType; @@ -55,7 +57,13 @@ public class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisIn implements ModuleInfoAnalysisInputLocation { @Nonnull private final Language language; - @Nonnull private final int[] availableVersions; + + @Nonnull + public List getAvailableVersions() { + return availableVersions; + } + + @Nonnull private final List availableVersions; @Nonnull private final Map> moduleInfoMap = new HashMap<>(); @@ -67,55 +75,59 @@ public class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisIn boolean isResolved = false; public MultiReleaseJarAnalysisInputLocation( - @Nonnull Path path, @Nullable SourceType srcType, @Nonnull Language language) { + @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { super(path, srcType); this.language = language; - int[] tmp; + FileSystem fs; + try { - FileSystem fs = fileSystemCache.get(path); - final Path archiveRoot = fs.getPath("/"); - tmp = - Files.list(archiveRoot.getFileSystem().getPath("/META-INF/versions/")) - .map(dir -> dir.getFileName().toString().replace("/", "")) - .mapToInt(Integer::new) + fs = fileSystemCache.get(path); + } catch (ExecutionException e) { + throw new IllegalArgumentException("Could not open filesystemcache.", e); + } + final Path archiveRoot = fs.getPath("/").getFileSystem().getPath("/META-INF/versions/"); + + try (Stream list = Files.list(archiveRoot)) { + availableVersions = + list.map(dir -> dir.getFileName().toString().replace("/", "")) + .map(Integer::new) .sorted() - .toArray(); - } catch (IOException | ExecutionException e) { - e.printStackTrace(); - tmp = new int[] {}; + .collect(Collectors.toList()); + } catch (IOException e) { + throw new IllegalStateException("Can not index the given file.", e); } - availableVersions = tmp; - discoverInputLocations(srcType); + discoverInputLocations(); } /** Discovers all input locations for different java versions in this multi release jar */ - private void discoverInputLocations(@Nullable SourceType srcType) { - FileSystem fs = null; + private void discoverInputLocations() { + FileSystem fs; try { fs = fileSystemCache.get(path); } catch (ExecutionException e) { - e.printStackTrace(); + throw new IllegalStateException("Can not index the given file.", e); } final Path archiveRoot = fs.getPath("/"); final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; - baseInputLocations.add(PathBasedAnalysisInputLocation.create(archiveRoot, srcType)); + baseInputLocations.add(PathBasedAnalysisInputLocation.create(archiveRoot, sourceType)); String sep = archiveRoot.getFileSystem().getSeparator(); if (!isResolved) { - for (int i = availableVersions.length - 1; i >= 0; i--) { - inputLocations.put(availableVersions[i], new ArrayList<>()); + for (int i = availableVersions.size() - 1; i >= 0; i--) { + Integer version = availableVersions.get(i); + inputLocations.put(version, new ArrayList<>()); final Path versionRoot = - archiveRoot.getFileSystem().getPath("/META-INF/versions/" + availableVersions[i] + sep); + archiveRoot.getFileSystem().getPath("/META-INF/versions/" + version + sep); // only versions >= 9 support java modules - if (availableVersions[i] > 8) { - moduleInfoMap.put(availableVersions[i], new HashMap<>()); + if (version > 8) { + moduleInfoMap.put(version, new HashMap<>()); try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { for (Path entry : stream) { @@ -128,8 +140,8 @@ private void discoverInputLocations(@Nullable SourceType srcType) { new JavaModulePathAnalysisInputLocation( versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - inputLocations.get(availableVersions[i]).add(inputLocation); - moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); + inputLocations.get(version).add(inputLocation); + moduleInfoMap.get(version).put(moduleSignature, moduleInfo); } if (Files.isDirectory(entry)) { @@ -142,23 +154,23 @@ private void discoverInputLocations(@Nullable SourceType srcType) { new JavaModulePathAnalysisInputLocation( versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - inputLocations.get(availableVersions[i]).add(inputLocation); - moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); + inputLocations.get(version).add(inputLocation); + moduleInfoMap.get(version).put(moduleSignature, moduleInfo); } // else TODO [bh] can we have automatic modules here? } } } catch (IOException e) { - e.printStackTrace(); + throw new IllegalArgumentException("Could not index the file.", e); } } // if there was no module or the version is not > 8, we just add a directory based input // location - if (inputLocations.get(availableVersions[i]).size() == 0) { + if (inputLocations.get(version).isEmpty()) { inputLocations - .get(availableVersions[i]) - .add(PathBasedAnalysisInputLocation.create(versionRoot, srcType)); + .get(version) + .add(PathBasedAnalysisInputLocation.create(versionRoot, sourceType)); } } } @@ -238,11 +250,12 @@ public Collection getModulesClassSources( * @return best match or base input locations */ private Collection getBestMatchingInputLocationsRaw(int javaVersion) { - for (int i = availableVersions.length - 1; i >= 0; i--) { + for (int i = availableVersions.size() - 1; i >= 0; i--) { - if (availableVersions[i] > javaVersion) continue; + Integer version = availableVersions.get(i); + if (version > javaVersion) continue; - return new ArrayList<>(inputLocations.get(availableVersions[i])); + return new ArrayList<>(inputLocations.get(version)); } return getBaseInputLocations(); @@ -325,11 +338,11 @@ public int hashCode() { return path.hashCode(); } - @Nonnull @Override protected String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClass) { - // FIXME: [ms] implement specific handling of the versioned path -> /META-INF/versions/{Java_Version}/ -> cut 3 directories + // FIXME: [ms] implement specific handling of the versioned path -> + // /META-INF/versions/{Java_Version}/ -> cut 3 directories return super.fromPath(baseDirPath, packageNamePathAndClass); } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index 392da6b6199..df1a23817fd 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -2,12 +2,7 @@ import java.io.*; import java.nio.file.*; -import java.nio.file.FileSystem; import java.util.*; -import java.util.concurrent.ExecutionException; -import java.util.jar.Attributes; -import java.util.jar.JarInputStream; -import java.util.jar.Manifest; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.zip.ZipEntry; @@ -24,7 +19,6 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import sootup.core.IdentifierFactory; -import sootup.core.frontend.AbstractClassSource; import sootup.core.frontend.ClassProvider; import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; @@ -36,9 +30,7 @@ import sootup.core.util.StreamUtils; import sootup.core.views.View; import sootup.java.bytecode.frontend.AsmJavaClassProvider; -import sootup.java.bytecode.frontend.AsmModuleSource; import sootup.java.core.*; -import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.JavaClassType; /*- @@ -71,8 +63,8 @@ * @author Kaustubh Kelkar updated on 30.07.2020 */ public abstract class PathBasedAnalysisInputLocation implements AnalysisInputLocation { - private final SourceType sourceType; - private final List bodyInterceptors; + protected final SourceType sourceType; + protected final List bodyInterceptors; protected Path path; protected PathBasedAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { @@ -92,8 +84,8 @@ protected PathBasedAnalysisInputLocation( } } - @Nullable @Override + @Nonnull public SourceType getSourceType() { return sourceType; } @@ -129,9 +121,9 @@ public static PathBasedAnalysisInputLocation create( } } throw new IllegalArgumentException( - "Path '" - + path.toAbsolutePath() - + "' has to be pointing to the root of a class container, e.g. directory, jar, zip, apk, war etc."); + "Path '" + + path.toAbsolutePath() + + "' has to be pointing to the root of a class container, e.g. directory, jar, zip, apk, war etc."); } @Nonnull @@ -155,8 +147,8 @@ Collection walkDirectory( classProvider.createClassSource( this, p, factory.getClassType(fullyQualifiedName))); }) - .map(src -> (JavaSootClassSource) src) - .collect(Collectors.toList()); + .map(src -> (JavaSootClassSource) src) + .collect(Collectors.toList()); } catch (IOException e) { throw new IllegalArgumentException(e); @@ -202,11 +194,12 @@ protected Optional getSingleClass( public static class ClassFileBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { - @Nonnull - private final String omittedPackageName; + @Nonnull private final String omittedPackageName; public ClassFileBasedAnalysisInputLocation( - @Nonnull Path classFilePath, @Nonnull String omittedPackageName, @Nonnull SourceType srcType) { + @Nonnull Path classFilePath, + @Nonnull String omittedPackageName, + @Nonnull SourceType srcType) { this(classFilePath, omittedPackageName, srcType, Collections.emptyList()); } @@ -219,9 +212,9 @@ public ClassFileBasedAnalysisInputLocation( this.omittedPackageName = omittedPackageName; if (!Files.isRegularFile(classFilePath) || Files.isDirectory(classFilePath)) { - throw new IllegalArgumentException("Needs to point to a regular file - not to a directory."); + throw new IllegalArgumentException( + "Needs to point to a regular file - not to a directory."); } - } @Override @@ -241,21 +234,23 @@ public Collection getClassSources(@Nonnull View view) { final String fullyQualifiedName = fromPath(dirPath, path); Optional classSource = - classProvider.createClassSource(this, path, factory.getClassType(fullyQualifiedName)) .map(src -> (JavaSootClassSource) src); + classProvider + .createClassSource(this, path, factory.getClassType(fullyQualifiedName)) + .map(src -> (JavaSootClassSource) src); return Collections.singletonList(classSource.get()); } @Nonnull protected String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClass) { - String str = FilenameUtils.removeExtension( + String str = + FilenameUtils.removeExtension( packageNamePathAndClass - .subpath(baseDirPath.getNameCount(), packageNamePathAndClass.getNameCount()) - .toString() - .replace(packageNamePathAndClass.getFileSystem().getSeparator(), ".")); + .subpath(baseDirPath.getNameCount(), packageNamePathAndClass.getNameCount()) + .toString() + .replace(packageNamePathAndClass.getFileSystem().getSeparator(), ".")); return omittedPackageName.isEmpty() ? str : omittedPackageName + "." + str; } - } private static class DirectoryBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarInputLocationTest.java index 60c1d025736..67c9d8f32e7 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarInputLocationTest.java @@ -29,6 +29,7 @@ import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; +import sootup.core.model.SourceType; import sootup.core.types.ClassType; import sootup.java.core.JavaModuleIdentifierFactory; import sootup.java.core.language.JavaLanguage; @@ -47,25 +48,26 @@ public void multiReleaseJar() { final ClassType classType2 = getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - final JavaLanguage minLanguage = new JavaLanguage(Integer.MIN_VALUE); final JavaView view_min = - new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, null, minLanguage)); - - final JavaLanguage language8 = new JavaLanguage(8); + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(1))); final JavaView view_8 = - new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, null, language8)); - - final JavaLanguage language9 = new JavaLanguage(9); + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(8))); final JavaView view_9 = - new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, null, language9)); - - final JavaLanguage language10 = new JavaLanguage(10); + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(9))); final JavaView view_10 = - new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, null, language10)); - - final JavaLanguage maxLanguage = new JavaLanguage(Integer.MAX_VALUE); + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(10))); final JavaView view_max = - new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, null, maxLanguage)); + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(Integer.MAX_VALUE))); // for java10 Assert.assertEquals( @@ -151,16 +153,17 @@ public void modularMultiReleaseJar() { final ClassType classType2 = getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - final JavaLanguage language8 = new JavaLanguage(8); + MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation8 = + new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); final JavaView view_8 = - new JavaView(new MultiReleaseJarAnalysisInputLocation(mmrj, null, language8)); + new JavaView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation8)); - final JavaLanguage language9 = new JavaLanguage(9); + MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation9 = + new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(9)); final JavaModuleView view_9 = new JavaModuleView( Collections.emptyList(), - Collections.singletonList( - new MultiReleaseJarAnalysisInputLocation(mmrj, null, language9))); + Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation9)); ModuleSignature moduleSignature = JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java index 2c6e9694ab8..b4467c90e49 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocationTest.java @@ -22,8 +22,13 @@ * #L% */ +import static junit.framework.TestCase.assertEquals; +import static org.junit.Assert.*; + import categories.Java8Test; -import org.junit.Assert; +import java.io.File; +import java.nio.file.Paths; +import java.util.*; import org.junit.Test; import org.junit.experimental.categories.Category; import sootup.core.inputlocation.AnalysisInputLocation; @@ -38,20 +43,9 @@ import sootup.core.types.ClassType; import sootup.core.views.View; import sootup.java.core.*; -import sootup.java.core.language.JavaLanguage; -import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.JavaClassType; -import sootup.java.core.types.ModuleJavaClassType; -import sootup.java.core.views.JavaModuleView; import sootup.java.core.views.JavaView; -import java.io.File; -import java.nio.file.Paths; -import java.util.*; - -import static junit.framework.TestCase.assertEquals; -import static org.junit.Assert.*; - /** * @author Manuel Benz created on 06.06.18 * @author Kaustubh Kelkar updated on 16.04.2020 @@ -59,336 +53,170 @@ @Category(Java8Test.class) public class PathBasedAnalysisInputLocationTest extends AnalysisInputLocationTest { - @Test - public void multiReleaseJar() { - final ClassType classType = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - - final JavaView view_min = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(1))); - final JavaView view_8 = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(8))); - final JavaView view_9 = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(9))); - final JavaView view_10 = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(10))); - final JavaView view_max = new JavaView(new MultiReleaseJarAnalysisInputLocation(mrj, SourceType.Application, new JavaLanguage(Integer.MAX_VALUE))); - - // for java10 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_10.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_10.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // assert that method is correctly resolved - Assert.assertTrue( - view_10 - .getClass(classType) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 9")); - - // for java 9 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_9.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // for java 8 - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_8 - .getClass(classType) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); - - // for max int - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_max.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // for min int - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_min.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_min.getClass(classType2).get().getClassSource().getSourcePath().toString()); - } - - @Test - public void modularMultiReleaseJar() { - final ClassType utilityNoModule = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - - final ModuleJavaClassType utilityModule = - JavaModuleIdentifierFactory.getInstance() - .getClassType("de.upb.swt.multirelease/de.upb.swt.multirelease.Utility"); - - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - - MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation8 = new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); - final JavaView view_8 = new JavaView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation8)); - - - MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation9 = new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(9)); - final JavaModuleView view_9 = new JavaModuleView(Collections.emptyList(), Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation9)); - - ModuleSignature moduleSignature = - JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); - - Assert.assertEquals(Collections.singleton(moduleSignature), view_9.getNamedModules()); - - Assert.assertTrue(view_9.getModuleInfo(moduleSignature).isPresent()); - - Assert.assertEquals(1, view_9.getModuleClasses(moduleSignature).size()); - - Assert.assertEquals( - "de.upb.swt.multirelease.Utility", - view_9.getModuleClasses(moduleSignature).stream() - .findAny() - .get() - .getType() - .getFullyQualifiedName()); - - // for java 9 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityModule).get().getClassSource().getSourcePath().toString()); - // different class will be returned if no module is specified - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_9 - .getClass(utilityModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 9")); - - // for java 8 - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - assertFalse(view_8.getClass(utilityModule).isPresent()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_8 - .getClass(utilityNoModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); + @Test + public void testApk() { + PathBasedAnalysisInputLocation pathBasedNamespace = + new ApkAnalysisInputLocation(apk, SourceType.Application); + final ClassType mainClass = + getIdentifierFactory().getClassType("de.upb.futuresoot.fields.MainActivity"); + testClassReceival(pathBasedNamespace, Collections.singletonList(mainClass), 1392); + } + + @Test + public void testSingleClass() { + PathBasedAnalysisInputLocation pathBasedNamespace = + new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( + cls, "", SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("Employee")); + testClassReceival(pathBasedNamespace, sigs, 1); + } + + @Test(expected = IllegalArgumentException.class) + public void testSingleClassDoesNotExist() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create( + Paths.get("NonExisting.class"), SourceType.Application); + } + + @Test + public void testSingleClassWPackageName() { + AnalysisInputLocation pathBasedNamespace = + new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( + Paths.get("../shared-test-resources/ClassWithPackageName.class"), + "ClassesPackageName", + SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("ClassesPackageName.ClassWithPackageName")); + testClassReceival(pathBasedNamespace, sigs, 1); + } + + @Test + public void testJar() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create(jar, SourceType.Application); + ArrayList sigs = new ArrayList<>(); + sigs.add(getIdentifierFactory().getClassType("Employee", "ds")); + sigs.add(getIdentifierFactory().getClassType("MiniApp")); + testClassReceival(pathBasedNamespace, sigs, 6); + } + + @Test + public void testWar() { + PathBasedAnalysisInputLocation pathBasedNamespace = + PathBasedAnalysisInputLocation.create(war, SourceType.Application); + final ClassType warClass1 = getIdentifierFactory().getClassType("SimpleWarRead"); + testClassReceival(pathBasedNamespace, Collections.singletonList(warClass1), 19); + } + + @Test + public void testClassInWar() { + + String warFile = "../shared-test-resources/java-warApp/dummyWarApp.war"; + + assertTrue("File " + warFile + " not found.", new File(warFile).exists()); + + // Get the view + JavaView view = new JavaView(new JavaClassPathAnalysisInputLocation(warFile)); + + assertEquals(19, view.getClasses().size()); + + // Create java class signature + ClassType utilsClassSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); + + // Resolve signature to `SootClass` + JavaSootClass utilsClass = view.getClass(utilsClassSignature).get(); + + // Parse sub-signature for "setEmpSalary" method + MethodSubSignature optionalToStreamMethodSubSignature = + JavaIdentifierFactory.getInstance().parseMethodSubSignature("void setEmpSalary(int)"); + + // Get method for sub-signature + JavaSootMethod foundMethod = utilsClass.getMethod(optionalToStreamMethodSubSignature).get(); + assertNotNull(foundMethod.getBody()); + + // Print method + assertTrue("setEmpSalary".equalsIgnoreCase(foundMethod.getName())); + assertEquals("void", foundMethod.getReturnType().toString()); + assertEquals(1, foundMethod.getParameterCount()); + assertTrue( + foundMethod.getParameterTypes().stream().anyMatch(type -> "int".equals(type.toString()))); + + // Parse sub-signature for "empName" field + FieldSubSignature nameFieldSubSignature = + JavaIdentifierFactory.getInstance().parseFieldSubSignature("java.lang.String empName"); + + // Create the class signature + JavaClassType classSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); + + JavaSootField field = + new JavaSootField( + JavaIdentifierFactory.getInstance() + .getFieldSignature(classSignature, nameFieldSubSignature), + Collections.singleton(FieldModifier.PUBLIC), + null, + NoPositionInformation.getInstance()); + + // Build a soot class + JavaSootClass c = + new JavaSootClass( + new OverridingJavaClassSource( + new EagerInputLocation(), + null, + classSignature, + null, + null, + null, + Collections.singleton(field), + Collections.emptySet(), + null, + EnumSet.of(ClassModifier.PUBLIC), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList()), + SourceType.Application); + + assertEquals("java.lang.String", c.getField(nameFieldSubSignature).get().getType().toString()); + assertEquals("empName", c.getField(nameFieldSubSignature).get().getName()); + } + + void runtimeContains(View view, String classname, String packageName) { + final ClassType sig = getIdentifierFactory().getClassType(classname, packageName); + assertTrue(sig + " is not found in rt.jar", view.getClass(sig).isPresent()); + } + + @Test + public void testRuntimeJar() { + PathBasedAnalysisInputLocation pathBasedNamespace = new DefaultRTJarAnalysisInputLocation(); + + JavaView v = new JavaView(pathBasedNamespace); + + // test some standard jre classes + runtimeContains(v, "Object", "java.lang"); + runtimeContains(v, "List", "java.util"); + runtimeContains(v, "Map", "java.util"); + runtimeContains(v, "ArrayList", "java.util"); + runtimeContains(v, "HashMap", "java.util"); + runtimeContains(v, "Collection", "java.util"); + runtimeContains(v, "Comparator", "java.util"); + } + + /** + * Test for JavaClassPathAnalysisInputLocation. Specifying jar file with source type as Library. + * Expected - All input classes are of source type Library. + */ + @Test + public void testInputLocationLibraryMode() { + JavaView view = new JavaView(new DefaultRTJarAnalysisInputLocation()); + + Collection classes = new HashSet<>(); // Set to track the classes to check + + for (SootClass aClass : view.getClasses()) { + if (!aClass.isLibraryClass()) { + classes.add(aClass); + } } - @Test - public void testApk() { - PathBasedAnalysisInputLocation pathBasedNamespace = new ApkAnalysisInputLocation(apk, SourceType.Application); - final ClassType mainClass = - getIdentifierFactory().getClassType("de.upb.futuresoot.fields.MainActivity"); - testClassReceival(pathBasedNamespace, Collections.singletonList(mainClass), 1392); - } - - @Test - public void testSingleClass() { - PathBasedAnalysisInputLocation pathBasedNamespace = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(cls,"", SourceType.Application); - ArrayList sigs = new ArrayList<>(); - sigs.add(getIdentifierFactory().getClassType("Employee")); - testClassReceival(pathBasedNamespace, sigs, 1); - } - - @Test(expected = IllegalArgumentException.class) - public void testSingleClassDoesNotExist() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create( - Paths.get("NonExisting.class"), SourceType.Application); - } - - @Test - public void testSingleClassWPackageName() { - AnalysisInputLocation pathBasedNamespace = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(Paths.get("../shared-test-resources/ClassWithPackageName.class"),"ClassesPackageName", SourceType.Application); - ArrayList sigs = new ArrayList<>(); - sigs.add(getIdentifierFactory().getClassType("ClassesPackageName.ClassWithPackageName")); - testClassReceival(pathBasedNamespace, sigs, 1); - } - - @Test - public void testJar() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(jar, SourceType.Application); - ArrayList sigs = new ArrayList<>(); - sigs.add(getIdentifierFactory().getClassType("Employee", "ds")); - sigs.add(getIdentifierFactory().getClassType("MiniApp")); - testClassReceival(pathBasedNamespace, sigs, 6); - } - - @Test - public void testWar() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create(war, SourceType.Application); - final ClassType warClass1 = getIdentifierFactory().getClassType("SimpleWarRead"); - testClassReceival(pathBasedNamespace, Collections.singletonList(warClass1), 19); - } - - @Test - public void testClassInWar() { - - String warFile = "../shared-test-resources/java-warApp/dummyWarApp.war"; - - assertTrue("File " + warFile + " not found.", new File(warFile).exists()); - - // Get the view - JavaView view = new JavaView(new JavaClassPathAnalysisInputLocation(warFile)); - - assertEquals(19, view.getClasses().size()); - - // Create java class signature - ClassType utilsClassSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); - - // Resolve signature to `SootClass` - JavaSootClass utilsClass = view.getClass(utilsClassSignature).get(); - - // Parse sub-signature for "setEmpSalary" method - MethodSubSignature optionalToStreamMethodSubSignature = - JavaIdentifierFactory.getInstance().parseMethodSubSignature("void setEmpSalary(int)"); - - // Get method for sub-signature - JavaSootMethod foundMethod = utilsClass.getMethod(optionalToStreamMethodSubSignature).get(); - assertNotNull(foundMethod.getBody()); - - // Print method - assertTrue("setEmpSalary".equalsIgnoreCase(foundMethod.getName())); - assertEquals("void", foundMethod.getReturnType().toString()); - assertEquals(1, foundMethod.getParameterCount()); - assertTrue( - foundMethod.getParameterTypes().stream().anyMatch(type -> "int".equals(type.toString()))); - - // Parse sub-signature for "empName" field - FieldSubSignature nameFieldSubSignature = - JavaIdentifierFactory.getInstance().parseFieldSubSignature("java.lang.String empName"); - - // Create the class signature - JavaClassType classSignature = view.getIdentifierFactory().getClassType("Employee", "ds"); - - JavaSootField field = - new JavaSootField( - JavaIdentifierFactory.getInstance() - .getFieldSignature(classSignature, nameFieldSubSignature), - Collections.singleton(FieldModifier.PUBLIC), - null, - NoPositionInformation.getInstance()); - - // Build a soot class - JavaSootClass c = - new JavaSootClass( - new OverridingJavaClassSource( - new EagerInputLocation(), - null, - classSignature, - null, - null, - null, - Collections.singleton(field), - Collections.emptySet(), - null, - EnumSet.of(ClassModifier.PUBLIC), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList()), - SourceType.Application); - - assertEquals("java.lang.String", c.getField(nameFieldSubSignature).get().getType().toString()); - assertEquals("empName", c.getField(nameFieldSubSignature).get().getName()); - } - - void runtimeContains(View view, String classname, String packageName) { - final ClassType sig = getIdentifierFactory().getClassType(classname, packageName); - assertTrue(sig + " is not found in rt.jar", view.getClass(sig).isPresent()); - } - - @Test - public void testRuntimeJar() { - PathBasedAnalysisInputLocation pathBasedNamespace = new DefaultRTJarAnalysisInputLocation(); - - JavaView v = new JavaView(pathBasedNamespace); - - // test some standard jre classes - runtimeContains(v, "Object", "java.lang"); - runtimeContains(v, "List", "java.util"); - runtimeContains(v, "Map", "java.util"); - runtimeContains(v, "ArrayList", "java.util"); - runtimeContains(v, "HashMap", "java.util"); - runtimeContains(v, "Collection", "java.util"); - runtimeContains(v, "Comparator", "java.util"); - } - - /** - * Test for JavaClassPathAnalysisInputLocation. Specifying jar file with source type as Library. - * Expected - All input classes are of source type Library. - */ - @Test - public void testInputLocationLibraryMode() { - JavaView view = new JavaView(new DefaultRTJarAnalysisInputLocation()); - - Collection classes = new HashSet<>(); // Set to track the classes to check - - for (SootClass aClass : view.getClasses()) { - if (!aClass.isLibraryClass()) { - classes.add(aClass); - } - } - - assertEquals("User Defined class found, expected none", 0, classes.size()); - } + assertEquals("User Defined class found, expected none", 0, classes.size()); + } } diff --git a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/inputlocation/JavaSourcePathAnalysisInputLocation.java b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/inputlocation/JavaSourcePathAnalysisInputLocation.java index 46703e48240..4951d9e8a4b 100644 --- a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/inputlocation/JavaSourcePathAnalysisInputLocation.java +++ b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/inputlocation/JavaSourcePathAnalysisInputLocation.java @@ -146,6 +146,7 @@ public void setSpecifiedAsBuiltInByUser(@Nullable SourceType srcType) { this.srcType = srcType; } + @Nonnull @Override public SourceType getSourceType() { return srcType; diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java index 07e3adf418a..d95713da8fe 100644 --- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java +++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java @@ -27,8 +27,8 @@ public class JimpleAnalysisInputLocation implements AnalysisInputLocation { final Path path; /** Variable to track if user has specified the SourceType. By default, it will be set to null. */ private final SourceType srcType; - @Nonnull - private final List bodyInterceptors; + + @Nonnull private final List bodyInterceptors; public JimpleAnalysisInputLocation(@Nonnull Path path) { this(path, SourceType.Application, Collections.emptyList()); @@ -39,22 +39,23 @@ public JimpleAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcT } public JimpleAnalysisInputLocation( - @Nonnull Path path, - @Nullable SourceType srcType, - @Nonnull List bodyInterceptors) { - if (!Files.exists(path)) { - throw new IllegalArgumentException( + @Nonnull Path path, + @Nullable SourceType srcType, + @Nonnull List bodyInterceptors) { + if (!Files.exists(path)) { + throw new IllegalArgumentException( "The configured path '" + path + "' pointing to '" + path.toAbsolutePath() + "' does not exist."); - } + } this.bodyInterceptors = bodyInterceptors; this.path = path; this.srcType = srcType; } + @Nonnull @Override public SourceType getSourceType() { return srcType; From ca8d50f6dc449b65987529a8a6e0d5e283fba4d3 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 12 Jan 2024 10:32:37 +0100 Subject: [PATCH 13/57] remove obsolete sourcetypespecifier --- .../core/frontend/AbstractClassSource.java | 2 +- .../DefaultSourceTypeSpecifier.java | 61 ------------------- .../java/core/views/JavaModuleView.java | 19 +----- .../java/sootup/java/core/views/JavaView.java | 20 +----- .../java/sootup/jimple/parser/JimpleView.java | 1 - 5 files changed, 5 insertions(+), 98 deletions(-) delete mode 100644 sootup.core/src/main/java/sootup/core/inputlocation/DefaultSourceTypeSpecifier.java diff --git a/sootup.core/src/main/java/sootup/core/frontend/AbstractClassSource.java b/sootup.core/src/main/java/sootup/core/frontend/AbstractClassSource.java index 4274e3fb227..3205dfd0f83 100644 --- a/sootup.core/src/main/java/sootup/core/frontend/AbstractClassSource.java +++ b/sootup.core/src/main/java/sootup/core/frontend/AbstractClassSource.java @@ -64,7 +64,7 @@ public ClassType getClassType() { return classSignature; } - public AnalysisInputLocation getClassSource() { + public AnalysisInputLocation getAnalysisInputLocation() { return classSource; } diff --git a/sootup.core/src/main/java/sootup/core/inputlocation/DefaultSourceTypeSpecifier.java b/sootup.core/src/main/java/sootup/core/inputlocation/DefaultSourceTypeSpecifier.java deleted file mode 100644 index 2d11a7d7b0e..00000000000 --- a/sootup.core/src/main/java/sootup/core/inputlocation/DefaultSourceTypeSpecifier.java +++ /dev/null @@ -1,61 +0,0 @@ -package sootup.core.inputlocation; -/*- - * #%L - * Soot - a J*va Optimization Framework - * %% - * Copyright (C) 2019-2020 Markus Schmidt, Linghui Luo - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 2.1 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * . - * #L% - */ -import javax.annotation.Nonnull; -import sootup.core.SourceTypeSpecifier; -import sootup.core.frontend.AbstractClassSource; -import sootup.core.model.SourceType; - -/** - * Implements a very basic version of {@link SourceTypeSpecifier} which tells the type of a class by - * checking if it is a language build-in class. - * - * @author Markus Schmidt - */ -public class DefaultSourceTypeSpecifier implements SourceTypeSpecifier { - - private static final DefaultSourceTypeSpecifier INSTANCE = new DefaultSourceTypeSpecifier(); - - /** Singleton to get an Instance of this SourceTypeSpecifier */ - public static DefaultSourceTypeSpecifier getInstance() { - return INSTANCE; - } - - private DefaultSourceTypeSpecifier() {} - - @Nonnull - public SourceType sourceTypeFor(AbstractClassSource clsSource) { - SourceType sourceType = clsSource.getClassSource().getSourceType(); - if (sourceType != null) { - // Check if source type is specified in AnalysisInputLocation. - return sourceType; - } - - if (clsSource.getClassType().isBuiltInClass()) { - // Call builtInClass() method which uses package name to validate whether the class is inbuilt - // or not. - return SourceType.Library; - } - - return SourceType.Application; - } -} 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..f8be95a5e67 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 @@ -33,7 +33,6 @@ import sootup.core.cache.provider.FullCacheProvider; import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.inputlocation.ClassLoadingOptions; -import sootup.core.inputlocation.DefaultSourceTypeSpecifier; import sootup.core.inputlocation.EmptyClassLoadingOptions; import sootup.core.signatures.PackageName; import sootup.core.types.ClassType; @@ -70,19 +69,6 @@ public JavaModuleView( analysisInputLocation -> EmptyClassLoadingOptions.Default); } - public JavaModuleView( - @Nonnull List inputLocations, - @Nonnull List moduleInputLocations, - @Nonnull ClassCacheProvider cacheProvider, - @Nonnull Function classLoadingOptionsSpecifier) { - this( - inputLocations, - moduleInputLocations, - cacheProvider, - classLoadingOptionsSpecifier, - DefaultSourceTypeSpecifier.getInstance()); - } - /** * Creates a new instance of the {@link JavaModuleView} class. * @@ -94,9 +80,8 @@ public JavaModuleView( @Nonnull List inputLocations, @Nonnull List moduleInputLocations, @Nonnull ClassCacheProvider cacheProvider, - @Nonnull Function classLoadingOptionsSpecifier, - @Nonnull SourceTypeSpecifier sourceTypeSpecifier) { - super(inputLocations, cacheProvider, sourceTypeSpecifier); + @Nonnull Function classLoadingOptionsSpecifier) { + super(inputLocations, cacheProvider); this.moduleInfoAnalysisInputLocations = moduleInputLocations; JavaModuleInfo unnamedModuleInfo = JavaModuleInfo.getUnnamedModuleInfo(); 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..063cca185ae 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 @@ -28,14 +28,13 @@ import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Nonnull; -import sootup.core.SourceTypeSpecifier; + import sootup.core.cache.ClassCache; import sootup.core.cache.FullCache; import sootup.core.cache.provider.ClassCacheProvider; import sootup.core.cache.provider.FullCacheProvider; import sootup.core.frontend.AbstractClassSource; import sootup.core.inputlocation.AnalysisInputLocation; -import sootup.core.inputlocation.DefaultSourceTypeSpecifier; import sootup.core.signatures.FieldSignature; import sootup.core.signatures.MethodSignature; import sootup.core.types.ClassType; @@ -55,7 +54,6 @@ public class JavaView extends AbstractView { @Nonnull protected final List inputLocations; @Nonnull protected final ClassCache cache; - @Nonnull protected final SourceTypeSpecifier sourceTypeSpecifier; protected volatile boolean isFullyResolved = false; @@ -67,25 +65,11 @@ public JavaView(@Nonnull List inputLocations) { this(inputLocations, new FullCacheProvider()); } - /** - * Creates a new instance of the {@link JavaView} class. - * - *

{@link AnalysisInputLocation}, simply return null, otherwise the desired - * options. - */ public JavaView( @Nonnull List inputLocations, @Nonnull ClassCacheProvider cacheProvider) { - this(inputLocations, cacheProvider, DefaultSourceTypeSpecifier.getInstance()); - } - - public JavaView( - @Nonnull List inputLocations, - @Nonnull ClassCacheProvider cacheProvider, - @Nonnull SourceTypeSpecifier sourceTypeSpecifier) { this.inputLocations = inputLocations; this.cache = cacheProvider.createCache(); - this.sourceTypeSpecifier = sourceTypeSpecifier; } /** Resolves all classes that are part of the view and stores them in the cache. */ @@ -159,7 +143,7 @@ protected synchronized Optional buildClassFrom(AbstractClassSourc JavaSootClass theClass; if (!cache.hasClass(classType)) { theClass = - (JavaSootClass) classSource.buildClass(sourceTypeSpecifier.sourceTypeFor(classSource)); + (JavaSootClass) classSource.buildClass(classSource.getAnalysisInputLocation().getSourceType()); cache.putClass(classType, theClass); } else { theClass = (JavaSootClass) cache.getClass(classType); diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java index c746a8d9493..5a272813eff 100644 --- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java +++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java @@ -15,7 +15,6 @@ import sootup.core.frontend.ResolveException; import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; -import sootup.core.inputlocation.DefaultSourceTypeSpecifier; import sootup.core.model.SootClass; import sootup.core.types.ClassType; import sootup.core.views.AbstractView; From aa155268607b88598d278e415c63bc2b49fd712d Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 12 Jan 2024 11:52:13 +0100 Subject: [PATCH 14/57] progress --- .../main/java/sootup/core/jimple/Jimple.java | 34 ------------------- ...iReleaseJarAnalysisInputLocationTest.java} | 2 +- .../java/core/views/MutableJavaView.java | 9 ++--- .../java/sootup/jimple/parser/JimpleView.java | 8 ----- 4 files changed, 3 insertions(+), 50 deletions(-) rename sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/{MultiReleaseJarInputLocationTest.java => MultiReleaseJarAnalysisInputLocationTest.java} (99%) diff --git a/sootup.core/src/main/java/sootup/core/jimple/Jimple.java b/sootup.core/src/main/java/sootup/core/jimple/Jimple.java index 768e72b5e7f..d6ec617df28 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/Jimple.java +++ b/sootup.core/src/main/java/sootup/core/jimple/Jimple.java @@ -348,11 +348,6 @@ public static JStaticInvokeExpr newStaticInvokeExpr( return new JStaticInvokeExpr(method, args); } - @Deprecated // use the version with List args instead - public static JStaticInvokeExpr newStaticInvokeExpr(MethodSignature method, Immediate... args) { - return newStaticInvokeExpr(method, Arrays.asList(args)); - } - public static JStaticInvokeExpr newStaticInvokeExpr(MethodSignature method, Immediate arg) { return newStaticInvokeExpr(method, Collections.singletonList(arg)); } @@ -370,15 +365,6 @@ public static JSpecialInvokeExpr newSpecialInvokeExpr( return new JSpecialInvokeExpr(base, method, args); } - /** - * Constructs a NewSpecialInvokeExpr(Local base, SootMethod method, List of Immediate) grammar - * chunk. - */ - @Deprecated // use the version with List args instead - public static JSpecialInvokeExpr newSpecialInvokeExpr( - Local base, MethodSignature method, Immediate... args) { - return newSpecialInvokeExpr(base, method, Arrays.asList(args)); - } public static JSpecialInvokeExpr newSpecialInvokeExpr( Local base, MethodSignature method, Immediate arg) { @@ -424,16 +410,6 @@ public static JVirtualInvokeExpr newVirtualInvokeExpr( return new JVirtualInvokeExpr(base, method, args); } - /** - * Constructs a NewVirtualInvokeExpr(Local base, SootMethod method, List of Immediate) grammar - * chunk. - */ - @Deprecated // use the version with List args instead - public static JVirtualInvokeExpr newVirtualInvokeExpr( - Local base, MethodSignature method, Immediate... args) { - return newVirtualInvokeExpr(base, method, Arrays.asList(args)); - } - public static JVirtualInvokeExpr newVirtualInvokeExpr( Local base, MethodSignature method, Immediate arg) { return newVirtualInvokeExpr(base, method, Collections.singletonList(arg)); @@ -452,16 +428,6 @@ public static JInterfaceInvokeExpr newInterfaceInvokeExpr( return new JInterfaceInvokeExpr(base, method, args); } - /** - * Constructs a NewInterfaceInvokeExpr(Local base, SootMethod method, List of Immediate) grammar - * chunk. - */ - @Deprecated // use the version with List args instead - public static JInterfaceInvokeExpr newInterfaceInvokeExpr( - Local base, MethodSignature method, Immediate... args) { - return newInterfaceInvokeExpr(base, method, Arrays.asList(args)); - } - public static JInterfaceInvokeExpr newInterfaceInvokeExpr( Local base, MethodSignature method, Immediate arg) { return newInterfaceInvokeExpr(base, method, Collections.singletonList(arg)); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java similarity index 99% rename from sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarInputLocationTest.java rename to sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java index 67c9d8f32e7..e091efe502e 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java @@ -39,7 +39,7 @@ import sootup.java.core.views.JavaView; @Category(Java8Test.class) -public class MultiReleaseJarInputLocationTest extends AnalysisInputLocationTest { +public class MultiReleaseJarAnalysisInputLocationTest extends AnalysisInputLocationTest { @Test public void multiReleaseJar() { diff --git a/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java b/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java index 1525668fc69..9c37ec2e8ab 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java +++ b/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java @@ -28,14 +28,9 @@ public MutableJavaView(@Nonnull AnalysisInputLocation inputLocation) { this(Collections.singletonList(inputLocation)); } - public MutableJavaView(@Nonnull List inputLocations) { - super(inputLocations, new MutableFullCacheProvider()); - } - public MutableJavaView( - @Nonnull List inputLocations, - @Nonnull SourceTypeSpecifier sourceTypeSpecifier) { - super(inputLocations, new MutableFullCacheProvider(), sourceTypeSpecifier); + @Nonnull List inputLocations) { + super(inputLocations, new MutableFullCacheProvider()); } /** diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java index 5a272813eff..d7e36ccde0e 100644 --- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java +++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java @@ -47,16 +47,8 @@ public JimpleView(@Nonnull List inputLocations) { public JimpleView( @Nonnull List inputLocations, @Nonnull ClassCacheProvider cacheProvider) { - this(inputLocations, cacheProvider, DefaultSourceTypeSpecifier.getInstance()); - } - - public JimpleView( - @Nonnull List inputLocations, - @Nonnull ClassCacheProvider cacheProvider, - @Nonnull SourceTypeSpecifier sourceTypeSpecifier) { this.inputLocations = inputLocations; this.cache = cacheProvider.createCache(); - this.sourceTypeSpecifier = sourceTypeSpecifier; } @Override From c2a60b745a16fcfa3e2d36b5725bf24f707689b7 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 12 Jan 2024 18:00:26 +0100 Subject: [PATCH 15/57] cleanup --- .../main/java/sootup/core/jimple/Jimple.java | 1 - .../MultiReleaseJarAnalysisInputLocation.java | 144 +++++++++--------- .../AnalysisInputLocationTest.java | 2 - ...tiReleaseJarAnalysisInputLocationTest.java | 14 +- .../java/core/views/JavaModuleView.java | 1 - .../java/sootup/java/core/views/JavaView.java | 4 +- .../java/core/views/MutableJavaView.java | 4 +- 7 files changed, 83 insertions(+), 87 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/jimple/Jimple.java b/sootup.core/src/main/java/sootup/core/jimple/Jimple.java index d6ec617df28..d9c6dcb78ff 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/Jimple.java +++ b/sootup.core/src/main/java/sootup/core/jimple/Jimple.java @@ -365,7 +365,6 @@ public static JSpecialInvokeExpr newSpecialInvokeExpr( return new JSpecialInvokeExpr(base, method, args); } - public static JSpecialInvokeExpr newSpecialInvokeExpr( Local base, MethodSignature method, Immediate arg) { return newSpecialInvokeExpr(base, method, Collections.singletonList(arg)); diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index c50ccf147a9..51cfd240205 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -51,36 +51,31 @@ /** * If the user wants to analyze a Multi-Release Jar, they have to specify the language level to - * analyze explicitly + * analyze explicitly. if there is no match for the given language level, the default location + * inside the jar will be used. */ public class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation implements ModuleInfoAnalysisInputLocation { @Nonnull private final Language language; - - @Nonnull - public List getAvailableVersions() { - return availableVersions; - } - @Nonnull private final List availableVersions; @Nonnull private final Map> moduleInfoMap = new HashMap<>(); @Nonnull private final Map> inputLocations = new HashMap<>(); - @Nonnull private final List baseInputLocations = new ArrayList<>(); - boolean isResolved = false; - public MultiReleaseJarAnalysisInputLocation( @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { super(path, srcType); this.language = language; - FileSystem fs; + if (!isMultiReleaseJar(path)) { + throw new IllegalArgumentException("The given path does not point to a multi release jar."); + } + FileSystem fs; try { fs = fileSystemCache.get(path); } catch (ExecutionException e) { @@ -116,22 +111,34 @@ private void discoverInputLocations() { String sep = archiveRoot.getFileSystem().getSeparator(); - if (!isResolved) { + for (int i = availableVersions.size() - 1; i >= 0; i--) { + Integer version = availableVersions.get(i); + inputLocations.put(version, new ArrayList<>()); + + final Path versionRoot = + archiveRoot.getFileSystem().getPath("/META-INF/versions/" + version + sep); + + // only versions >= 9 support java modules + if (version > 8) { + moduleInfoMap.put(version, new HashMap<>()); + try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { + for (Path entry : stream) { - for (int i = availableVersions.size() - 1; i >= 0; i--) { - Integer version = availableVersions.get(i); - inputLocations.put(version, new ArrayList<>()); + Path mi = path.resolve(moduleInfoFilename); - final Path versionRoot = - archiveRoot.getFileSystem().getPath("/META-INF/versions/" + version + sep); + if (Files.exists(mi)) { + JavaModuleInfo moduleInfo = new AsmModuleSource(mi); + ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); + JavaModulePathAnalysisInputLocation inputLocation = + new JavaModulePathAnalysisInputLocation( + versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - // only versions >= 9 support java modules - if (version > 8) { - moduleInfoMap.put(version, new HashMap<>()); - try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { - for (Path entry : stream) { + inputLocations.get(version).add(inputLocation); + moduleInfoMap.get(version).put(moduleSignature, moduleInfo); + } - Path mi = path.resolve(moduleInfoFilename); + if (Files.isDirectory(entry)) { + mi = versionRoot.resolve(moduleInfoFilename); if (Files.exists(mi)) { JavaModuleInfo moduleInfo = new AsmModuleSource(mi); @@ -143,71 +150,55 @@ private void discoverInputLocations() { inputLocations.get(version).add(inputLocation); moduleInfoMap.get(version).put(moduleSignature, moduleInfo); } - - if (Files.isDirectory(entry)) { - mi = versionRoot.resolve(moduleInfoFilename); - - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - - inputLocations.get(version).add(inputLocation); - moduleInfoMap.get(version).put(moduleSignature, moduleInfo); - } - // else TODO [bh] can we have automatic modules here? - } + // else TODO [bh] can we have automatic modules here? } - } catch (IOException e) { - throw new IllegalArgumentException("Could not index the file.", e); } + } catch (IOException e) { + throw new IllegalArgumentException("Could not index the file.", e); } + } - // if there was no module or the version is not > 8, we just add a directory based input - // location - if (inputLocations.get(version).isEmpty()) { - inputLocations - .get(version) - .add(PathBasedAnalysisInputLocation.create(versionRoot, sourceType)); - } + // if there was no module or the version is not > 8, we just add a directory based input + // location + if (inputLocations.get(version).isEmpty()) { + inputLocations + .get(version) + .add(PathBasedAnalysisInputLocation.create(versionRoot, sourceType)); } } - - isResolved = true; } @Override @Nonnull public Optional getClassSource(@Nonnull ClassType type, @Nonnull View view) { - Collection il = getBestMatchingInputLocationsRaw(language.getVersion()); + Collection inputLocations = + getBestMatchingInputLocationsRaw(language.getVersion()); - Collection baseIl = getBaseInputLocations(); + Collection baseInputLocations = getBaseInputLocations(); if (type instanceof ModuleJavaClassType) { - il = - il.stream() + inputLocations = + inputLocations.stream() .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) .collect(Collectors.toList()); - baseIl = - baseIl.stream() + baseInputLocations = + baseInputLocations.stream() .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) .collect(Collectors.toList()); } else { - il = - il.stream() + inputLocations = + inputLocations.stream() .filter(location -> !(location instanceof ModuleInfoAnalysisInputLocation)) .collect(Collectors.toList()); - baseIl = - baseIl.stream() + baseInputLocations = + baseInputLocations.stream() .filter(location -> !(location instanceof ModuleInfoAnalysisInputLocation)) .collect(Collectors.toList()); } Optional foundClass = - il.stream() + inputLocations.stream() .map(location -> location.getClassSource(type, view)) .filter(Optional::isPresent) .limit(1) @@ -218,7 +209,7 @@ public Optional getClassSource(@Nonnull ClassType type, @No if (foundClass.isPresent()) { return foundClass; } else { - return baseIl.stream() + return baseInputLocations.stream() .map(location -> location.getClassSource(type, view)) .filter(Optional::isPresent) .limit(1) @@ -322,20 +313,12 @@ public Set getModules(@Nonnull View view) { @Nonnull public Language getLanguage() { - return this.language; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof PathBasedAnalysisInputLocation)) { - return false; - } - return path.equals(((PathBasedAnalysisInputLocation) o).path); + return language; } - @Override - public int hashCode() { - return path.hashCode(); + @Nonnull + public List getAvailableVersions() { + return availableVersions; } @Nonnull @@ -365,4 +348,17 @@ private static boolean isMultiReleaseJar(Path path) { throw new IllegalArgumentException("File not found.", e); } } + + @Override + public boolean equals(Object o) { + if (!(o instanceof MultiReleaseJarAnalysisInputLocation)) { + return false; + } + return path.equals(((MultiReleaseJarAnalysisInputLocation) o).path); + } + + @Override + public int hashCode() { + return path.hashCode(); + } } diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java index 2274a28849d..07fdfd7a606 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/AnalysisInputLocationTest.java @@ -44,8 +44,6 @@ public abstract class AnalysisInputLocationTest { final Path war = Paths.get("../shared-test-resources/java-warApp/dummyWarApp.war"); final Path jar = Paths.get("../shared-test-resources/java-miniapps/MiniApp.jar"); - final Path mrj = Paths.get("../shared-test-resources/multi-release-jar/mrjar.jar"); - final Path mmrj = Paths.get("../shared-test-resources/multi-release-jar-modular/mrjar.jar"); final Path apk = Paths.get("../shared-test-resources/apk/SimpleApk.apk"); final Path cls = Paths.get("../shared-test-resources/miniTestSuite/java6/binary/Employee.class"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java index e091efe502e..aeba3d84348 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java @@ -25,6 +25,8 @@ import static org.junit.Assert.assertFalse; import categories.Java8Test; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Collections; import org.junit.Assert; import org.junit.Test; @@ -41,12 +43,11 @@ @Category(Java8Test.class) public class MultiReleaseJarAnalysisInputLocationTest extends AnalysisInputLocationTest { + final Path mrj = Paths.get("../shared-test-resources/multi-release-jar/mrjar.jar"); + final Path mmrj = Paths.get("../shared-test-resources/multi-release-jar-modular/mrjar.jar"); + @Test public void multiReleaseJar() { - final ClassType classType = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); final JavaView view_min = new JavaView( @@ -69,6 +70,11 @@ public void multiReleaseJar() { new MultiReleaseJarAnalysisInputLocation( mrj, SourceType.Application, new JavaLanguage(Integer.MAX_VALUE))); + final ClassType classType = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); + final ClassType classType2 = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); + // for java10 Assert.assertEquals( "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", 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 f8be95a5e67..8cbf1b7aef5 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 @@ -27,7 +27,6 @@ import java.util.stream.Collectors; 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; 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 063cca185ae..1f4e92bdf44 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 @@ -28,7 +28,6 @@ import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Nonnull; - import sootup.core.cache.ClassCache; import sootup.core.cache.FullCache; import sootup.core.cache.provider.ClassCacheProvider; @@ -143,7 +142,8 @@ protected synchronized Optional buildClassFrom(AbstractClassSourc JavaSootClass theClass; if (!cache.hasClass(classType)) { theClass = - (JavaSootClass) classSource.buildClass(classSource.getAnalysisInputLocation().getSourceType()); + (JavaSootClass) + classSource.buildClass(classSource.getAnalysisInputLocation().getSourceType()); cache.putClass(classType, theClass); } else { theClass = (JavaSootClass) cache.getClass(classType); diff --git a/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java b/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java index 9c37ec2e8ab..861d2940399 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java +++ b/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java @@ -5,7 +5,6 @@ import javax.annotation.Nonnull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sootup.core.SourceTypeSpecifier; import sootup.core.ViewChangeListener; import sootup.core.cache.MutableClassCache; import sootup.core.cache.provider.MutableFullCacheProvider; @@ -28,8 +27,7 @@ public MutableJavaView(@Nonnull AnalysisInputLocation inputLocation) { this(Collections.singletonList(inputLocation)); } - public MutableJavaView( - @Nonnull List inputLocations) { + public MutableJavaView(@Nonnull List inputLocations) { super(inputLocations, new MutableFullCacheProvider()); } From 38f037575fdf1dbe3aead10ff753d17ef80c60bc Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 12 Jan 2024 18:38:06 +0100 Subject: [PATCH 16/57] test if multi release --- .../MultiReleaseJarAnalysisInputLocation.java | 13 ++++--------- .../MultiReleaseJarAnalysisInputLocationTest.java | 4 ++++ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index 51cfd240205..0a9c5e5506d 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -93,17 +93,12 @@ public MultiReleaseJarAnalysisInputLocation( throw new IllegalStateException("Can not index the given file.", e); } - discoverInputLocations(); + discoverInputLocations(fs); } /** Discovers all input locations for different java versions in this multi release jar */ - private void discoverInputLocations() { - FileSystem fs; - try { - fs = fileSystemCache.get(path); - } catch (ExecutionException e) { - throw new IllegalStateException("Can not index the given file.", e); - } + private void discoverInputLocations(@Nonnull FileSystem fs) { + final Path archiveRoot = fs.getPath("/"); final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; @@ -329,7 +324,7 @@ protected String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClas return super.fromPath(baseDirPath, packageNamePathAndClass); } - private static boolean isMultiReleaseJar(Path path) { + public static boolean isMultiReleaseJar(Path path) { try { FileInputStream inputStream = new FileInputStream(path.toFile()); JarInputStream jarStream = new JarInputStream(inputStream); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java index aeba3d84348..3efac8b35ba 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java @@ -23,6 +23,7 @@ */ import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import categories.Java8Test; import java.nio.file.Path; @@ -75,6 +76,9 @@ public void multiReleaseJar() { final ClassType classType2 = getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); + assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mrj)); + assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mmrj)); + // for java10 Assert.assertEquals( "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", From ee9345cf7496edc7680bffea5c240272823f5d21 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 12 Jan 2024 19:09:42 +0100 Subject: [PATCH 17/57] refactor --- .../MultiReleaseJarAnalysisInputLocation.java | 533 +++++++++--------- 1 file changed, 251 insertions(+), 282 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index 0a9c5e5506d..b7a00398e21 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -22,6 +22,21 @@ * #L% */ +import com.google.common.collect.Streams; +import sootup.core.Language; +import sootup.core.inputlocation.AnalysisInputLocation; +import sootup.core.model.SourceType; +import sootup.core.types.ClassType; +import sootup.core.views.View; +import sootup.java.bytecode.frontend.AsmModuleSource; +import sootup.java.core.JavaModuleIdentifierFactory; +import sootup.java.core.JavaModuleInfo; +import sootup.java.core.JavaSootClassSource; +import sootup.java.core.ModuleInfoAnalysisInputLocation; +import sootup.java.core.signatures.ModuleSignature; +import sootup.java.core.types.ModuleJavaClassType; + +import javax.annotation.Nonnull; import java.io.FileInputStream; import java.io.IOException; import java.nio.file.DirectoryStream; @@ -30,24 +45,12 @@ import java.nio.file.Path; import java.util.*; import java.util.concurrent.ExecutionException; +import java.util.function.Predicate; import java.util.jar.Attributes; import java.util.jar.JarInputStream; import java.util.jar.Manifest; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.annotation.Nonnull; -import sootup.core.Language; -import sootup.core.inputlocation.AnalysisInputLocation; -import sootup.core.model.SourceType; -import sootup.core.types.ClassType; -import sootup.core.views.View; -import sootup.java.bytecode.frontend.AsmModuleSource; -import sootup.java.core.JavaModuleIdentifierFactory; -import sootup.java.core.JavaModuleInfo; -import sootup.java.core.JavaSootClassSource; -import sootup.java.core.ModuleInfoAnalysisInputLocation; -import sootup.java.core.signatures.ModuleSignature; -import sootup.java.core.types.ModuleJavaClassType; /** * If the user wants to analyze a Multi-Release Jar, they have to specify the language level to @@ -55,305 +58,271 @@ * inside the jar will be used. */ public class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation - implements ModuleInfoAnalysisInputLocation { - - @Nonnull private final Language language; - @Nonnull private final List availableVersions; + implements ModuleInfoAnalysisInputLocation { - @Nonnull - private final Map> moduleInfoMap = new HashMap<>(); + @Nonnull + private final Language language; + @Nonnull + private final List availableVersions; - @Nonnull private final Map> inputLocations = new HashMap<>(); - @Nonnull private final List baseInputLocations = new ArrayList<>(); + @Nonnull + private final Map> moduleInfoMap = new HashMap<>(); - public MultiReleaseJarAnalysisInputLocation( - @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { - super(path, srcType); - this.language = language; + @Nonnull + private final Map> inputLocations = new HashMap<>(); + @Nonnull + private final List baseInputLocations = new ArrayList<>(); - if (!isMultiReleaseJar(path)) { - throw new IllegalArgumentException("The given path does not point to a multi release jar."); - } - - FileSystem fs; - try { - fs = fileSystemCache.get(path); - } catch (ExecutionException e) { - throw new IllegalArgumentException("Could not open filesystemcache.", e); - } - final Path archiveRoot = fs.getPath("/").getFileSystem().getPath("/META-INF/versions/"); - - try (Stream list = Files.list(archiveRoot)) { - availableVersions = - list.map(dir -> dir.getFileName().toString().replace("/", "")) - .map(Integer::new) - .sorted() - .collect(Collectors.toList()); - } catch (IOException e) { - throw new IllegalStateException("Can not index the given file.", e); - } + public MultiReleaseJarAnalysisInputLocation( + @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { + super(path, srcType); + this.language = language; - discoverInputLocations(fs); - } + if (!isMultiReleaseJar(path)) { + throw new IllegalArgumentException("The given path does not point to a multi release jar."); + } - /** Discovers all input locations for different java versions in this multi release jar */ - private void discoverInputLocations(@Nonnull FileSystem fs) { + FileSystem fs; + try { + fs = fileSystemCache.get(path); + } catch (ExecutionException e) { + throw new IllegalArgumentException("Could not open filesystemcache.", e); + } + final Path archiveRoot = fs.getPath("/"); + Path versionedRoot = archiveRoot.getFileSystem().getPath("/META-INF/versions/"); + + try (Stream list = Files.list(versionedRoot)) { + availableVersions = + list.map(dir -> dir.getFileName().toString().replace("/", "")) + .map(Integer::new) + .sorted() + .collect(Collectors.toList()); + } catch (IOException e) { + throw new IllegalStateException("Can not index the given file.", e); + } - final Path archiveRoot = fs.getPath("/"); - final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; + final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; + + baseInputLocations.add(PathBasedAnalysisInputLocation.create(archiveRoot, sourceType)); + + String sep = archiveRoot.getFileSystem().getSeparator(); + + for (int i = availableVersions.size() - 1; i >= 0; i--) { + Integer version = availableVersions.get(i); + inputLocations.put(version, new ArrayList<>()); + + final Path versionRoot = + archiveRoot.getFileSystem().getPath("/META-INF/versions/" + version + sep); + + // only versions >= 9 support java modules + if (version > 8) { + moduleInfoMap.put(version, new HashMap<>()); + try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { + for (Path entry : stream) { + + Path mi = path.resolve(moduleInfoFilename); + + if (Files.exists(mi)) { + JavaModuleInfo moduleInfo = new AsmModuleSource(mi); + ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); + JavaModulePathAnalysisInputLocation inputLocation = + new JavaModulePathAnalysisInputLocation( + versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); + + inputLocations.get(version).add(inputLocation); + moduleInfoMap.get(version).put(moduleSignature, moduleInfo); + } + + if (Files.isDirectory(entry)) { + mi = versionRoot.resolve(moduleInfoFilename); + + if (Files.exists(mi)) { + JavaModuleInfo moduleInfo = new AsmModuleSource(mi); + ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); + JavaModulePathAnalysisInputLocation inputLocation = + new JavaModulePathAnalysisInputLocation( + versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); + + inputLocations.get(version).add(inputLocation); + moduleInfoMap.get(version).put(moduleSignature, moduleInfo); + } + // else TODO [bh] can we have automatic modules here? + } + } + } catch (IOException e) { + throw new IllegalArgumentException("Could not index the file.", e); + } + } - baseInputLocations.add(PathBasedAnalysisInputLocation.create(archiveRoot, sourceType)); + // if there was no module or the version is not > 8, we just add a directory based input + // location + if (inputLocations.get(version).isEmpty()) { + inputLocations + .get(version) + .add(PathBasedAnalysisInputLocation.create(versionRoot, sourceType)); + } + } + } - String sep = archiveRoot.getFileSystem().getSeparator(); + @Override + @Nonnull + public Optional getClassSource(@Nonnull ClassType type, @Nonnull View view) { - for (int i = availableVersions.size() - 1; i >= 0; i--) { - Integer version = availableVersions.get(i); - inputLocations.put(version, new ArrayList<>()); + Collection inputLocations = + getBestMatchingInputLocationsRaw(language.getVersion()); - final Path versionRoot = - archiveRoot.getFileSystem().getPath("/META-INF/versions/" + version + sep); + Collection baseInputLocations = getBaseInputLocations(); - // only versions >= 9 support java modules - if (version > 8) { - moduleInfoMap.put(version, new HashMap<>()); - try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { - for (Path entry : stream) { + Predicate analysisInputLocationPredicate; + if (type instanceof ModuleJavaClassType) { + analysisInputLocationPredicate = location -> location instanceof ModuleInfoAnalysisInputLocation; + } else { + analysisInputLocationPredicate = location -> !(location instanceof ModuleInfoAnalysisInputLocation); + } - Path mi = path.resolve(moduleInfoFilename); + return Streams.concat( inputLocations.stream().filter(analysisInputLocationPredicate), baseInputLocations.stream().filter(analysisInputLocationPredicate)) + .map(location -> location.getClassSource(type, view)) + .filter(Optional::isPresent) + .limit(1) + .map(Optional::get) + .map(src -> (JavaSootClassSource) src) + .findFirst(); + } - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); + @Nonnull + @Override + public Collection getModulesClassSources( + @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { + return inputLocations.get(language.getVersion()).stream() + .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) + .map( + location -> + ((ModuleInfoAnalysisInputLocation) location) + .getModulesClassSources(moduleSignature, view)) + .flatMap(Collection::stream) + .map(src -> (JavaSootClassSource) src) + .collect(Collectors.toList()); + } - inputLocations.get(version).add(inputLocation); - moduleInfoMap.get(version).put(moduleSignature, moduleInfo); + /** + * Returns the best matching input locations or the base input location. + * + * @param javaVersion version to find best match to + * @return best match or base input locations + */ + private Collection getBestMatchingInputLocationsRaw(int javaVersion) { + for (int i = availableVersions.size() - 1; i >= 0; i--) { + + Integer version = availableVersions.get(i); + if (version > javaVersion) { + continue; } - if (Files.isDirectory(entry)) { - mi = versionRoot.resolve(moduleInfoFilename); + return new ArrayList<>(inputLocations.get(version)); + } - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); + return getBaseInputLocations(); + } - inputLocations.get(version).add(inputLocation); - moduleInfoMap.get(version).put(moduleSignature, moduleInfo); - } - // else TODO [bh] can we have automatic modules here? - } - } - } catch (IOException e) { - throw new IllegalArgumentException("Could not index the file.", e); + private Collection getBaseInputLocations() { + return baseInputLocations; + } + + @Override + @Nonnull + public Collection getClassSources(@Nonnull View view) { + Collection il = getBestMatchingInputLocationsRaw(language.getVersion()); + + Collection result = + il.stream() + .map(location -> location.getClassSources(view)) + .flatMap(Collection::stream) + .map(src -> (JavaSootClassSource) src) + .collect(Collectors.toList()); + + if (il != getBaseInputLocations()) { + + Collection baseSources = + getBaseInputLocations().stream() + .map(location -> location.getClassSources(view)) + .flatMap(Collection::stream) + .map(src -> (JavaSootClassSource) src) + .collect(Collectors.toList()); + + baseSources.forEach( + cs -> { + // do not add duplicate class sources + if (result.stream() + .noneMatch( + bestMatchCS -> + bestMatchCS + .getClassType() + .getFullyQualifiedName() + .equals(cs.getClassType().getFullyQualifiedName()))) { + result.add(cs); + } + }); } - } - - // if there was no module or the version is not > 8, we just add a directory based input - // location - if (inputLocations.get(version).isEmpty()) { - inputLocations - .get(version) - .add(PathBasedAnalysisInputLocation.create(versionRoot, sourceType)); - } + + return result; } - } - - @Override - @Nonnull - public Optional getClassSource(@Nonnull ClassType type, @Nonnull View view) { - - Collection inputLocations = - getBestMatchingInputLocationsRaw(language.getVersion()); - - Collection baseInputLocations = getBaseInputLocations(); - - if (type instanceof ModuleJavaClassType) { - inputLocations = - inputLocations.stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .collect(Collectors.toList()); - baseInputLocations = - baseInputLocations.stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .collect(Collectors.toList()); - } else { - inputLocations = - inputLocations.stream() - .filter(location -> !(location instanceof ModuleInfoAnalysisInputLocation)) - .collect(Collectors.toList()); - baseInputLocations = - baseInputLocations.stream() - .filter(location -> !(location instanceof ModuleInfoAnalysisInputLocation)) - .collect(Collectors.toList()); + + @Nonnull + @Override + public Optional getModuleInfo(ModuleSignature sig, View view) { + return Optional.ofNullable(moduleInfoMap.get(language.getVersion()).get(sig)); } - Optional foundClass = - inputLocations.stream() - .map(location -> location.getClassSource(type, view)) - .filter(Optional::isPresent) - .limit(1) - .map(Optional::get) - .map(src -> (JavaSootClassSource) src) - .findAny(); - - if (foundClass.isPresent()) { - return foundClass; - } else { - return baseInputLocations.stream() - .map(location -> location.getClassSource(type, view)) - .filter(Optional::isPresent) - .limit(1) - .map(Optional::get) - .map(src -> (JavaSootClassSource) src) - .findAny(); + @Nonnull + @Override + public Set getModules(@Nonnull View view) { + return inputLocations.get(language.getVersion()).stream() + .filter(e -> e instanceof ModuleInfoAnalysisInputLocation) + .map(e -> ((ModuleInfoAnalysisInputLocation) e).getModules(view)) + .flatMap(Set::stream) + .collect(Collectors.toSet()); } - } - - @Nonnull - @Override - public Collection getModulesClassSources( - @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { - return inputLocations.get(language.getVersion()).stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .map( - location -> - ((ModuleInfoAnalysisInputLocation) location) - .getModulesClassSources(moduleSignature, view)) - .flatMap(Collection::stream) - .map(src -> (JavaSootClassSource) src) - .collect(Collectors.toList()); - } - - /** - * Returns the best matching input locations or the base input location. - * - * @param javaVersion version to find best match to - * @return best match or base input locations - */ - private Collection getBestMatchingInputLocationsRaw(int javaVersion) { - for (int i = availableVersions.size() - 1; i >= 0; i--) { - - Integer version = availableVersions.get(i); - if (version > javaVersion) continue; - - return new ArrayList<>(inputLocations.get(version)); + + @Nonnull + public Language getLanguage() { + return language; } - return getBaseInputLocations(); - } - - private Collection getBaseInputLocations() { - return baseInputLocations; - } - - @Override - @Nonnull - public Collection getClassSources(@Nonnull View view) { - Collection il = getBestMatchingInputLocationsRaw(language.getVersion()); - - Collection result = - il.stream() - .map(location -> location.getClassSources(view)) - .flatMap(Collection::stream) - .map(src -> (JavaSootClassSource) src) - .collect(Collectors.toList()); - - if (il != getBaseInputLocations()) { - - Collection baseSources = - getBaseInputLocations().stream() - .map(location -> location.getClassSources(view)) - .flatMap(Collection::stream) - .map(src -> (JavaSootClassSource) src) - .collect(Collectors.toList()); - - baseSources.forEach( - cs -> { - // do not add duplicate class sources - if (result.stream() - .noneMatch( - bestMatchCS -> - bestMatchCS - .getClassType() - .getFullyQualifiedName() - .equals(cs.getClassType().getFullyQualifiedName()))) { - result.add(cs); - } - }); + @Nonnull + public List getAvailableVersions() { + return availableVersions; } - return result; - } - - @Nonnull - @Override - public Optional getModuleInfo(ModuleSignature sig, View view) { - return Optional.ofNullable(moduleInfoMap.get(language.getVersion()).get(sig)); - } - - @Nonnull - @Override - public Set getModules(@Nonnull View view) { - return inputLocations.get(language.getVersion()).stream() - .filter(e -> e instanceof ModuleInfoAnalysisInputLocation) - .map(e -> ((ModuleInfoAnalysisInputLocation) e).getModules(view)) - .flatMap(Set::stream) - .collect(Collectors.toSet()); - } - - @Nonnull - public Language getLanguage() { - return language; - } - - @Nonnull - public List getAvailableVersions() { - return availableVersions; - } - - @Nonnull - @Override - protected String fromPath(@Nonnull Path baseDirPath, Path packageNamePathAndClass) { - // FIXME: [ms] implement specific handling of the versioned path -> - // /META-INF/versions/{Java_Version}/ -> cut 3 directories - return super.fromPath(baseDirPath, packageNamePathAndClass); - } - - public static boolean isMultiReleaseJar(Path path) { - try { - FileInputStream inputStream = new FileInputStream(path.toFile()); - JarInputStream jarStream = new JarInputStream(inputStream); - Manifest mf = jarStream.getManifest(); - - if (mf == null) { - return false; - } - - Attributes attributes = mf.getMainAttributes(); - - String value = attributes.getValue("Multi-Release"); - - return Boolean.parseBoolean(value); - } catch (IOException e) { - throw new IllegalArgumentException("File not found.", e); + public static boolean isMultiReleaseJar(Path path) { + try { + FileInputStream inputStream = new FileInputStream(path.toFile()); + JarInputStream jarStream = new JarInputStream(inputStream); + Manifest mf = jarStream.getManifest(); + + if (mf == null) { + return false; + } + + Attributes attributes = mf.getMainAttributes(); + + String value = attributes.getValue("Multi-Release"); + + return Boolean.parseBoolean(value); + } catch (IOException e) { + throw new IllegalArgumentException("File not found.", e); + } } - } - @Override - public boolean equals(Object o) { - if (!(o instanceof MultiReleaseJarAnalysisInputLocation)) { - return false; + @Override + public boolean equals(Object o) { + if (!(o instanceof MultiReleaseJarAnalysisInputLocation)) { + return false; + } + return path.equals(((MultiReleaseJarAnalysisInputLocation) o).path); } - return path.equals(((MultiReleaseJarAnalysisInputLocation) o).path); - } - @Override - public int hashCode() { - return path.hashCode(); - } + @Override + public int hashCode() { + return path.hashCode(); + } } From d9c2ff5917d88fe7c03edaa16b4266490c1d35ca Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 15 Jan 2024 20:37:09 +0100 Subject: [PATCH 18/57] refactor MultiReleaseJarAnalysisInputLocation --- .../MultiReleaseJarAnalysisInputLocation.java | 234 +++------- ...tiReleaseJarAnalysisInputLocationTest.java | 422 +++++++++--------- 2 files changed, 276 insertions(+), 380 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index b7a00398e21..2d680512700 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -22,56 +22,49 @@ * #L% */ -import com.google.common.collect.Streams; import sootup.core.Language; +import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.model.SourceType; import sootup.core.types.ClassType; import sootup.core.views.View; -import sootup.java.bytecode.frontend.AsmModuleSource; -import sootup.java.core.JavaModuleIdentifierFactory; import sootup.java.core.JavaModuleInfo; import sootup.java.core.JavaSootClassSource; import sootup.java.core.ModuleInfoAnalysisInputLocation; import sootup.java.core.signatures.ModuleSignature; -import sootup.java.core.types.ModuleJavaClassType; import javax.annotation.Nonnull; import java.io.FileInputStream; import java.io.IOException; -import java.nio.file.DirectoryStream; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.concurrent.ExecutionException; -import java.util.function.Predicate; import java.util.jar.Attributes; import java.util.jar.JarInputStream; import java.util.jar.Manifest; -import java.util.stream.Collectors; import java.util.stream.Stream; /** * If the user wants to analyze a Multi-Release Jar, they have to specify the language level to * analyze explicitly. if there is no match for the given language level, the default location * inside the jar will be used. + *

+ * see JEP 238 */ -public class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation - implements ModuleInfoAnalysisInputLocation { +public class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation { - @Nonnull - private final Language language; - @Nonnull - private final List availableVersions; + // ModularInputLocations exist since Java 9 -> in previous language levels its structured like a "usual" Jar + protected static final Integer DEFAULT_VERSION = 0; @Nonnull - private final Map> moduleInfoMap = new HashMap<>(); - + protected final Language language; @Nonnull - private final Map> inputLocations = new HashMap<>(); + protected final List availableVersions; + @Nonnull - private final List baseInputLocations = new ArrayList<>(); + protected final Map inputLocations = new LinkedHashMap<>(); public MultiReleaseJarAnalysisInputLocation( @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { @@ -91,196 +84,69 @@ public MultiReleaseJarAnalysisInputLocation( final Path archiveRoot = fs.getPath("/"); Path versionedRoot = archiveRoot.getFileSystem().getPath("/META-INF/versions/"); + availableVersions = new ArrayList<>(); try (Stream list = Files.list(versionedRoot)) { - availableVersions = list.map(dir -> dir.getFileName().toString().replace("/", "")) .map(Integer::new) .sorted() - .collect(Collectors.toList()); + .forEach(availableVersions::add); } catch (IOException e) { throw new IllegalStateException("Can not index the given file.", e); } - final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; - - baseInputLocations.add(PathBasedAnalysisInputLocation.create(archiveRoot, sourceType)); - - String sep = archiveRoot.getFileSystem().getSeparator(); - for (int i = availableVersions.size() - 1; i >= 0; i--) { Integer version = availableVersions.get(i); - inputLocations.put(version, new ArrayList<>()); - - final Path versionRoot = - archiveRoot.getFileSystem().getPath("/META-INF/versions/" + version + sep); - - // only versions >= 9 support java modules - if (version > 8) { - moduleInfoMap.put(version, new HashMap<>()); - try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { - for (Path entry : stream) { - - Path mi = path.resolve(moduleInfoFilename); - - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - - inputLocations.get(version).add(inputLocation); - moduleInfoMap.get(version).put(moduleSignature, moduleInfo); - } - - if (Files.isDirectory(entry)) { - mi = versionRoot.resolve(moduleInfoFilename); - - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - - inputLocations.get(version).add(inputLocation); - moduleInfoMap.get(version).put(moduleSignature, moduleInfo); - } - // else TODO [bh] can we have automatic modules here? - } - } - } catch (IOException e) { - throw new IllegalArgumentException("Could not index the file.", e); - } - } - - // if there was no module or the version is not > 8, we just add a directory based input - // location - if (inputLocations.get(version).isEmpty()) { - inputLocations - .get(version) - .add(PathBasedAnalysisInputLocation.create(versionRoot, sourceType)); + if (version > language.getVersion()) { + continue; } + final Path versionRoot = archiveRoot.getFileSystem().getPath("/META-INF", "versions", version.toString()); + inputLocations.put(version, createAnalysisInputLocation(versionRoot)); } + inputLocations.put(DEFAULT_VERSION, createAnalysisInputLocation(archiveRoot)); } - @Override - @Nonnull - public Optional getClassSource(@Nonnull ClassType type, @Nonnull View view) { - - Collection inputLocations = - getBestMatchingInputLocationsRaw(language.getVersion()); - - Collection baseInputLocations = getBaseInputLocations(); - - Predicate analysisInputLocationPredicate; - if (type instanceof ModuleJavaClassType) { - analysisInputLocationPredicate = location -> location instanceof ModuleInfoAnalysisInputLocation; - } else { - analysisInputLocationPredicate = location -> !(location instanceof ModuleInfoAnalysisInputLocation); - } - - return Streams.concat( inputLocations.stream().filter(analysisInputLocationPredicate), baseInputLocations.stream().filter(analysisInputLocationPredicate)) - .map(location -> location.getClassSource(type, view)) - .filter(Optional::isPresent) - .limit(1) - .map(Optional::get) - .map(src -> (JavaSootClassSource) src) - .findFirst(); + protected AnalysisInputLocation createAnalysisInputLocation(Path archiveRoot) { + return PathBasedAnalysisInputLocation.create(archiveRoot, sourceType); } - @Nonnull @Override - public Collection getModulesClassSources( - @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { - return inputLocations.get(language.getVersion()).stream() - .filter(location -> location instanceof ModuleInfoAnalysisInputLocation) - .map( - location -> - ((ModuleInfoAnalysisInputLocation) location) - .getModulesClassSources(moduleSignature, view)) - .flatMap(Collection::stream) - .map(src -> (JavaSootClassSource) src) - .collect(Collectors.toList()); - } - - /** - * Returns the best matching input locations or the base input location. - * - * @param javaVersion version to find best match to - * @return best match or base input locations - */ - private Collection getBestMatchingInputLocationsRaw(int javaVersion) { - for (int i = availableVersions.size() - 1; i >= 0; i--) { - - Integer version = availableVersions.get(i); - if (version > javaVersion) { - continue; + @Nonnull + public Optional getClassSource(@Nonnull ClassType type, @Nonnull View view) { + for (AnalysisInputLocation analysisInputLocation : inputLocations.values()) { + Optional classSource = analysisInputLocation.getClassSource(type, view); + if (classSource.isPresent()) { + SootClassSource src = classSource.get(); + JavaSootClassSource javaSootClassSource = (JavaSootClassSource) src; + return Optional.of(javaSootClassSource); } - - return new ArrayList<>(inputLocations.get(version)); } - - return getBaseInputLocations(); - } - - private Collection getBaseInputLocations() { - return baseInputLocations; + return Optional.empty(); } @Override @Nonnull public Collection getClassSources(@Nonnull View view) { - Collection il = getBestMatchingInputLocationsRaw(language.getVersion()); - - Collection result = - il.stream() - .map(location -> location.getClassSources(view)) - .flatMap(Collection::stream) - .map(src -> (JavaSootClassSource) src) - .collect(Collectors.toList()); - - if (il != getBaseInputLocations()) { - - Collection baseSources = - getBaseInputLocations().stream() - .map(location -> location.getClassSources(view)) - .flatMap(Collection::stream) - .map(src -> (JavaSootClassSource) src) - .collect(Collectors.toList()); - - baseSources.forEach( - cs -> { - // do not add duplicate class sources - if (result.stream() - .noneMatch( - bestMatchCS -> - bestMatchCS - .getClassType() - .getFullyQualifiedName() - .equals(cs.getClassType().getFullyQualifiedName()))) { - result.add(cs); - } - }); - } - return result; - } + Collection classSources = new ArrayList<>(); + inputLocations.values().stream() + .map(location -> location.getClassSources(view)) + .flatMap(Collection::stream) + .map(src -> (JavaSootClassSource) src) + .forEach( + cs -> { + // do not add duplicate class sources + if (classSources.stream() + .noneMatch( + bestMatchCS -> + bestMatchCS + .getClassType() + .getFullyQualifiedName() + .equals(cs.getClassType().getFullyQualifiedName()))) { + classSources.add(cs); + } + }); - @Nonnull - @Override - public Optional getModuleInfo(ModuleSignature sig, View view) { - return Optional.ofNullable(moduleInfoMap.get(language.getVersion()).get(sig)); - } - - @Nonnull - @Override - public Set getModules(@Nonnull View view) { - return inputLocations.get(language.getVersion()).stream() - .filter(e -> e instanceof ModuleInfoAnalysisInputLocation) - .map(e -> ((ModuleInfoAnalysisInputLocation) e).getModules(view)) - .flatMap(Set::stream) - .collect(Collectors.toSet()); + return classSources; } @Nonnull @@ -307,6 +173,10 @@ public static boolean isMultiReleaseJar(Path path) { String value = attributes.getValue("Multi-Release"); + if (value == null) { + return false; + } + return Boolean.parseBoolean(value); } catch (IOException e) { throw new IllegalArgumentException("File not found.", e); @@ -326,3 +196,5 @@ public int hashCode() { return path.hashCode(); } } + + diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java index 3efac8b35ba..0bd04ff18b9 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java @@ -26,221 +26,245 @@ import static org.junit.Assert.assertTrue; import categories.Java8Test; + import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; + import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; +import sootup.core.Language; +import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.model.SourceType; import sootup.core.types.ClassType; import sootup.java.core.JavaModuleIdentifierFactory; +import sootup.java.core.ModuleInfoAnalysisInputLocation; import sootup.java.core.language.JavaLanguage; import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.ModuleJavaClassType; import sootup.java.core.views.JavaModuleView; import sootup.java.core.views.JavaView; +import javax.annotation.Nonnull; + @Category(Java8Test.class) public class MultiReleaseJarAnalysisInputLocationTest extends AnalysisInputLocationTest { - final Path mrj = Paths.get("../shared-test-resources/multi-release-jar/mrjar.jar"); - final Path mmrj = Paths.get("../shared-test-resources/multi-release-jar-modular/mrjar.jar"); - - @Test - public void multiReleaseJar() { - - final JavaView view_min = - new JavaView( - new MultiReleaseJarAnalysisInputLocation( - mrj, SourceType.Application, new JavaLanguage(1))); - final JavaView view_8 = - new JavaView( - new MultiReleaseJarAnalysisInputLocation( - mrj, SourceType.Application, new JavaLanguage(8))); - final JavaView view_9 = - new JavaView( - new MultiReleaseJarAnalysisInputLocation( - mrj, SourceType.Application, new JavaLanguage(9))); - final JavaView view_10 = - new JavaView( - new MultiReleaseJarAnalysisInputLocation( - mrj, SourceType.Application, new JavaLanguage(10))); - final JavaView view_max = - new JavaView( - new MultiReleaseJarAnalysisInputLocation( - mrj, SourceType.Application, new JavaLanguage(Integer.MAX_VALUE))); - - final ClassType classType = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - - assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mrj)); - assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mmrj)); - - // for java10 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_10.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_10.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // assert that method is correctly resolved - Assert.assertTrue( - view_10 - .getClass(classType) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 9")); - - // for java 9 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_9.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // for java 8 - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_8 - .getClass(classType) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); - - // for max int - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_max.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // for min int - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_min.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_min.getClass(classType2).get().getClassSource().getSourcePath().toString()); - } - - @Test - public void modularMultiReleaseJar() { - final ClassType utilityNoModule = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - - final ModuleJavaClassType utilityModule = - JavaModuleIdentifierFactory.getInstance() - .getClassType("de.upb.swt.multirelease/de.upb.swt.multirelease.Utility"); - - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - - MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation8 = - new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); - final JavaView view_8 = - new JavaView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation8)); - - MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation9 = - new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(9)); - final JavaModuleView view_9 = - new JavaModuleView( - Collections.emptyList(), - Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation9)); - - ModuleSignature moduleSignature = - JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); - - Assert.assertEquals(Collections.singleton(moduleSignature), view_9.getNamedModules()); - - Assert.assertTrue(view_9.getModuleInfo(moduleSignature).isPresent()); - - Assert.assertEquals(1, view_9.getModuleClasses(moduleSignature).size()); - - Assert.assertEquals( - "de.upb.swt.multirelease.Utility", - view_9.getModuleClasses(moduleSignature).stream() - .findAny() - .get() - .getType() - .getFullyQualifiedName()); - - // for java 9 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityModule).get().getClassSource().getSourcePath().toString()); - // different class will be returned if no module is specified - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_9 - .getClass(utilityModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 9")); - - // for java 8 - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - assertFalse(view_8.getClass(utilityModule).isPresent()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_8 - .getClass(utilityNoModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); - } + final Path mrj = Paths.get("../shared-test-resources/multi-release-jar/mrjar.jar"); + final Path mmrj = Paths.get("../shared-test-resources/multi-release-jar-modular/mrjar.jar"); + + @Test + public void multiReleaseJar() { + + final JavaView view_min = + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(1))); + final JavaView view_8 = + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(8))); + final JavaView view_9 = + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(9))); + final JavaView view_10 = + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(10))); + final JavaView view_max = + new JavaView( + new MultiReleaseJarAnalysisInputLocation( + mrj, SourceType.Application, new JavaLanguage(Integer.MAX_VALUE))); + + final ClassType classType = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); + final ClassType classType2 = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); + + assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mrj)); + assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mmrj)); + + // for java10 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_10.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_10.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // assert that method is correctly resolved + Assert.assertTrue( + view_10 + .getClass(classType) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 9")); + + // for java 9 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_9.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // for java 8 + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_8.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_8 + .getClass(classType) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 8")); + + // for max int + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_max.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // for min int + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_min.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_min.getClass(classType2).get().getClassSource().getSourcePath().toString()); + } + + @Test + public void modularMultiReleaseJar() { + final ClassType utilityNoModule = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); + + final ModuleJavaClassType utilityModule = + JavaModuleIdentifierFactory.getInstance() + .getClassType("de.upb.swt.multirelease/de.upb.swt.multirelease.Utility"); + + final ClassType classType2 = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); + + MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation8 = + new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); + final JavaView view_8 = + new JavaView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation8)); + + ModuleMultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation9 = + new ModuleMultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(9)); + final JavaModuleView view_9 = + new JavaModuleView( + Collections.emptyList(), + Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation9) + ); + ModuleSignature moduleSignature = + JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); + + Assert.assertEquals(Collections.singleton(moduleSignature), view_9.getNamedModules()); + + Assert.assertTrue(view_9.getModuleInfo(moduleSignature).isPresent()); + + Assert.assertEquals(1, view_9.getModuleClasses(moduleSignature).size()); + + Assert.assertEquals( + "de.upb.swt.multirelease.Utility", + view_9.getModuleClasses(moduleSignature).stream() + .findAny() + .get() + .getType() + .getFullyQualifiedName()); + + // for java 9 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_9.getClass(utilityModule).get().getClassSource().getSourcePath().toString()); + // different class will be returned if no module is specified + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_9.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_9 + .getClass(utilityModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 9")); + + + // for java 8 + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_8.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); + assertFalse(view_8.getClass(utilityModule).isPresent()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_8 + .getClass(utilityNoModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 8")); + + + Assert.assertTrue( + view_8 + .getClass(utilityNoModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 8")); + } } From 628a5248943baf28117fed7aeb5c77ff9180ea10 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 16 Jan 2024 10:48:46 +0100 Subject: [PATCH 19/57] refactor + extract tests - they definitely need >java8 runtime to run.. why didn't they fail.. or didnt they just *not* work as intended and therefore did not fail. --- ...eMultiReleaseJarAnalysisInputLocation.java | 52 +++++++ ...tiReleaseJarAnalysisInputLocationTest.java | 145 ++++++++++++++++++ ...tiReleaseJarAnalysisInputLocationTest.java | 111 -------------- 3 files changed, 197 insertions(+), 111 deletions(-) create mode 100644 sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java create mode 100644 sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java new file mode 100644 index 00000000000..68b9f11b08f --- /dev/null +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java @@ -0,0 +1,52 @@ +package sootup.java.bytecode.inputlocation; + +import sootup.core.Language; +import sootup.core.frontend.SootClassSource; +import sootup.core.model.SourceType; +import sootup.core.views.View; +import sootup.java.core.JavaModuleInfo; +import sootup.java.core.ModuleInfoAnalysisInputLocation; +import sootup.java.core.signatures.ModuleSignature; + +import javax.annotation.Nonnull; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ExecutionException; + +public class ModuleMultiReleaseJarAnalysisInputLocation extends MultiReleaseJarAnalysisInputLocation implements ModuleInfoAnalysisInputLocation { + public ModuleMultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { + super(path, srcType, language); + } + + @Override + protected ModuleInfoAnalysisInputLocation createAnalysisInputLocation(@Nonnull Path path) { + try { + return new JavaModulePathAnalysisInputLocation(path.toString(), fileSystemCache.get(this.path), sourceType ); + } catch (ExecutionException e) { + throw new IllegalArgumentException("Could not open filesystemcache.", e); + } + } + + + @Override + public Collection getModulesClassSources(@Nonnull ModuleSignature moduleSignature, @Nonnull View view) { + // FIXME: implement + return null; + } + + @Nonnull + @Override + public Optional getModuleInfo(@Nonnull ModuleSignature sig, @Nonnull View view) { + // TODO: check if we need to combine modules as well or if only versioned .class files are allowed + return ( (ModuleInfoAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)).getModuleInfo(sig, view); + } + + @Nonnull + @Override + public Set getModules(@Nonnull View view) { + // TODO: check if we need to combine modules as well or if only versioned .class files are allowed + return ( (ModuleInfoAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)).getModules(view); + } +} diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java new file mode 100644 index 00000000000..5acd3912dc6 --- /dev/null +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java @@ -0,0 +1,145 @@ +package sootup.java.bytecode.inputlocation; + +import categories.Java9Test; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import sootup.core.model.SourceType; +import sootup.core.types.ClassType; +import sootup.java.core.JavaModuleIdentifierFactory; +import sootup.java.core.ModuleInfoAnalysisInputLocation; +import sootup.java.core.language.JavaLanguage; +import sootup.java.core.signatures.ModuleSignature; +import sootup.java.core.types.ModuleJavaClassType; +import sootup.java.core.views.JavaModuleView; +import sootup.java.core.views.JavaView; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@Category(Java9Test.class) +public class ModuleMultiReleaseJarAnalysisInputLocationTest extends AnalysisInputLocationTest { + final Path mmrj = Paths.get("../shared-test-resources/multi-release-jar-modular/mrjar.jar"); + + @Test + public void modularMultiReleaseJar() { + + assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mmrj)); + + final ClassType utilityNoModule = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); + + final ModuleJavaClassType utilityModule = + JavaModuleIdentifierFactory.getInstance() + .getClassType("de.upb.swt.multirelease/de.upb.swt.multirelease.Utility"); + + final ClassType classType2 = + getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); + + ModuleInfoAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation8 = + new ModuleMultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); + + final JavaView view_8 = + new JavaModuleView(Collections.emptyList(), Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation8)); + + ModuleMultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation9 = + new ModuleMultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(9)); + final JavaModuleView view_9 = + new JavaModuleView( + Collections.emptyList(), + Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation9) + ); + ModuleSignature moduleSignature = + JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); + + Assert.assertEquals(Collections.singleton(moduleSignature), view_9.getNamedModules()); + + Assert.assertTrue(view_9.getModuleInfo(moduleSignature).isPresent()); + + Assert.assertEquals(1, view_9.getModuleClasses(moduleSignature).size()); + + Assert.assertEquals( + "de.upb.swt.multirelease.Utility", + view_9.getModuleClasses(moduleSignature).stream() + .findAny() + .get() + .getType() + .getFullyQualifiedName()); + + // for java 9 + Assert.assertEquals( + "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + view_9.getClass(utilityModule).get().getClassSource().getSourcePath().toString()); + // different class will be returned if no module is specified + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_9.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_9 + .getClass(utilityModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 9")); + + + // for java 8 + Assert.assertEquals( + "/de/upb/swt/multirelease/Utility.class", + view_8.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); + assertFalse(view_8.getClass(utilityModule).isPresent()); + Assert.assertEquals( + "/de/upb/swt/multirelease/Main.class", + view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base + Assert.assertTrue( + view_8 + .getClass(utilityNoModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 8")); + + + Assert.assertTrue( + view_8 + .getClass(utilityNoModule) + .get() + .getMethod( + getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList())) + .get() + .getBody() + .toString() + .contains("java 8")); + + + // TODO: test what happens if we put a *non* ModuleClassType into a ModuleMultiReleaseAnalysisInoutLocation + + } +} \ No newline at end of file diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java index 0bd04ff18b9..ac7499db4c1 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java @@ -52,7 +52,6 @@ public class MultiReleaseJarAnalysisInputLocationTest extends AnalysisInputLocationTest { final Path mrj = Paths.get("../shared-test-resources/multi-release-jar/mrjar.jar"); - final Path mmrj = Paths.get("../shared-test-resources/multi-release-jar-modular/mrjar.jar"); @Test public void multiReleaseJar() { @@ -84,7 +83,6 @@ public void multiReleaseJar() { getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mrj)); - assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mmrj)); // for java10 Assert.assertEquals( @@ -158,113 +156,4 @@ public void multiReleaseJar() { view_min.getClass(classType2).get().getClassSource().getSourcePath().toString()); } - @Test - public void modularMultiReleaseJar() { - final ClassType utilityNoModule = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - - final ModuleJavaClassType utilityModule = - JavaModuleIdentifierFactory.getInstance() - .getClassType("de.upb.swt.multirelease/de.upb.swt.multirelease.Utility"); - - final ClassType classType2 = - getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - - MultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation8 = - new MultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(8)); - final JavaView view_8 = - new JavaView(Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation8)); - - ModuleMultiReleaseJarAnalysisInputLocation moduleMultiReleaseJarAnalysisInputLocation9 = - new ModuleMultiReleaseJarAnalysisInputLocation(mmrj, SourceType.Application, new JavaLanguage(9)); - final JavaModuleView view_9 = - new JavaModuleView( - Collections.emptyList(), - Collections.singletonList(moduleMultiReleaseJarAnalysisInputLocation9) - ); - ModuleSignature moduleSignature = - JavaModuleIdentifierFactory.getModuleSignature("de.upb.swt.multirelease"); - - Assert.assertEquals(Collections.singleton(moduleSignature), view_9.getNamedModules()); - - Assert.assertTrue(view_9.getModuleInfo(moduleSignature).isPresent()); - - Assert.assertEquals(1, view_9.getModuleClasses(moduleSignature).size()); - - Assert.assertEquals( - "de.upb.swt.multirelease.Utility", - view_9.getModuleClasses(moduleSignature).stream() - .findAny() - .get() - .getType() - .getFullyQualifiedName()); - - // for java 9 - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityModule).get().getClassSource().getSourcePath().toString()); - // different class will be returned if no module is specified - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_9.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_9 - .getClass(utilityModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 9")); - - - // for java 8 - Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(utilityNoModule).get().getClassSource().getSourcePath().toString()); - assertFalse(view_8.getClass(utilityModule).isPresent()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base - Assert.assertTrue( - view_8 - .getClass(utilityNoModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); - - - Assert.assertTrue( - view_8 - .getClass(utilityNoModule) - .get() - .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) - .get() - .getBody() - .toString() - .contains("java 8")); - } } From be9593a9eb9a2474c20e9a2f30f252cd91a7125f Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 16 Jan 2024 11:32:54 +0100 Subject: [PATCH 20/57] fixup --- .../java/sootup/core/SourceTypeSpecifier.java | 41 ------------------- .../bytecode/interceptors/AggregatorTest.java | 1 + .../frontend/WalaJavaClassProvider.java | 11 +++-- .../java/sootup/jimple/parser/JimpleView.java | 14 ++++--- 4 files changed, 17 insertions(+), 50 deletions(-) delete mode 100644 sootup.core/src/main/java/sootup/core/SourceTypeSpecifier.java diff --git a/sootup.core/src/main/java/sootup/core/SourceTypeSpecifier.java b/sootup.core/src/main/java/sootup/core/SourceTypeSpecifier.java deleted file mode 100644 index 5887de096b9..00000000000 --- a/sootup.core/src/main/java/sootup/core/SourceTypeSpecifier.java +++ /dev/null @@ -1,41 +0,0 @@ -package sootup.core; -/*- - * #%L - * Soot - * %% - * Copyright (C) 2019-2020 Linghui Luo, Markus Schmidt - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 2.1 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * . - * #L% - */ -import javax.annotation.Nonnull; -import sootup.core.frontend.AbstractClassSource; -import sootup.core.model.SourceType; - -/** - * @author Christian Brüggemann - * @author Markus Schmidt - */ -public interface SourceTypeSpecifier { - - /** - * Specifies which {@link SourceType} a specific ClassType maps to. - * - * @param clsSource the type - * @return the source type - */ - @Nonnull - SourceType sourceTypeFor(AbstractClassSource clsSource); -} diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/AggregatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/AggregatorTest.java index a67b7f0df15..cb55b547569 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/AggregatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/AggregatorTest.java @@ -183,6 +183,7 @@ public void testIssue739() { AnalysisInputLocation inputLocation = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( Paths.get("../shared-test-resources/bugfixes/Issue739_Aggregator.class"), + "", SourceType.Application, BytecodeClassLoadingOptions.Default.getBodyInterceptors()); diff --git a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java index cbb1cfc49a4..f9824e2ee45 100644 --- a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java +++ b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java @@ -43,7 +43,6 @@ import java.util.jar.JarFile; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import sootup.core.SourceTypeSpecifier; import sootup.core.frontend.ClassProvider; import sootup.core.frontend.ResolveException; import sootup.core.inputlocation.AnalysisInputLocation; @@ -62,6 +61,7 @@ */ public class WalaJavaClassProvider implements ClassProvider { + private final SourceType sourceType; private Set sourcePath; private IClassHierarchy classHierarchy; private List sootClasses; @@ -86,6 +86,7 @@ public WalaJavaClassProvider( @Nonnull Set sourcePath, @Nullable String exclusionFilePath) { addScopesForJava(); this.sourcePath = sourcePath; + this.sourceType = SourceType.Application; // add the source directory to scope for (String path : sourcePath) { scope.addToScope( @@ -100,6 +101,7 @@ public WalaJavaClassProvider( @Nonnull Set libPath, @Nonnull String exclusionFilePath) { addScopesForJava(); + this.sourceType = SourceType.Application; this.sourcePath = sourcePath; // add the source directory to scope for (String path : sourcePath) { @@ -125,6 +127,7 @@ public WalaJavaClassProvider( @Nullable String exclusionFilePath) { addScopesForJava(); this.sourcePath = sourcePath; + this.sourceType = SourceType.Application; try { // add the source directory to scope for (String path : sourcePath) { @@ -152,7 +155,8 @@ public WalaJavaClassProvider( public WalaJavaClassProvider( @Nonnull String sourceDirPath, @Nullable String exclusionFilePath, - @Nonnull SourceTypeSpecifier sourceTypeSpecifier) { + @Nonnull SourceType sourceType) { + this.sourceType = sourceType; addScopesForJava(); this.sourcePath = Collections.singleton(sourceDirPath); // add the source directory to scope @@ -169,7 +173,8 @@ public WalaJavaClassProvider( */ public WalaJavaClassProvider( @Nonnull Collection moduleFiles, - @Nonnull SourceTypeSpecifier sourceTypeSpecifier) { + @Nonnull SourceType sourceType) { + this.sourceType = sourceType; addScopesForJava(); for (Module m : moduleFiles) { scope.addToScope(JavaSourceAnalysisScope.SOURCE, m); diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java index d7e36ccde0e..bcf1d66a798 100644 --- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java +++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java @@ -7,7 +7,6 @@ import java.util.stream.Collectors; import javax.annotation.Nonnull; import sootup.core.IdentifierFactory; -import sootup.core.SourceTypeSpecifier; import sootup.core.cache.ClassCache; import sootup.core.cache.provider.ClassCacheProvider; import sootup.core.cache.provider.FullCacheProvider; @@ -16,6 +15,7 @@ import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.model.SootClass; +import sootup.core.model.SourceType; import sootup.core.types.ClassType; import sootup.core.views.AbstractView; @@ -32,23 +32,25 @@ public class JimpleView extends AbstractView { @Nonnull protected final List inputLocations; @Nonnull private final ClassCache cache; - @Nonnull protected final SourceTypeSpecifier sourceTypeSpecifier; + @Nonnull protected final SourceType sourceType; private volatile boolean isFullyResolved = false; public JimpleView(@Nonnull AnalysisInputLocation inputLocation) { - this(Collections.singletonList(inputLocation), new FullCacheProvider()); + this(Collections.singletonList(inputLocation)); } public JimpleView(@Nonnull List inputLocations) { - this(inputLocations, new FullCacheProvider()); + this(inputLocations, new FullCacheProvider(), SourceType.Application); } public JimpleView( @Nonnull List inputLocations, - @Nonnull ClassCacheProvider cacheProvider) { + @Nonnull ClassCacheProvider cacheProvider, + SourceType sourceType) { this.inputLocations = inputLocations; this.cache = cacheProvider.createCache(); + this.sourceType = sourceType; } @Override @@ -112,7 +114,7 @@ private synchronized Optional buildClassFrom(AbstractClassSource clas ClassType classType = classSource.getClassType(); SootClass theClass; if (!cache.hasClass(classType)) { - theClass = classSource.buildClass(sourceTypeSpecifier.sourceTypeFor(classSource)); + theClass = classSource.buildClass(sourceType); cache.putClass(classType, theClass); } else { theClass = cache.getClass(classType); From e53e2f517b88e3a5aa6344989e53513383d5c15e Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 16 Jan 2024 12:27:20 +0100 Subject: [PATCH 21/57] style --- .../ModuleMultiReleaseJarAnalysisInputLocation.java | 5 +++-- .../MultiReleaseJarAnalysisInputLocation.java | 8 +++++++- .../java/sourcecode/frontend/WalaJavaClassProvider.java | 3 +-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java index 0b3e05f86dd..b70b64d4b0b 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java @@ -34,8 +34,9 @@ protected ModuleInfoAnalysisInputLocation createAnalysisInputLocation(@Nonnull P @Override public Collection getModulesClassSources( @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { - // FIXME: implement - return null; + // TODO: check if we need to combine modules as well or if only versioned .class files are + return ((ModuleInfoAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) + .getModulesClassSources(moduleSignature, view); } @Nonnull diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index c0c672c9b3f..c7f365aba42 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -81,7 +81,11 @@ public MultiReleaseJarAnalysisInputLocation( availableVersions = new ArrayList<>(); try (Stream list = Files.list(versionedRoot)) { - list.map(dir -> dir.getFileName().toString().replace("/", "")) + list.map( + dir -> { + String versionDirName = dir.getFileName().toString(); + return versionDirName.substring(0, versionDirName.length() - 1); + }) .map(Integer::new) .sorted() .forEach(availableVersions::add); @@ -92,6 +96,7 @@ public MultiReleaseJarAnalysisInputLocation( for (int i = availableVersions.size() - 1; i >= 0; i--) { Integer version = availableVersions.get(i); if (version > language.getVersion()) { + // TODO: use binSearch to find desired versions more efficiently? continue; } final Path versionRoot = @@ -102,6 +107,7 @@ public MultiReleaseJarAnalysisInputLocation( } protected AnalysisInputLocation createAnalysisInputLocation(Path archiveRoot) { + // FIXME: make the inputlocation ignore /META_INF/* return PathBasedAnalysisInputLocation.create(archiveRoot, sourceType); } diff --git a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java index f9824e2ee45..4b6c30f8657 100644 --- a/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java +++ b/sootup.java.sourcecode/src/main/java/sootup/java/sourcecode/frontend/WalaJavaClassProvider.java @@ -172,8 +172,7 @@ public WalaJavaClassProvider( * @param moduleFiles */ public WalaJavaClassProvider( - @Nonnull Collection moduleFiles, - @Nonnull SourceType sourceType) { + @Nonnull Collection moduleFiles, @Nonnull SourceType sourceType) { this.sourceType = sourceType; addScopesForJava(); for (Module m : moduleFiles) { From 3d85900b0a44f8ca85e146b63e92c946405c273b Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 16 Jan 2024 12:44:24 +0100 Subject: [PATCH 22/57] add ignorePaths; improve error message --- .../frontend/AsmJavaClassProvider.java | 4 +- .../ArchiveBasedAnalysisInputLocation.java | 10 +++- .../MultiReleaseJarAnalysisInputLocation.java | 4 +- .../PathBasedAnalysisInputLocation.java | 51 ++++++++++++++++--- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java index df1af52ab3c..f95e5c1c0ac 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java @@ -69,9 +69,7 @@ public Optional createClassSource( "ASM could not resolve class source of " + classType + " in " - + sourcePath - + " causing " - + exception.getMessage()); + + sourcePath, exception); return Optional.empty(); } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ArchiveBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ArchiveBasedAnalysisInputLocation.java index 27d590ff466..09107109066 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ArchiveBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ArchiveBasedAnalysisInputLocation.java @@ -78,7 +78,15 @@ public ArchiveBasedAnalysisInputLocation( @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull List bodyInterceptors) { - super(path, srcType, bodyInterceptors); + this(path, srcType, bodyInterceptors, Collections.emptyList()); + } + + public ArchiveBasedAnalysisInputLocation( + Path path, + SourceType srcType, + List bodyInterceptors, + Collection ignoredPaths) { + super(path, srcType, bodyInterceptors, ignoredPaths); } @Override diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index c7f365aba42..cf8c28114aa 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -27,6 +27,7 @@ import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.jar.Attributes; @@ -107,8 +108,7 @@ public MultiReleaseJarAnalysisInputLocation( } protected AnalysisInputLocation createAnalysisInputLocation(Path archiveRoot) { - // FIXME: make the inputlocation ignore /META_INF/* - return PathBasedAnalysisInputLocation.create(archiveRoot, sourceType); + return PathBasedAnalysisInputLocation.create(archiveRoot, sourceType, bodyInterceptors, Collections.singletonList(Paths.get("/META_INF"))); } @Override diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index df1a23817fd..863001ec0ac 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -66,6 +66,7 @@ public abstract class PathBasedAnalysisInputLocation implements AnalysisInputLoc protected final SourceType sourceType; protected final List bodyInterceptors; protected Path path; + protected Collection ignoredPaths = new ArrayList<>(); protected PathBasedAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { this(path, srcType, Collections.emptyList()); @@ -75,7 +76,16 @@ protected PathBasedAnalysisInputLocation( @Nonnull Path path, @Nullable SourceType srcType, @Nonnull List bodyInterceptors) { + this(path, srcType, bodyInterceptors, Collections.emptyList()); + } + + protected PathBasedAnalysisInputLocation( + @Nonnull Path path, + @Nullable SourceType srcType, + @Nonnull List bodyInterceptors, + @Nonnull Collection ignoredPaths) { this.path = path; + this.ignoredPaths = ignoredPaths; this.sourceType = srcType; this.bodyInterceptors = bodyInterceptors; @@ -99,7 +109,7 @@ public List getBodyInterceptors() { @Nonnull public static PathBasedAnalysisInputLocation create( @Nonnull Path path, @Nonnull SourceType sourceType) { - return PathBasedAnalysisInputLocation.create(path, sourceType, Collections.emptyList()); + return create(path, sourceType, Collections.emptyList()); } @Nonnull @@ -107,14 +117,23 @@ public static PathBasedAnalysisInputLocation create( @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull List bodyInterceptors) { + return create(path, srcType, bodyInterceptors, Collections.emptyList()); + } + + @Nonnull + public static PathBasedAnalysisInputLocation create( + @Nonnull Path path, + @Nonnull SourceType srcType, + @Nonnull List bodyInterceptors, + @Nonnull Collection ignoredPaths) { if (Files.isDirectory(path)) { - return new DirectoryBasedAnalysisInputLocation(path, srcType, bodyInterceptors); + return new DirectoryBasedAnalysisInputLocation(path, srcType, bodyInterceptors, ignoredPaths); } else if (PathUtils.isArchive(path)) { if (PathUtils.hasExtension(path, FileType.JAR)) { - return new ArchiveBasedAnalysisInputLocation(path, srcType, bodyInterceptors); + return new ArchiveBasedAnalysisInputLocation(path, srcType, bodyInterceptors, ignoredPaths); } else if (PathUtils.hasExtension(path, FileType.WAR)) { try { - return new WarArchiveAnalysisInputLocation(path, srcType, bodyInterceptors); + return new WarArchiveAnalysisInputLocation(path, srcType, bodyInterceptors, ignoredPaths); } catch (IOException e) { throw new RuntimeException(e); } @@ -137,6 +156,7 @@ Collection walkDirectory( try (final Stream walk = Files.walk(dirPath)) { return walk.filter( filePath -> + ignoredPaths.stream().noneMatch(filePath::startsWith) && PathUtils.hasExtension(filePath, handledFileType) && !filePath.toString().endsWith(moduleInfoFilename)) .flatMap( @@ -263,7 +283,15 @@ private DirectoryBasedAnalysisInputLocation( @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull List bodyInterceptors) { - super(path, srcType, bodyInterceptors); + this(path, srcType, bodyInterceptors, Collections.emptyList()); + } + + public DirectoryBasedAnalysisInputLocation( + @Nonnull Path path, + @Nonnull SourceType srcType, + @Nonnull List bodyInterceptors, + @Nonnull Collection ignoredPaths) { + super(path, srcType, bodyInterceptors, ignoredPaths); } @Override @@ -288,18 +316,20 @@ private static final class WarArchiveAnalysisInputLocation private WarArchiveAnalysisInputLocation(@Nonnull Path warPath, @Nonnull SourceType srcType) throws IOException { - this(warPath, srcType, Collections.emptyList()); + this(warPath, srcType, Collections.emptyList(), Collections.emptyList()); } private WarArchiveAnalysisInputLocation( @Nonnull Path warPath, @Nonnull SourceType srcType, - @Nonnull List bodyInterceptors) + @Nonnull List bodyInterceptors, + @Nonnull Collection ignoredPaths) throws IOException { super( Files.createTempDirectory("sootUp-war-" + warPath.hashCode()).toAbsolutePath(), srcType, - bodyInterceptors); + bodyInterceptors, + ignoredPaths); extractWarFile(warPath, path); @@ -327,6 +357,11 @@ private WarArchiveAnalysisInputLocation( } } + public WarArchiveAnalysisInputLocation( + Path path, SourceType srcType, List bodyInterceptors) throws IOException { + this(path, srcType, bodyInterceptors, Collections.emptyList()); + } + @Override @Nonnull public Collection getClassSources(@Nonnull View view) { From e829c827cd3be97f88fe001f7796bccda82e0805 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Wed, 17 Jan 2024 10:39:05 +0100 Subject: [PATCH 23/57] style --- .../sootup/java/bytecode/frontend/AsmJavaClassProvider.java | 5 +---- .../inputlocation/MultiReleaseJarAnalysisInputLocation.java | 6 +++++- .../inputlocation/PathBasedAnalysisInputLocation.java | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java index f95e5c1c0ac..6fa1bfcc0d6 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java @@ -66,10 +66,7 @@ public Optional createClassSource( } } catch (IOException | IllegalArgumentException exception) { logger.warn( - "ASM could not resolve class source of " - + classType - + " in " - + sourcePath, exception); + "ASM could not resolve class source of " + classType + " in " + sourcePath, exception); return Optional.empty(); } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index cf8c28114aa..806dbe31d8e 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -108,7 +108,11 @@ public MultiReleaseJarAnalysisInputLocation( } protected AnalysisInputLocation createAnalysisInputLocation(Path archiveRoot) { - return PathBasedAnalysisInputLocation.create(archiveRoot, sourceType, bodyInterceptors, Collections.singletonList(Paths.get("/META_INF"))); + return PathBasedAnalysisInputLocation.create( + archiveRoot, + sourceType, + bodyInterceptors, + Collections.singletonList(Paths.get("/META_INF"))); } @Override diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index 863001ec0ac..fcb3bc8c9b8 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -156,8 +156,8 @@ Collection walkDirectory( try (final Stream walk = Files.walk(dirPath)) { return walk.filter( filePath -> - ignoredPaths.stream().noneMatch(filePath::startsWith) && - PathUtils.hasExtension(filePath, handledFileType) + ignoredPaths.stream().noneMatch(filePath::startsWith) + && PathUtils.hasExtension(filePath, handledFileType) && !filePath.toString().endsWith(moduleInfoFilename)) .flatMap( p -> { From 4a3f33550350390c4c3ce7409e4d048f19c31498 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Wed, 17 Jan 2024 18:08:15 +0100 Subject: [PATCH 24/57] add test execution --- .../JavaModulePathAnalysisInputLocation.java | 9 ++-- .../bytecode/inputlocation/ModuleFinder.java | 8 ++-- ...eMultiReleaseJarAnalysisInputLocation.java | 2 +- .../MultiReleaseJarAnalysisInputLocation.java | 4 ++ .../bytecode/frontend/JavaModuleViewTest.java | 42 ++++++++++--------- ...vaModulePathAnalysisInputLocationTest.java | 15 ++++--- .../inputlocation/ModuleFinderTest.java | 17 ++++---- 7 files changed, 57 insertions(+), 40 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java index c711e462815..4bbc266f17a 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java @@ -23,6 +23,7 @@ import com.google.common.base.Preconditions; import java.nio.file.FileSystem; import java.nio.file.FileSystems; +import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -62,17 +63,17 @@ public class JavaModulePathAnalysisInputLocation implements ModuleInfoAnalysisIn * @param modulePath The class path to search in The {@link ClassProvider} for generating {@link * SootClassSource}es for the files found on the class path */ - public JavaModulePathAnalysisInputLocation(@Nonnull String modulePath) { + public JavaModulePathAnalysisInputLocation(@Nonnull Path modulePath) { this(modulePath, SourceType.Application); } public JavaModulePathAnalysisInputLocation( - @Nonnull String modulePath, @Nonnull SourceType sourcetype) { + @Nonnull Path modulePath, @Nonnull SourceType sourcetype) { this(modulePath, FileSystems.getDefault(), sourcetype); } public JavaModulePathAnalysisInputLocation( - @Nonnull String modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourcetype) { + @Nonnull Path modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourcetype) { this(modulePath, fileSystem, sourcetype, new ArrayList<>()); } @@ -85,7 +86,7 @@ public JavaModulePathAnalysisInputLocation( * @param fileSystem filesystem for the path */ public JavaModulePathAnalysisInputLocation( - @Nonnull String modulePath, + @Nonnull Path modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourcetype, @Nonnull List bodyInterceptors) { diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java index d9e66fa4179..9e897dbd272 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java @@ -76,10 +76,10 @@ public boolean hasMoreToResolve() { * @param sourceType */ public ModuleFinder( - @Nonnull String modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourceType) { + @Nonnull Path modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourceType) { this.sourceType = sourceType; this.modulePathEntries = - JavaClassPathAnalysisInputLocation.explode(modulePath, fileSystem) + JavaClassPathAnalysisInputLocation.explode(modulePath.toString(), fileSystem) .collect(Collectors.toList()); for (Path modulePathEntry : modulePathEntries) { if (!Files.exists(modulePathEntry)) { @@ -93,11 +93,11 @@ public ModuleFinder( } } - public ModuleFinder(@Nonnull String modulePath, @Nonnull SourceType sourceType) { + public ModuleFinder(@Nonnull Path modulePath, @Nonnull SourceType sourceType) { this(modulePath, FileSystems.getDefault(), sourceType); } - public ModuleFinder(@Nonnull String modulePath) { + public ModuleFinder(@Nonnull Path modulePath) { this(modulePath, FileSystems.getDefault(), SourceType.Application); } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java index b70b64d4b0b..3522c1a20a5 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java @@ -25,7 +25,7 @@ public ModuleMultiReleaseJarAnalysisInputLocation( protected ModuleInfoAnalysisInputLocation createAnalysisInputLocation(@Nonnull Path path) { try { return new JavaModulePathAnalysisInputLocation( - path.toString(), fileSystemCache.get(this.path), sourceType); + path, fileSystemCache.get(this.path), sourceType); } catch (ExecutionException e) { throw new IllegalArgumentException("Could not open filesystemcache.", e); } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index 806dbe31d8e..a222fea993c 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -161,6 +161,10 @@ public Language getLanguage() { return language; } + /** + * lists all versions from the version directories inside the META_INF/ directory - excluding the + * default implemention version + */ @Nonnull public List getAvailableVersions() { return availableVersions; diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/JavaModuleViewTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/JavaModuleViewTest.java index f8f9dd3b318..90d6b5585f2 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/JavaModuleViewTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/JavaModuleViewTest.java @@ -3,6 +3,7 @@ import static org.junit.Assert.*; import categories.Java9Test; +import java.nio.file.Paths; import java.util.*; import org.junit.Ignore; import org.junit.Test; @@ -104,7 +105,7 @@ public void testAnnotation() { List moduleInfoAnalysisInputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "annotations/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "annotations/jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); ModulePackageName modMain = @@ -145,7 +146,7 @@ public void testRequiresStatic() { List inputLocations = Collections.emptyList(); List moduleInfoAnalysisInputLocations = new ArrayList<>(); moduleInfoAnalysisInputLocations.add( - new JavaModulePathAnalysisInputLocation(testPath + "requires-static/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "requires-static/jar"))); moduleInfoAnalysisInputLocations.add(new JrtFileSystemAnalysisInputLocation()); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -186,7 +187,7 @@ public void testRequiresExport() { List inputLocations = Collections.emptyList(); List moduleInfoAnalysisInputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "requires_exports/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "requires_exports/jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); ModulePackageName modMain = @@ -236,7 +237,7 @@ public void testRequiresTransitiveExport() { List moduleInfoAnalysisInputLocations = new ArrayList<>(); moduleInfoAnalysisInputLocations.add( new JavaModulePathAnalysisInputLocation( - testPath + "requires_exports_requires-transitive_exports-to/jar")); + Paths.get(testPath + "requires_exports_requires-transitive_exports-to/jar"))); moduleInfoAnalysisInputLocations.add(new JrtFileSystemAnalysisInputLocation()); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -285,7 +286,7 @@ public void testReflection() { List inputLocations = Collections.emptyList(); List moduleInfoAnalysisInputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "reflection/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "reflection/jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); ModuleJavaClassType mainClass = @@ -338,7 +339,7 @@ public void testUsesProvide() { List inputLocations = Collections.emptyList(); List moduleInfoAnalysisInputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "uses-provides/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "uses-provides/jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); ModuleJavaClassType mainModmainSig = @@ -385,7 +386,8 @@ public void testUsesProvideInClient() { List inputLocations = Collections.emptyList(); List moduleInfoAnalysisInputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "uses-provides_uses-in-client/jar")); + new JavaModulePathAnalysisInputLocation( + Paths.get(testPath + "uses-provides_uses-in-client/jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); ModuleJavaClassType mainModmainSig = @@ -435,7 +437,7 @@ public void testDerivedPrivatePackageProtected() { List moduleInfoAnalysisInputLocations = Collections.singletonList( new JavaModulePathAnalysisInputLocation( - testPath + "derived_private-package-protected/jar")); + Paths.get(testPath + "derived_private-package-protected/jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); ModuleJavaClassType mainClass = @@ -482,7 +484,7 @@ public void testExceptions() { List moduleInfoAnalysisInputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "exceptions/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "exceptions/jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); ModuleJavaClassType mainClass = @@ -519,7 +521,8 @@ public void testInterfaceCallback() { List inputLocations = Collections.emptyList(); List moduleInfoAnalysisInputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "interface-callback/jar")); + new JavaModulePathAnalysisInputLocation( + Paths.get(testPath + "interface-callback/jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); ModuleJavaClassType mainClass = @@ -555,7 +558,7 @@ public void testSplitpackageAutomaticModules() { List inputLocations = Collections.singletonList( new JavaModulePathAnalysisInputLocation( - testPath + "splitpackage_automatic-modules/jar")); + Paths.get(testPath + "splitpackage_automatic-modules/jar"))); List moduleInfoAnalysisInputLocations = Collections.emptyList(); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -591,7 +594,7 @@ public void testSplitpackage() { // TODO: adapt List inputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "splitpackage")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "splitpackage"))); List moduleInfoAnalysisInputLocations = Collections.emptyList(); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -608,7 +611,7 @@ public void testHiddenMain() { // i.e. main is in non exported package List inputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "hiddenmain/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "hiddenmain/jar"))); List moduleInfoAnalysisInputLocations = Collections.emptyList(); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -633,7 +636,8 @@ public void testAccessUnnamedModuleFromAutomaticModule() { List moduleInfoAnalysisInputLocations = new ArrayList<>(); moduleInfoAnalysisInputLocations.add( new JavaModulePathAnalysisInputLocation( - testPath + "unnamed-module_access-from-automatic-module/jar/modmain.auto.jar")); + Paths.get( + testPath + "unnamed-module_access-from-automatic-module/jar/modmain.auto.jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -662,10 +666,10 @@ public void testAccessUnnamedModuleFromModule() { List moduleInfoAnalysisInputLocations = new ArrayList<>(); moduleInfoAnalysisInputLocations.add( new JavaModulePathAnalysisInputLocation( - testPath + "unnamed-module_access-from-explicit-module/jar/modb.jar")); + Paths.get(testPath + "unnamed-module_access-from-explicit-module/jar/modb.jar"))); moduleInfoAnalysisInputLocations.add( new JavaModulePathAnalysisInputLocation( - testPath + "unnamed-module_access-from-explicit-module/jar/modmain.jar")); + Paths.get(testPath + "unnamed-module_access-from-explicit-module/jar/modmain.jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); ModulePackageName cpb = JavaModuleIdentifierFactory.getInstance().getPackageName("pkgb", ""); @@ -712,7 +716,7 @@ public void testAccessModuleFromUnnamedModule() { List moduleInfoAnalysisInputLocations = new ArrayList<>(); moduleInfoAnalysisInputLocations.add( new JavaModulePathAnalysisInputLocation( - testPath + "unnamed-module_accessing-module-path/jar/modb.jar")); + Paths.get(testPath + "unnamed-module_accessing-module-path/jar/modb.jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -800,9 +804,9 @@ public void testEqualModulePath() { List inputLocations = Collections.emptyList(); List moduleInfoAnalysisInputLocations = new ArrayList<>(); moduleInfoAnalysisInputLocations.add( - new JavaModulePathAnalysisInputLocation(testPath + "requires_exports/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "requires_exports/jar"))); moduleInfoAnalysisInputLocations.add( - new JavaModulePathAnalysisInputLocation(testPath + "requires_exports/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "requires_exports/jar"))); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java index 243246dce26..5e6e9608e0d 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java @@ -2,11 +2,15 @@ import static org.junit.Assert.*; +import java.nio.file.Paths; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Optional; + +import categories.Java9Test; import org.junit.Test; +import org.junit.experimental.categories.Category; import sootup.core.frontend.AbstractClassSource; import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; @@ -18,6 +22,7 @@ import sootup.java.core.types.JavaClassType; import sootup.java.core.views.JavaModuleView; +@Category(Java9Test.class) public class JavaModulePathAnalysisInputLocationTest { private final String testPath = "../shared-test-resources/jigsaw-examples/"; @@ -26,7 +31,7 @@ public class JavaModulePathAnalysisInputLocationTest { public void testJarModule() { List inputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "uses-provides/jar/")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "uses-provides/jar/"))); List moduleInfoAnalysisInputLocations = Collections.emptyList(); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -45,7 +50,7 @@ public void testJarModule() { public void testExplodedModule() { List inputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "uses-provides/exploded_module/")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "uses-provides/exploded_module/"))); List moduleInfoAnalysisInputLocations = Collections.emptyList(); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -64,7 +69,7 @@ public void testExplodedModule() { public void testGetModuleInfo() { List inputLocations = Collections.singletonList( - new JavaModulePathAnalysisInputLocation(testPath + "requires_exports/jar")); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "requires_exports/jar"))); List moduleInfoAnalysisInputLocations = Collections.emptyList(); JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations); @@ -110,7 +115,7 @@ public void testGetClassSource() { @Test public void testGetClassSources() { JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation(testPath + "requires_exports/jar"); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "requires_exports/jar")); List inputLocations = Collections.emptyList(); List moduleInfoAnalysisInputLocations = Collections.singletonList(inputLocation); @@ -123,7 +128,7 @@ public void testGetClassSources() { @Test public void testGetModules() { JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation(testPath + "requires_exports/jar"); + new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "requires_exports/jar")); List inputLocations = Collections.emptyList(); List moduleInfoAnalysisInputLocations = Collections.singletonList(inputLocation); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleFinderTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleFinderTest.java index 1f2600be4e0..42fe2e25fec 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleFinderTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleFinderTest.java @@ -17,7 +17,7 @@ public class ModuleFinderTest extends AnalysisInputLocationTest { @Test public void discoverJarModuleByName() { - ModuleFinder moduleFinder = new ModuleFinder(jar.toString()); + ModuleFinder moduleFinder = new ModuleFinder(jar); AnalysisInputLocation inputLocation = moduleFinder.getModule(JavaModuleIdentifierFactory.getModuleSignature("MiniApp")); assertTrue(inputLocation instanceof PathBasedAnalysisInputLocation); @@ -25,14 +25,14 @@ public void discoverJarModuleByName() { @Test public void discoverJarModuleInAllModules() { - ModuleFinder moduleFinder = new ModuleFinder(jar.toString()); + ModuleFinder moduleFinder = new ModuleFinder(jar); Collection modules = moduleFinder.getAllModules(); assertTrue(modules.contains(JavaModuleIdentifierFactory.getModuleSignature("MiniApp"))); } @Test public void discoverWarModuleByName() { - ModuleFinder moduleFinder = new ModuleFinder(war.toString()); + ModuleFinder moduleFinder = new ModuleFinder(war); AnalysisInputLocation inputLocation = moduleFinder.getModule(JavaModuleIdentifierFactory.getModuleSignature("dummyWarApp")); assertTrue(inputLocation instanceof PathBasedAnalysisInputLocation); @@ -40,7 +40,7 @@ public void discoverWarModuleByName() { @Test public void discoverWarModuleInAllModules() { - ModuleFinder moduleFinder = new ModuleFinder(war.toString()); + ModuleFinder moduleFinder = new ModuleFinder(war); Collection modules = moduleFinder.getAllModules(); assertTrue(modules.contains(JavaModuleIdentifierFactory.getModuleSignature("dummyWarApp"))); } @@ -48,7 +48,8 @@ public void discoverWarModuleInAllModules() { @Test public void testModuleJar() { ModuleFinder moduleFinder = - new ModuleFinder("../shared-test-resources/java9-target/de/upb/soot/namespaces/modules/"); + new ModuleFinder( + Paths.get("../shared-test-resources/java9-target/de/upb/soot/namespaces/modules/")); Collection discoveredModules = moduleFinder.getAllModules(); assertTrue( discoveredModules.contains(JavaModuleIdentifierFactory.getModuleSignature("de.upb.mod"))); @@ -57,7 +58,8 @@ public void testModuleJar() { @Test public void testModuleExploded() { ModuleFinder moduleFinder = - new ModuleFinder("../shared-test-resources/java9-target/de/upb/soot/namespaces/modules/"); + new ModuleFinder( + Paths.get("../shared-test-resources/java9-target/de/upb/soot/namespaces/modules/")); Collection discoveredModules = moduleFinder.getAllModules(); assertTrue( discoveredModules.contains(JavaModuleIdentifierFactory.getModuleSignature("fancyMod"))); @@ -77,7 +79,8 @@ public void testAutomaticModuleNamingViaManifest() { ModuleFinder moduleFinder = new ModuleFinder( - "../shared-test-resources/java9-target/de/upb/soot/namespaces/modules/automaticModuleWithManifest"); + Paths.get( + "../shared-test-resources/java9-target/de/upb/soot/namespaces/modules/automaticModuleWithManifest")); assertNotNull( moduleFinder.getModule( From 4ddd7107476186730a009663457e9e5c4501ba92 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Wed, 17 Jan 2024 18:17:39 +0100 Subject: [PATCH 25/57] fix check for java modules --- .../sootup/java/bytecode/frontend/AsmJavaClassProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java index 6fa1bfcc0d6..fc192014faa 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java @@ -56,7 +56,7 @@ public Optional createClassSource( try { final String actualClassSignature = AsmUtil.initAsmClassSource(sourcePath, classNode); - if (!actualClassSignature.replace('/', '.').equals(classType.toString())) { + if (!actualClassSignature.replace('/', '.').equals(classType.getFullyQualifiedName().toString())) { throw new IllegalArgumentException( "The given Classtype '" + classType From 02298d84c41242828efa5ea60583f6178fbadc0b Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Wed, 17 Jan 2024 18:22:47 +0100 Subject: [PATCH 26/57] postpone fixing more tests into a future PR --- .../ModuleMultiReleaseJarAnalysisInputLocation.java | 2 ++ .../inputlocation/JavaModulePathAnalysisInputLocationTest.java | 2 ++ .../ModuleMultiReleaseJarAnalysisInputLocationTest.java | 2 ++ 3 files changed, 6 insertions(+) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java index 3522c1a20a5..a64151e80e3 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java @@ -19,6 +19,8 @@ public class ModuleMultiReleaseJarAnalysisInputLocation extends MultiReleaseJarA public ModuleMultiReleaseJarAnalysisInputLocation( @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { super(path, srcType, language); + + throw new UnsupportedOperationException("not fully implemented, yet!"); } @Override diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java index 5e6e9608e0d..be22d72def3 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java @@ -9,6 +9,7 @@ import java.util.Optional; import categories.Java9Test; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import sootup.core.frontend.AbstractClassSource; @@ -66,6 +67,7 @@ public void testExplodedModule() { } @Test + @Ignore("// FIXME does not find moduleInfo's ") public void testGetModuleInfo() { List inputLocations = Collections.singletonList( diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java index bd0e1c0be02..553b9983b4f 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java @@ -8,6 +8,7 @@ import java.nio.file.Paths; import java.util.Collections; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import sootup.core.model.SourceType; @@ -25,6 +26,7 @@ public class ModuleMultiReleaseJarAnalysisInputLocationTest extends AnalysisInpu final Path mmrj = Paths.get("../shared-test-resources/multi-release-jar-modular/mrjar.jar"); @Test + @Ignore("// FIXME") public void modularMultiReleaseJar() { assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mmrj)); From 218f005f8a14d611990f86c864214eba032c6a95 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Thu, 18 Jan 2024 09:44:53 +0100 Subject: [PATCH 27/57] this lamb is silent now. --- .../frontend/AsmJavaClassProvider.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java index fc192014faa..092f36fd269 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java @@ -54,22 +54,22 @@ public Optional createClassSource( AnalysisInputLocation analysisInputLocation, Path sourcePath, ClassType classType) { SootClassNode classNode = new SootClassNode(analysisInputLocation); + final String actualClassSignature; try { - final String actualClassSignature = AsmUtil.initAsmClassSource(sourcePath, classNode); - if (!actualClassSignature.replace('/', '.').equals(classType.getFullyQualifiedName().toString())) { - throw new IllegalArgumentException( - "The given Classtype '" - + classType - + "' did not match the found ClassType in the compilation unit '" - + actualClassSignature - + "'. Possibly the AnalysisInputLocation points to a subfolder already including the PackageName directory while the ClassType you wanted to retrieve is missing a PackageName."); - } - } catch (IOException | IllegalArgumentException exception) { - logger.warn( - "ASM could not resolve class source of " + classType + " in " + sourcePath, exception); + actualClassSignature = AsmUtil.initAsmClassSource(sourcePath, classNode); + } catch (IOException exception) { return Optional.empty(); } + if (!actualClassSignature.replace('/', '.').equals(classType.getFullyQualifiedName().toString())) { + throw new IllegalStateException( + "The given Classtype '" + + classType + + "' did not match the found ClassType in the compilation unit '" + + actualClassSignature + + "'. Possibly the AnalysisInputLocation points to a subfolder already including the PackageName directory while the ClassType you wanted to retrieve is missing a PackageName."); + } + JavaClassType klassType = (JavaClassType) classType; if (klassType instanceof ModuleJavaClassType From db0b17190c89b279ccdd83987c0c709fb9b40207 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Thu, 18 Jan 2024 09:55:33 +0100 Subject: [PATCH 28/57] update multimodulereleasejar according to its sources; de-win the creation description --- .../multi-release-jar-modular/createJar.sh | 18 ++++++++++++++++++ .../multi-release-jar-modular/mrjar.jar | Bin 3275 -> 3505 bytes .../multi-release-jar-modular/readme.md | 10 ---------- 3 files changed, 18 insertions(+), 10 deletions(-) create mode 100755 shared-test-resources/multi-release-jar-modular/createJar.sh delete mode 100644 shared-test-resources/multi-release-jar-modular/readme.md diff --git a/shared-test-resources/multi-release-jar-modular/createJar.sh b/shared-test-resources/multi-release-jar-modular/createJar.sh new file mode 100755 index 00000000000..a006c783cdc --- /dev/null +++ b/shared-test-resources/multi-release-jar-modular/createJar.sh @@ -0,0 +1,18 @@ +# /bin/bash + +# To build the jar: + +javac --release 8 -d classes src/main/java/de/upb/swt/multirelease/*java +javac --release 9 -d classes-9 src/main/java9/de/upb/swt/multirelease/*java src/main/java9/module-info.java +javac --release 10 -d classes-10 src/main/java10/de/upb/swt/multirelease/*java src/main/java10/module-info.java + +jar --create --file mrjar.jar --main-class multirelease.Main -C classes . --release 9 -C classes-9 . --release 10 -C classes-10 . + + +# cleanup +rm -r ./classes ./classes-9 ./classes-10 + + +#More info: +#https://www.baeldung.com/java-multi-release-jar + diff --git a/shared-test-resources/multi-release-jar-modular/mrjar.jar b/shared-test-resources/multi-release-jar-modular/mrjar.jar index 794bff2680e4b37fa9fcc08e32991e711f2c0110..e98fb0cabd8cd3ce25de6ee832fb978e6a69b135 100644 GIT binary patch literal 3505 zcmWIWW@Zs#;Nak3NcA_0U_b(#3@i-3t|5-Po_=on|4uP5Ff#;rvvYt{FhP|C;M6Pv zQ~}rQ>*(j{<{BKL=j*0=awAu>fdIn=+X?kM0^35)v^Nwm$eZJH6 z?`3EHsOr9RUi9ZQW14;BX3oTgFRtxAc-p_N@u9#zsY6kgM=#EjwcM?{FsotnvO`Xt z0Vls_+&#JXzt{o~)$BEuU}x_3UcE9E=!ilf#_dd1WM`J878Pga=N0Q)>gVRCl;))B zX6B{k>m}zT78m>WIPx_)2(VO(II=h{cHgfsucoonTu3;6!=sEaagT_PXLj5CV31Eu znJ)3x`}`H3@2~$>FhwY~tI#2hX zyVrs2X)Xo^U>ZH+hnkpqfu7DS%_+$&O3g`4EKb$OohHQ5mHH-T=0Q?HZop1IW=}byTr`cSu z&Oi3~>)(%@4>*3C8J&Tlfq;1*)ZhKGk=cFyaA!pTPphz`SLvwxdh;MIaQE9YFs z)`JySCdyArTmFCj+(ln@T$jC(k#zLHs%F!_ja3tVcpW<=UZZu#TD5j%8js&9BY}@0 zZVNkkFWK_DS8*`www;oBJ;^(3x^=f()50s$7w+(CTG)~Q^TKi;J&)IC&;4CgDUqY^ z^@zPt(e%cpq;{!x*_=z8zMgD&S$cW5YhbsI@@)GG=4!R}#M$?pW}P|YG<(JV3y-I8 zU5QT!nI0Edwt4}PgnVctRmb=|!>fJ3L@9~3@t*C04K@cMY!*3wQ9W7Gm z(GpscnUh&k35%K2UWXk-Y%gz_spb~_`-AR{)(g7~q{W?%_CC;BA#k=XsNG1Ff2Lnc z-84Osm>-OFQ!0eJ_zT3opR;{_r}#l#&Az?N76<2bOX>9OYG=!7`{rZAWiNR1%KpCe zq9lno##1$m&n57>Pi$6`;k$mAYmfb>0z-2n)zG*LLG~*orv5gMN>ww7>MFT&MC#|% zGY408n_aWClH2vdu;l+m;}7jcUPeYTZ2LFy9K8HdQ$rc5|24m~Qyw z5MrKrYx%hq=6!Jo=e;<*!S(7o2X4M?`Fb;=H*ssBAyD zNIdtp)kOgq#rlj6pa2U|;_{mwG1`fUY;EzNLggJ?S}vRC zUs>pL(s`Ni!udzDtA*or6ci5{O8`33|6hl;jU8Nwc3wb1lAk%E}6G_&YZgj`d?h)R&_97JOAM*FLqZ zyU3|*)s(xyqK%y+UE|_jd4h2*iZ$qgRRQkER>Gx)$k^5=NxkFEn4MGN}3(^iin-7~RG9uPx0v>1-yw(B7M$OYRTjKaD~mVBY38w!WX8U}ty# z9^;&(s_syqdym!|5t z>ixA|oRs>E=WF+yIHN60Q%|i{k_5)~F+;^TQ7O;4t9vHhHPD8{_Kp5isW;r`zYE?c z6;Y|U>b1$+p!6%!?duc#za-vRkQKgwm3{X8OU(@1PB8<3e?4A_e^P*VW`&H{rD zEoq~M5pwMXYC0gm4|J`Fh6K8wkc(zeMTY?Wzz9RJA0=zx^9O2#eP_iMHkQDgjyoh2 z5zYXzG}*A5fZ{rIk0F;spn@I&GKevbXwQO5G6Z!zE4-4*=m}bszu$ literal 3275 zcmWIWW@Zs#;Nak3aH+iz#DD}i8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1g8t9~BMdU$Tp&Z`{8e)m)pjqV-#YW<)|_*}s*PFrs0tWD;M(m&tab=uh$;$eE| z*p2V(ua1AX+nxIG(2}0xlAjlB_@~?Cnf`vyZ$^-dwSqpcDFC{s5r}cSSQXjDWvNBQ znfZCe`j+~+`6;D2sk)hYY597|If=!^x&GdKO%6P@Uzs1VdzutJ7L^H`ci@O@XQ#Tv zQmGP##|?Rw)4BN{EbK8ja^g_lt$o+8U*C7HU%f%q=8%Hl;h2v~UVJNgl`420<~;Eg zN>l9qvq|{ZyiSYo$dc5fL7!P<580&bSNS{X%j_lcCp0!DO8&gxsaeIce3O9n=C%GW z@-P3{^}KY+j0DzaB2Cfa(mU->D`y|t!KT$cbyAeL1NZ$G2_38QlS7_a?qbu8*M0To zf%v+a>o;t?ctai(7Im}cXY2&}RE7}}7F-Mrz!=p>i+X0Dij-7+P+(zKzz$JRT9AZC z5jR3nad`98uftz`Ax?FomB60A=g z{>l9Q>@u$(EnLY;p}Rd@+TMk#FkcOx_@M6i5vAs4f}IMHl{3ivY>~{xstE- z;EasZ+#2btf3KdS^nJzUceht0-aOFN9BO;uS-_5uDG&VQr@THsZ_>mMEc3a(yLtMr zl5C!=@}@gO>+pdiR#Po_+jhw_^S1q}=RCJ_iJFo6!vF)3T}A@p8|?)yn#xx^Ir+nL z&$V51ud6oS<$nCaZ;mJLwvtV?y@$nKZDFbnN~q%ek~iV1!by*`?{Np@JQv=4aaQ%5 ziH=Fmg&tX;+yzWgpacU-3n)<>T9TQQSyBnjT>+=P4m*h0UfwcO%`H0mb@Y|i z3%d%;^jf;44~7OP&Z@n{m+B>_I#c7XPOQd`56piwKB|exKhSwMxBA@9=Li1&sHtWz z=!%s#m5?cA=bgdxHuHl(hlYpRBeglFCZ-vj4_)+ywfUm_53yMrEOOYr3;vzhTe&XP zXVsPkOXo!!YKd;2>9u9KvE-4%YGEhVr|_N2*|PD}#lj0mrJTRZ+cM9e8a!n};{Cr< zmvYYIVYfSOb@*RISCUxQpTO=N9a~PNs5HlPRj*ZA`kd$M=@K2usC8aXN(I}Ec5@%< z5Lo`{d+M~+Q=D@2bvI4i6C}Dl!d|nuutP3(RgLL}PhlbE8MhXnTVdW8e{kN5!y7!W zu5n-%+qQ41J2&%d$vvC@G+pbzvrc1j-)YX9>w?Pmfy?5I{O>ZFz_4G6lAE>Bax+R< zj8w8AvNyU8abRr0OK&6{C}je=CTZN7P|FE)jq><4qLv-#nso?kMoDalB#Lg5C5a{x zk!-{CmOOGR5Dn=_o4>_*<|KDdH7|Q_aW1_-4EA1oIFGVhbXPy0SNzVhz~1iuJ;pgn z*WGy8-0wOvt2tLo*{~>aP3qjixx8qJ2U-$C|(w~Z`rrap6Pt9yn zKiqhJR$6d6(h6AeY#dW@0vZLS9xcBTVedF_i^|J^ z8X%|uo+d%fkpOR0t;p3pD9Iy$EszPRn-iq95Mt&0GT2u+ZDgxfYyEsOwJs2b7o5F+G3 z1wC>VpoB02$XbBM6hs}391kG#kc&0cc<=?L2%@SH Date: Thu, 18 Jan 2024 10:25:00 +0100 Subject: [PATCH 29/57] remove obsolete python file --- shared-test-resources/srcCodeForTest.py | 93 ------------------------- 1 file changed, 93 deletions(-) delete mode 100644 shared-test-resources/srcCodeForTest.py diff --git a/shared-test-resources/srcCodeForTest.py b/shared-test-resources/srcCodeForTest.py deleted file mode 100644 index efc4121b0c7..00000000000 --- a/shared-test-resources/srcCodeForTest.py +++ /dev/null @@ -1,93 +0,0 @@ -import re -import os -import fnmatch -from re import search -import pdb - -srcMatches = [] -srcTestMatches = [] - -#Change this variable while updating the JavaDoc for new source code files -srcTargetDir='..\\..\\target' -for root, dirnames, filenames in os.walk(srcTargetDir): - for filename in fnmatch.filter(filenames, '*.java'): - srcMatches.append(os.path.join(root, filename)) -for root, dirnames, filenames in os.walk('..\\sootup.java.sourcecode\\src\\test\\java\\soot\\test\\java\\sourcecode\\minimaltestsuite\\'): - for filename in fnmatch.filter(filenames, '*Test.java'): - srcTestMatches.append(os.path.join(root, filename)) -for root, dirnames, filenames in os.walk('..\\sootup.java.bytecode\\src\\test\\java\\soot\\test\\java\\bytecode\\minimaltestsuite\\'): - for filename in fnmatch.filter(filenames, '*Test.java'): - srcTestMatches.append(os.path.join(root, filename)) -for srcFile in srcMatches: - ocb=0 - ccb=0 - flagRegex=0 - str ="/**

\n"
-	listData=[]
-	data=""
-	regexMethod =re.compile( "(\w*)[(]((([a-zA-Z])*(\s+)([a-zA-Z]))*)(([,])(\s+)([a-zA-Z])*(\s+)([a-zA-Z])*)*[)]" )
-	f= open(srcFile, 'r', encoding="utf8")
-	print(srcFile)
-	foundFlag=0
-
-	for line in f.readlines():
-		found=regexMethod.search(line)
-		if found:
-			foundFlag=1
-			if '{' in line :
-				ocb+=1
-			if '}' in line:
-				ccb+=1
-			str+=line
-			if found:
-				continue	
-			
-		if ocb >= 1 or foundFlag==1:	
-			if '{' in line :
-				ocb+=1
-			if '}' in line:
-				ccb+=1
-			if ocb>=ccb:
-				str+=line	
-			if '}' in line and ocb == 1 :
-				ocb=0
-				exit
-	
-	str+="\n
*/"
-	var1=""
-	srcFileName = (srcFile.rsplit('\\',1)[1]).split('.')[0]
-	
-	for filename in srcTestMatches:
-		dummy=srcFileName+"Test"
-		filenameDummy = (filename.rsplit('\\',1)[1]).split('.')[0]
-		if dummy == filenameDummy:
-			str2=""
-			var1=""
-			strSrcTest1=""
-			strSrcTest2=""
-			srcTestFile=filename
-			str2= open(srcTestFile, 'r', encoding="utf8").read()
-			for line in open(srcTestFile, 'r'):
-				l_strip=line.strip()
-				if	" expectedBodyStmts()" in l_strip:
-					break
-				else:
-					strSrcTest1+=line
-					#print("Line added for "+srcTestFile+line)
-				
-			found= re.search(r'  @Override(\s*)public List expectedBodyStmts((.+\s)*)}(\s*)((.+\s)*)}(\s*)',str2,re.DOTALL)
-			
-			if found != None:
-				strSrcTest2= var1.rsplit("\n",3)[0]+str
-				strSrcTest2+=found.group()
-				New2= ""
-				strSrcTestNew2 = "".join(strSrcTest1.rsplit('@Override', 1))
-				#pdb.set_trace()
-				strSrcTestNew2+=strSrcTest2
-				#pdb.set_trace()
-				with open(srcTestFile, 'w', encoding="utf8") as filew:
-					filew.writelines(strSrcTestNew2)
-					print("File write for file "+srcTestFile)
-			else :
-				print("No match for "+srcTestFile)
-				dummy=""

From d82c02fd1b634256236af5f1fbe0405614bafbc6 Mon Sep 17 00:00:00 2001
From: "M.Schmidt" 
Date: Thu, 18 Jan 2024 11:51:05 +0100
Subject: [PATCH 30/57] style, test todos

---
 .../bytecode/frontend/AsmJavaClassProvider.java    | 14 ++++++++------
 ...ModuleMultiReleaseJarAnalysisInputLocation.java |  4 ++++
 .../JavaModulePathAnalysisInputLocationTest.java   |  6 +++---
 ...leMultiReleaseJarAnalysisInputLocationTest.java |  6 ++++++
 4 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java
index 092f36fd269..3c90e11c230 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java
@@ -61,13 +61,15 @@ public Optional createClassSource(
       return Optional.empty();
     }
 
-    if (!actualClassSignature.replace('/', '.').equals(classType.getFullyQualifiedName().toString())) {
+    if (!actualClassSignature
+        .replace('/', '.')
+        .equals(classType.getFullyQualifiedName().toString())) {
       throw new IllegalStateException(
-              "The given Classtype '"
-                      + classType
-                      + "' did not match the found ClassType in the compilation unit '"
-                      + actualClassSignature
-                      + "'. Possibly the AnalysisInputLocation points to a subfolder already including the PackageName directory while the ClassType you wanted to retrieve is missing a PackageName.");
+          "The given Classtype '"
+              + classType
+              + "' did not match the found ClassType in the compilation unit '"
+              + actualClassSignature
+              + "'. Possibly the AnalysisInputLocation points to a subfolder already including the PackageName directory while the ClassType you wanted to retrieve is missing a PackageName.");
     }
 
     JavaClassType klassType = (JavaClassType) classType;
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java
index a64151e80e3..7fe76dfa457 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java
@@ -14,6 +14,10 @@
 import sootup.java.core.ModuleInfoAnalysisInputLocation;
 import sootup.java.core.signatures.ModuleSignature;
 
+/**
+ * This AnalysisInputLocation models MultiRelease Jars or Directories if path points to a directory
+ * that is not packed into a jar see https://openjdk.org/jeps/238#Modular_multi-release_JAR_files
+ */
 public class ModuleMultiReleaseJarAnalysisInputLocation extends MultiReleaseJarAnalysisInputLocation
     implements ModuleInfoAnalysisInputLocation {
   public ModuleMultiReleaseJarAnalysisInputLocation(
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java
index be22d72def3..57eafe4cdc1 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocationTest.java
@@ -2,13 +2,12 @@
 
 import static org.junit.Assert.*;
 
+import categories.Java9Test;
 import java.nio.file.Paths;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
-
-import categories.Java9Test;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -51,7 +50,8 @@ public void testJarModule() {
   public void testExplodedModule() {
     List inputLocations =
         Collections.singletonList(
-            new JavaModulePathAnalysisInputLocation(Paths.get(testPath + "uses-provides/exploded_module/")));
+            new JavaModulePathAnalysisInputLocation(
+                Paths.get(testPath + "uses-provides/exploded_module/")));
     List moduleInfoAnalysisInputLocations =
         Collections.emptyList();
     JavaModuleView view = new JavaModuleView(inputLocations, moduleInfoAnalysisInputLocations);
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java
index 553b9983b4f..42cfc8ee7aa 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java
@@ -29,6 +29,12 @@ public class ModuleMultiReleaseJarAnalysisInputLocationTest extends AnalysisInpu
   @Ignore("// FIXME")
   public void modularMultiReleaseJar() {
 
+    // TODO: test & create multiple types of input
+    // - [x] no module-info.class in root; module-info.class in version
+    // - [ ] no module-info.class in root; no module-info.class in version
+    // - [ ] module-info.class in root; no module-info.class in version
+    // - [ ] no module-info.class in root; no module-info.class in version -> non modular
+
     assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mmrj));
 
     final ClassType utilityNoModule =

From 03cb3b3e0a7b69e758ee9b5a4c9a5b33b51a9d5a Mon Sep 17 00:00:00 2001
From: "M.Schmidt" 
Date: Thu, 18 Jan 2024 12:08:57 +0100
Subject: [PATCH 31/57] header

---
 ...eMultiReleaseJarAnalysisInputLocation.java | 21 +++++++++++++++++++
 ...tiReleaseJarAnalysisInputLocationTest.java | 21 +++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java
index 7fe76dfa457..61b416aa0e6 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java
@@ -1,5 +1,26 @@
 package sootup.java.bytecode.inputlocation;
 
+/*-
+ * #%L
+ * Soot
+ * %%
+ * Copyright (C) 06.06.2018 Manuel Benz
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
 import java.nio.file.Path;
 import java.util.Collection;
 import java.util.Optional;
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java
index 42cfc8ee7aa..de5dd4c81bb 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java
@@ -1,5 +1,26 @@
 package sootup.java.bytecode.inputlocation;
 
+/*-
+ * #%L
+ * Soot
+ * %%
+ * Copyright (C) 06.06.2018 Manuel Benz
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 

From f0b075bed3aec090bfa28ffb12bd20953e0a0300 Mon Sep 17 00:00:00 2001
From: "M.Schmidt" 
Date: Thu, 18 Jan 2024 12:08:57 +0100
Subject: [PATCH 32/57] add license header - fix licenseheader check, change
 workflow to check in style

---
 .github/workflows/maven.yml                   |  3 +++
 pom.xml                                       |  8 ++++++-
 .../sootup/core/BaseViewChangeListener.java   | 22 +++++++++++++++++++
 .../java/sootup/core/ViewChangeListener.java  | 22 +++++++++++++++++++
 .../java/sootup/core/cache/ClassCache.java    | 22 +++++++++++++++++++
 .../java/sootup/core/cache/FullCache.java     | 22 +++++++++++++++++++
 .../main/java/sootup/core/cache/LRUCache.java | 22 +++++++++++++++++++
 .../sootup/core/cache/MutableClassCache.java  | 22 +++++++++++++++++++
 .../sootup/core/cache/MutableFullCache.java   | 22 +++++++++++++++++++
 .../cache/provider/ClassCacheProvider.java    | 22 +++++++++++++++++++
 .../cache/provider/FullCacheProvider.java     | 22 +++++++++++++++++++
 .../core/cache/provider/LRUCacheProvider.java | 22 +++++++++++++++++++
 .../provider/MutableFullCacheProvider.java    | 22 +++++++++++++++++++
 .../java/sootup/core/graph/BasicBlock.java    | 22 +++++++++++++++++++
 .../core/graph/ImmutableBasicBlock.java       | 22 +++++++++++++++++++
 .../core/graph/ImmutableBlockStmtGraph.java   | 22 +++++++++++++++++++
 .../core/graph/MutableBlockStmtGraph.java     | 22 +++++++++++++++++++
 .../EmptyClassLoadingOptions.java             | 22 +++++++++++++++++++
 .../java/sootup/core/jimple/basic/LValue.java | 22 +++++++++++++++++++
 .../jimple/common/stmt/FallsThroughStmt.java  | 22 +++++++++++++++++++
 .../core/jimple/common/stmt/JAssignStmt.java  | 22 +++++++++++++++++++
 .../visitor/AbstractImmediateVisitor.java     | 22 +++++++++++++++++++
 .../jimple/visitor/AbstractTypeVisitor.java   | 22 +++++++++++++++++++
 .../jimple/visitor/AbstractValueVisitor.java  | 22 +++++++++++++++++++
 .../core/jimple/visitor/AbstractVisitor.java  | 22 +++++++++++++++++++
 .../core/jimple/visitor/ImmediateVisitor.java | 22 +++++++++++++++++++
 .../java/sootup/core/model/HasPosition.java   | 22 +++++++++++++++++++
 .../java/sootup/core/model/LinePosition.java  | 22 +++++++++++++++++++
 .../main/java/sootup/core/model/Position.java | 22 +++++++++++++++++++
 .../java/sootup/core/util/DotExporter.java    | 22 +++++++++++++++++++
 .../java/sootup/core/views/MutableView.java   | 22 +++++++++++++++++++
 ...eMultiReleaseJarAnalysisInputLocation.java | 21 ++++++++++++++++++
 ...tiReleaseJarAnalysisInputLocationTest.java | 21 ++++++++++++++++++
 .../sootup/java/core/AnnotationUsage.java     | 22 +++++++++++++++++++
 .../java/core/JavaAnnotationSootMethod.java   | 22 +++++++++++++++++++
 .../core/ModuleInfoAnalysisInputLocation.java | 22 +++++++++++++++++++
 .../java/sootup/java/core/ModuleModifier.java | 22 +++++++++++++++++++
 .../java/core/views/MutableJavaView.java      | 22 +++++++++++++++++++
 .../parser/JimpleAnalysisInputLocation.java   | 22 +++++++++++++++++++
 .../jimple/parser/JimpleClassProvider.java    | 22 +++++++++++++++++++
 .../sootup/jimple/parser/JimpleConverter.java | 22 +++++++++++++++++++
 .../jimple/parser/JimpleConverterUtil.java    | 22 +++++++++++++++++++
 .../sootup/jimple/parser/JimpleLanguage.java  | 22 +++++++++++++++++++
 .../java/sootup/jimple/parser/JimpleView.java | 22 +++++++++++++++++++
 44 files changed, 932 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index ebb6639a1e7..a0c6d091f94 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -83,6 +83,9 @@ jobs:
       - name: Check Format
         run: mvn -B com.coveo:fmt-maven-plugin:check -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
 
+      - name: License Headers
+        run: mvn -B org.codehaus.mojo:license-maven-plugin:check-file-header -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
+
   JDK8:
     needs: Compilation
     runs-on: ubuntu-latest
diff --git a/pom.xml b/pom.xml
index 296d9da3a69..ce134d55566 100644
--- a/pom.xml
+++ b/pom.xml
@@ -324,9 +324,15 @@
                     lgpl_v2_1
                     Raja Vallée-Rai and others
                     
+                        sootup.java.analysis/src/main/java
                         sootup.callgraph/src/main/java
+                        sootup.core/src/main/java
+                        sootup.java.examples/src/main/java
                         sootup.java.bytecode/src/main/java
+                        sootup.java.core/src/main/java
                         sootup.java.sourcecode/src/main/java
+                        sootup.jimple.parser/src/main/java
+                        sootup.tests/src/main/java
                     
                 
                 
@@ -335,7 +341,7 @@
                         
                             check-file-header
                         
-                        verify
+                        none
                     
                 
             
diff --git a/sootup.core/src/main/java/sootup/core/BaseViewChangeListener.java b/sootup.core/src/main/java/sootup/core/BaseViewChangeListener.java
index 76d4baf64e2..cfa88865b86 100644
--- a/sootup.core/src/main/java/sootup/core/BaseViewChangeListener.java
+++ b/sootup.core/src/main/java/sootup/core/BaseViewChangeListener.java
@@ -1,5 +1,27 @@
 package sootup.core;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import sootup.core.model.SootClass;
 import sootup.core.model.SootMethod;
 
diff --git a/sootup.core/src/main/java/sootup/core/ViewChangeListener.java b/sootup.core/src/main/java/sootup/core/ViewChangeListener.java
index a72c7d65418..967685e58b5 100644
--- a/sootup.core/src/main/java/sootup/core/ViewChangeListener.java
+++ b/sootup.core/src/main/java/sootup/core/ViewChangeListener.java
@@ -1,5 +1,27 @@
 package sootup.core;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import sootup.core.model.SootClass;
 import sootup.core.model.SootMethod;
 
diff --git a/sootup.core/src/main/java/sootup/core/cache/ClassCache.java b/sootup.core/src/main/java/sootup/core/cache/ClassCache.java
index 7c7c85244d6..fa3a2a349f3 100644
--- a/sootup.core/src/main/java/sootup/core/cache/ClassCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/ClassCache.java
@@ -1,5 +1,27 @@
 package sootup.core.cache;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.Collection;
 import javax.annotation.Nonnull;
 import sootup.core.model.SootClass;
diff --git a/sootup.core/src/main/java/sootup/core/cache/FullCache.java b/sootup.core/src/main/java/sootup/core/cache/FullCache.java
index 658170d1b63..c9f36bbffe3 100644
--- a/sootup.core/src/main/java/sootup/core/cache/FullCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/FullCache.java
@@ -1,5 +1,27 @@
 package sootup.core.cache;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
diff --git a/sootup.core/src/main/java/sootup/core/cache/LRUCache.java b/sootup.core/src/main/java/sootup/core/cache/LRUCache.java
index fbe5e7ea67a..e0c4ed0d54f 100644
--- a/sootup.core/src/main/java/sootup/core/cache/LRUCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/LRUCache.java
@@ -1,5 +1,27 @@
 package sootup.core.cache;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.*;
 import javax.annotation.Nonnull;
 import sootup.core.model.SootClass;
diff --git a/sootup.core/src/main/java/sootup/core/cache/MutableClassCache.java b/sootup.core/src/main/java/sootup/core/cache/MutableClassCache.java
index 09b362ce5ea..4755d6e1e87 100644
--- a/sootup.core/src/main/java/sootup/core/cache/MutableClassCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/MutableClassCache.java
@@ -1,5 +1,27 @@
 package sootup.core.cache;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import javax.annotation.Nonnull;
 import sootup.core.model.SootClass;
 import sootup.core.types.ClassType;
diff --git a/sootup.core/src/main/java/sootup/core/cache/MutableFullCache.java b/sootup.core/src/main/java/sootup/core/cache/MutableFullCache.java
index 9fe303b9e62..ff9098566d6 100644
--- a/sootup.core/src/main/java/sootup/core/cache/MutableFullCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/MutableFullCache.java
@@ -1,5 +1,27 @@
 package sootup.core.cache;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import javax.annotation.Nonnull;
 import sootup.core.model.SootClass;
 import sootup.core.types.ClassType;
diff --git a/sootup.core/src/main/java/sootup/core/cache/provider/ClassCacheProvider.java b/sootup.core/src/main/java/sootup/core/cache/provider/ClassCacheProvider.java
index bba31e5a15a..7304a6e61f1 100644
--- a/sootup.core/src/main/java/sootup/core/cache/provider/ClassCacheProvider.java
+++ b/sootup.core/src/main/java/sootup/core/cache/provider/ClassCacheProvider.java
@@ -1,5 +1,27 @@
 package sootup.core.cache.provider;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import sootup.core.cache.ClassCache;
 
 /** Interface for cache providers. */
diff --git a/sootup.core/src/main/java/sootup/core/cache/provider/FullCacheProvider.java b/sootup.core/src/main/java/sootup/core/cache/provider/FullCacheProvider.java
index c6bc63226d9..9ff8a4fe8a0 100644
--- a/sootup.core/src/main/java/sootup/core/cache/provider/FullCacheProvider.java
+++ b/sootup.core/src/main/java/sootup/core/cache/provider/FullCacheProvider.java
@@ -1,5 +1,27 @@
 package sootup.core.cache.provider;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import sootup.core.cache.ClassCache;
 import sootup.core.cache.FullCache;
 
diff --git a/sootup.core/src/main/java/sootup/core/cache/provider/LRUCacheProvider.java b/sootup.core/src/main/java/sootup/core/cache/provider/LRUCacheProvider.java
index 762ff2153ac..bf69ab0b76c 100644
--- a/sootup.core/src/main/java/sootup/core/cache/provider/LRUCacheProvider.java
+++ b/sootup.core/src/main/java/sootup/core/cache/provider/LRUCacheProvider.java
@@ -1,5 +1,27 @@
 package sootup.core.cache.provider;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import sootup.core.cache.ClassCache;
 import sootup.core.cache.LRUCache;
 
diff --git a/sootup.core/src/main/java/sootup/core/cache/provider/MutableFullCacheProvider.java b/sootup.core/src/main/java/sootup/core/cache/provider/MutableFullCacheProvider.java
index f253e6e00f9..d624dab195e 100644
--- a/sootup.core/src/main/java/sootup/core/cache/provider/MutableFullCacheProvider.java
+++ b/sootup.core/src/main/java/sootup/core/cache/provider/MutableFullCacheProvider.java
@@ -1,5 +1,27 @@
 package sootup.core.cache.provider;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import sootup.core.cache.ClassCache;
 import sootup.core.cache.MutableFullCache;
 
diff --git a/sootup.core/src/main/java/sootup/core/graph/BasicBlock.java b/sootup.core/src/main/java/sootup/core/graph/BasicBlock.java
index b27d188b2c3..5642ae00f31 100644
--- a/sootup.core/src/main/java/sootup/core/graph/BasicBlock.java
+++ b/sootup.core/src/main/java/sootup/core/graph/BasicBlock.java
@@ -1,5 +1,27 @@
 package sootup.core.graph;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.List;
 import java.util.Map;
 import javax.annotation.Nonnull;
diff --git a/sootup.core/src/main/java/sootup/core/graph/ImmutableBasicBlock.java b/sootup.core/src/main/java/sootup/core/graph/ImmutableBasicBlock.java
index 2cb3c57a337..15a0d1d2f3a 100644
--- a/sootup.core/src/main/java/sootup/core/graph/ImmutableBasicBlock.java
+++ b/sootup.core/src/main/java/sootup/core/graph/ImmutableBasicBlock.java
@@ -1,5 +1,27 @@
 package sootup.core.graph;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.List;
 import java.util.Map;
 import javax.annotation.Nonnull;
diff --git a/sootup.core/src/main/java/sootup/core/graph/ImmutableBlockStmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/ImmutableBlockStmtGraph.java
index 7354ca426d8..3d1ac812829 100644
--- a/sootup.core/src/main/java/sootup/core/graph/ImmutableBlockStmtGraph.java
+++ b/sootup.core/src/main/java/sootup/core/graph/ImmutableBlockStmtGraph.java
@@ -1,5 +1,27 @@
 package sootup.core.graph;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import com.google.common.collect.Lists;
 import java.util.*;
 import javax.annotation.Nonnull;
diff --git a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java
index c8b53be8814..a90981b322c 100644
--- a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java
+++ b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java
@@ -1,5 +1,27 @@
 package sootup.core.graph;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import com.google.common.collect.ComparisonChain;
 import com.google.common.collect.Lists;
 import java.util.*;
diff --git a/sootup.core/src/main/java/sootup/core/inputlocation/EmptyClassLoadingOptions.java b/sootup.core/src/main/java/sootup/core/inputlocation/EmptyClassLoadingOptions.java
index ce252da5f3f..4ea2ab65e03 100644
--- a/sootup.core/src/main/java/sootup/core/inputlocation/EmptyClassLoadingOptions.java
+++ b/sootup.core/src/main/java/sootup/core/inputlocation/EmptyClassLoadingOptions.java
@@ -1,5 +1,27 @@
 package sootup.core.inputlocation;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.Collections;
 import java.util.List;
 import javax.annotation.Nonnull;
diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/LValue.java b/sootup.core/src/main/java/sootup/core/jimple/basic/LValue.java
index e7ff23de3c2..16a65602ccb 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/basic/LValue.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/basic/LValue.java
@@ -1,4 +1,26 @@
 package sootup.core.jimple.basic;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 /** Marker interface for Values that can be on the left side of an Assignment */
 public interface LValue extends Value {}
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/FallsThroughStmt.java b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/FallsThroughStmt.java
index 6bab22a5b62..92e2cd4211b 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/FallsThroughStmt.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/FallsThroughStmt.java
@@ -1,5 +1,27 @@
 package sootup.core.jimple.common.stmt;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 /** as an equivalent to BranchingStmt */
 public interface FallsThroughStmt extends Stmt {
 
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
index 3301d2d5422..5055ffc0ce9 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
@@ -1,5 +1,27 @@
 package sootup.core.jimple.common.stmt;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 /*-
  * #%Value
  * Soot - a J*va Optimization Framework
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractImmediateVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractImmediateVisitor.java
index b10be5e9632..e1f8e79993d 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractImmediateVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractImmediateVisitor.java
@@ -1,5 +1,27 @@
 package sootup.core.jimple.visitor;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import javax.annotation.Nonnull;
 import sootup.core.jimple.basic.Immediate;
 import sootup.core.jimple.basic.Local;
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractTypeVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractTypeVisitor.java
index f61fca7e998..8e6020ed5b3 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractTypeVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractTypeVisitor.java
@@ -1,5 +1,27 @@
 package sootup.core.jimple.visitor;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import javax.annotation.Nonnull;
 import sootup.core.types.*;
 
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractValueVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractValueVisitor.java
index f72e15ab648..5e269c653a3 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractValueVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractValueVisitor.java
@@ -1,5 +1,27 @@
 package sootup.core.jimple.visitor;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import javax.annotation.Nonnull;
 import sootup.core.jimple.basic.Local;
 import sootup.core.jimple.basic.Value;
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractVisitor.java
index fe2026df887..96695975504 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractVisitor.java
@@ -1,5 +1,27 @@
 package sootup.core.jimple.visitor;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 /**
  * Base class for retrieving a calculated result from the implemented Visitor (which is basically a
  * switch via OOP)
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/ImmediateVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/ImmediateVisitor.java
index 1f8a51b52f6..23b2192ecf9 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/ImmediateVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/ImmediateVisitor.java
@@ -1,5 +1,27 @@
 package sootup.core.jimple.visitor;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import javax.annotation.Nonnull;
 import sootup.core.jimple.basic.Local;
 
diff --git a/sootup.core/src/main/java/sootup/core/model/HasPosition.java b/sootup.core/src/main/java/sootup/core/model/HasPosition.java
index 68a00eaffe8..a2aa456e8f6 100644
--- a/sootup.core/src/main/java/sootup/core/model/HasPosition.java
+++ b/sootup.core/src/main/java/sootup/core/model/HasPosition.java
@@ -1,5 +1,27 @@
 package sootup.core.model;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 /**
  * Interface to mark Soot code objects that may contain code location information.
  *
diff --git a/sootup.core/src/main/java/sootup/core/model/LinePosition.java b/sootup.core/src/main/java/sootup/core/model/LinePosition.java
index 624ffa88fb8..f6f64d15e68 100644
--- a/sootup.core/src/main/java/sootup/core/model/LinePosition.java
+++ b/sootup.core/src/main/java/sootup/core/model/LinePosition.java
@@ -1,5 +1,27 @@
 package sootup.core.model;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 public class LinePosition extends Position {
   private final int lineNo;
 
diff --git a/sootup.core/src/main/java/sootup/core/model/Position.java b/sootup.core/src/main/java/sootup/core/model/Position.java
index 9a0aa6844e3..42158cca4d1 100644
--- a/sootup.core/src/main/java/sootup/core/model/Position.java
+++ b/sootup.core/src/main/java/sootup/core/model/Position.java
@@ -1,5 +1,27 @@
 package sootup.core.model;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import javax.annotation.Nonnull;
 
 public abstract class Position implements Comparable {
diff --git a/sootup.core/src/main/java/sootup/core/util/DotExporter.java b/sootup.core/src/main/java/sootup/core/util/DotExporter.java
index 134435c9043..0b784f18617 100644
--- a/sootup.core/src/main/java/sootup/core/util/DotExporter.java
+++ b/sootup.core/src/main/java/sootup/core/util/DotExporter.java
@@ -1,5 +1,27 @@
 package sootup.core.util;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import com.google.common.collect.Sets;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
diff --git a/sootup.core/src/main/java/sootup/core/views/MutableView.java b/sootup.core/src/main/java/sootup/core/views/MutableView.java
index 53db90cd92d..521e68326b1 100644
--- a/sootup.core/src/main/java/sootup/core/views/MutableView.java
+++ b/sootup.core/src/main/java/sootup/core/views/MutableView.java
@@ -1,5 +1,27 @@
 package sootup.core.views;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import sootup.core.ViewChangeListener;
 
 /**
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java
index 7fe76dfa457..61b416aa0e6 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java
@@ -1,5 +1,26 @@
 package sootup.java.bytecode.inputlocation;
 
+/*-
+ * #%L
+ * Soot
+ * %%
+ * Copyright (C) 06.06.2018 Manuel Benz
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
 import java.nio.file.Path;
 import java.util.Collection;
 import java.util.Optional;
diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java
index 42cfc8ee7aa..de5dd4c81bb 100644
--- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java
+++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocationTest.java
@@ -1,5 +1,26 @@
 package sootup.java.bytecode.inputlocation;
 
+/*-
+ * #%L
+ * Soot
+ * %%
+ * Copyright (C) 06.06.2018 Manuel Benz
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
diff --git a/sootup.java.core/src/main/java/sootup/java/core/AnnotationUsage.java b/sootup.java.core/src/main/java/sootup/java/core/AnnotationUsage.java
index c89b37917af..f4370c1beb0 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/AnnotationUsage.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/AnnotationUsage.java
@@ -1,5 +1,27 @@
 package sootup.java.core;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaAnnotationSootMethod.java b/sootup.java.core/src/main/java/sootup/java/core/JavaAnnotationSootMethod.java
index 81227e5c845..aab429ed50a 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/JavaAnnotationSootMethod.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/JavaAnnotationSootMethod.java
@@ -1,5 +1,27 @@
 package sootup.java.core;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import sootup.core.frontend.BodySource;
diff --git a/sootup.java.core/src/main/java/sootup/java/core/ModuleInfoAnalysisInputLocation.java b/sootup.java.core/src/main/java/sootup/java/core/ModuleInfoAnalysisInputLocation.java
index 7b36f0cf013..e11c69fbd8d 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/ModuleInfoAnalysisInputLocation.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/ModuleInfoAnalysisInputLocation.java
@@ -1,5 +1,27 @@
 package sootup.java.core;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.Collection;
 import java.util.Optional;
 import java.util.Set;
diff --git a/sootup.java.core/src/main/java/sootup/java/core/ModuleModifier.java b/sootup.java.core/src/main/java/sootup/java/core/ModuleModifier.java
index 43b765e71d0..60afd69aa69 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/ModuleModifier.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/ModuleModifier.java
@@ -1,5 +1,27 @@
 package sootup.java.core;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 // Modifier for java 9 modules corresponding to the bytecodes used in module-info.class
 public enum ModuleModifier {
   OPENS(0x0020), // a module is accessible to reflection (deep&shallow)
diff --git a/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java b/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java
index 861d2940399..e63ba9f5dd0 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java
@@ -1,5 +1,27 @@
 package sootup.java.core.views;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.*;
 import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java
index d95713da8fe..a4d93d7755e 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java
@@ -1,5 +1,27 @@
 package sootup.jimple.parser;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java
index 8bad43f6e89..bee940913f1 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java
@@ -1,5 +1,27 @@
 package sootup.jimple.parser;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.List;
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java
index 32697a283a7..eb3d6324330 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java
@@ -1,5 +1,27 @@
 package sootup.jimple.parser;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.nio.file.Path;
 import java.util.*;
 import java.util.stream.Collectors;
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverterUtil.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverterUtil.java
index fe01543387c..205cce3372a 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverterUtil.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverterUtil.java
@@ -1,5 +1,27 @@
 package sootup.jimple.parser;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.nio.file.Path;
 import java.util.*;
 import javax.annotation.Nonnull;
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleLanguage.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleLanguage.java
index 24497df1100..71dfbb397a0 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleLanguage.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleLanguage.java
@@ -1,5 +1,27 @@
 package sootup.jimple.parser;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import sootup.core.IdentifierFactory;
 import sootup.core.Language;
 import sootup.java.core.JavaIdentifierFactory;
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java
index bcf1d66a798..c382c133b67 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java
@@ -1,5 +1,27 @@
 package sootup.jimple.parser;
 
+/*-
+ * #%L
+ * SootUp
+ * %%
+ * Copyright (C) 1997 - 2024 Raja Vallée-Rai and others
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 2.1 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Lesser Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program.  If not, see
+ * .
+ * #L%
+ */
+
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;

From 0ae8c4d1168f5f9e8952aa0d09fa9cbe101ea523 Mon Sep 17 00:00:00 2001
From: "M.Schmidt" 
Date: Thu, 18 Jan 2024 13:59:08 +0100
Subject: [PATCH 33/57] sytle

---
 .../src/main/java/sootup/core/BaseViewChangeListener.java     | 4 ++--
 sootup.core/src/main/java/sootup/core/ViewChangeListener.java | 4 ++--
 sootup.core/src/main/java/sootup/core/cache/ClassCache.java   | 4 ++--
 sootup.core/src/main/java/sootup/core/cache/FullCache.java    | 4 ++--
 sootup.core/src/main/java/sootup/core/cache/LRUCache.java     | 4 ++--
 .../src/main/java/sootup/core/cache/MutableClassCache.java    | 4 ++--
 .../src/main/java/sootup/core/cache/MutableFullCache.java     | 4 ++--
 .../java/sootup/core/cache/provider/ClassCacheProvider.java   | 4 ++--
 .../java/sootup/core/cache/provider/FullCacheProvider.java    | 4 ++--
 .../java/sootup/core/cache/provider/LRUCacheProvider.java     | 4 ++--
 .../sootup/core/cache/provider/MutableFullCacheProvider.java  | 4 ++--
 sootup.core/src/main/java/sootup/core/graph/BasicBlock.java   | 4 ++--
 .../src/main/java/sootup/core/graph/ImmutableBasicBlock.java  | 4 ++--
 .../main/java/sootup/core/graph/ImmutableBlockStmtGraph.java  | 4 ++--
 .../main/java/sootup/core/graph/MutableBlockStmtGraph.java    | 4 ++--
 .../sootup/core/inputlocation/EmptyClassLoadingOptions.java   | 4 ++--
 .../src/main/java/sootup/core/jimple/basic/LValue.java        | 4 ++--
 .../java/sootup/core/jimple/common/stmt/FallsThroughStmt.java | 4 ++--
 .../main/java/sootup/core/jimple/common/stmt/JAssignStmt.java | 4 ++--
 .../sootup/core/jimple/visitor/AbstractImmediateVisitor.java  | 4 ++--
 .../java/sootup/core/jimple/visitor/AbstractTypeVisitor.java  | 4 ++--
 .../java/sootup/core/jimple/visitor/AbstractValueVisitor.java | 4 ++--
 .../main/java/sootup/core/jimple/visitor/AbstractVisitor.java | 4 ++--
 .../java/sootup/core/jimple/visitor/ImmediateVisitor.java     | 4 ++--
 sootup.core/src/main/java/sootup/core/model/HasPosition.java  | 4 ++--
 sootup.core/src/main/java/sootup/core/model/LinePosition.java | 4 ++--
 sootup.core/src/main/java/sootup/core/model/Position.java     | 4 ++--
 sootup.core/src/main/java/sootup/core/util/DotExporter.java   | 4 ++--
 sootup.core/src/main/java/sootup/core/views/MutableView.java  | 4 ++--
 .../src/main/java/sootup/java/core/AnnotationUsage.java       | 4 ++--
 .../main/java/sootup/java/core/JavaAnnotationSootMethod.java  | 4 ++--
 .../sootup/java/core/ModuleInfoAnalysisInputLocation.java     | 4 ++--
 .../src/main/java/sootup/java/core/ModuleModifier.java        | 4 ++--
 .../src/main/java/sootup/java/core/views/MutableJavaView.java | 4 ++--
 .../sootup/jimple/parser/JimpleAnalysisInputLocation.java     | 4 ++--
 .../main/java/sootup/jimple/parser/JimpleClassProvider.java   | 4 ++--
 .../src/main/java/sootup/jimple/parser/JimpleConverter.java   | 4 ++--
 .../main/java/sootup/jimple/parser/JimpleConverterUtil.java   | 4 ++--
 .../src/main/java/sootup/jimple/parser/JimpleLanguage.java    | 4 ++--
 .../src/main/java/sootup/jimple/parser/JimpleView.java        | 4 ++--
 40 files changed, 80 insertions(+), 80 deletions(-)

diff --git a/sootup.core/src/main/java/sootup/core/BaseViewChangeListener.java b/sootup.core/src/main/java/sootup/core/BaseViewChangeListener.java
index cfa88865b86..83d12923b70 100644
--- a/sootup.core/src/main/java/sootup/core/BaseViewChangeListener.java
+++ b/sootup.core/src/main/java/sootup/core/BaseViewChangeListener.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/ViewChangeListener.java b/sootup.core/src/main/java/sootup/core/ViewChangeListener.java
index 967685e58b5..7981fd96bf2 100644
--- a/sootup.core/src/main/java/sootup/core/ViewChangeListener.java
+++ b/sootup.core/src/main/java/sootup/core/ViewChangeListener.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/cache/ClassCache.java b/sootup.core/src/main/java/sootup/core/cache/ClassCache.java
index fa3a2a349f3..27674076559 100644
--- a/sootup.core/src/main/java/sootup/core/cache/ClassCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/ClassCache.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/cache/FullCache.java b/sootup.core/src/main/java/sootup/core/cache/FullCache.java
index c9f36bbffe3..f1932077315 100644
--- a/sootup.core/src/main/java/sootup/core/cache/FullCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/FullCache.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/cache/LRUCache.java b/sootup.core/src/main/java/sootup/core/cache/LRUCache.java
index e0c4ed0d54f..44b7b053669 100644
--- a/sootup.core/src/main/java/sootup/core/cache/LRUCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/LRUCache.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/cache/MutableClassCache.java b/sootup.core/src/main/java/sootup/core/cache/MutableClassCache.java
index 4755d6e1e87..c4d1435e1ca 100644
--- a/sootup.core/src/main/java/sootup/core/cache/MutableClassCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/MutableClassCache.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/cache/MutableFullCache.java b/sootup.core/src/main/java/sootup/core/cache/MutableFullCache.java
index ff9098566d6..e03b8512724 100644
--- a/sootup.core/src/main/java/sootup/core/cache/MutableFullCache.java
+++ b/sootup.core/src/main/java/sootup/core/cache/MutableFullCache.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/cache/provider/ClassCacheProvider.java b/sootup.core/src/main/java/sootup/core/cache/provider/ClassCacheProvider.java
index 7304a6e61f1..2913ffeb500 100644
--- a/sootup.core/src/main/java/sootup/core/cache/provider/ClassCacheProvider.java
+++ b/sootup.core/src/main/java/sootup/core/cache/provider/ClassCacheProvider.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/cache/provider/FullCacheProvider.java b/sootup.core/src/main/java/sootup/core/cache/provider/FullCacheProvider.java
index 9ff8a4fe8a0..324aae8e346 100644
--- a/sootup.core/src/main/java/sootup/core/cache/provider/FullCacheProvider.java
+++ b/sootup.core/src/main/java/sootup/core/cache/provider/FullCacheProvider.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/cache/provider/LRUCacheProvider.java b/sootup.core/src/main/java/sootup/core/cache/provider/LRUCacheProvider.java
index bf69ab0b76c..e23adc4640d 100644
--- a/sootup.core/src/main/java/sootup/core/cache/provider/LRUCacheProvider.java
+++ b/sootup.core/src/main/java/sootup/core/cache/provider/LRUCacheProvider.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/cache/provider/MutableFullCacheProvider.java b/sootup.core/src/main/java/sootup/core/cache/provider/MutableFullCacheProvider.java
index d624dab195e..20123f81468 100644
--- a/sootup.core/src/main/java/sootup/core/cache/provider/MutableFullCacheProvider.java
+++ b/sootup.core/src/main/java/sootup/core/cache/provider/MutableFullCacheProvider.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/graph/BasicBlock.java b/sootup.core/src/main/java/sootup/core/graph/BasicBlock.java
index 5642ae00f31..c104a4110ce 100644
--- a/sootup.core/src/main/java/sootup/core/graph/BasicBlock.java
+++ b/sootup.core/src/main/java/sootup/core/graph/BasicBlock.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/graph/ImmutableBasicBlock.java b/sootup.core/src/main/java/sootup/core/graph/ImmutableBasicBlock.java
index 15a0d1d2f3a..3a0ed109165 100644
--- a/sootup.core/src/main/java/sootup/core/graph/ImmutableBasicBlock.java
+++ b/sootup.core/src/main/java/sootup/core/graph/ImmutableBasicBlock.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/graph/ImmutableBlockStmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/ImmutableBlockStmtGraph.java
index 3d1ac812829..d49275e02c3 100644
--- a/sootup.core/src/main/java/sootup/core/graph/ImmutableBlockStmtGraph.java
+++ b/sootup.core/src/main/java/sootup/core/graph/ImmutableBlockStmtGraph.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java
index a90981b322c..b1b692601ad 100644
--- a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java
+++ b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/inputlocation/EmptyClassLoadingOptions.java b/sootup.core/src/main/java/sootup/core/inputlocation/EmptyClassLoadingOptions.java
index 4ea2ab65e03..3fda3aa8254 100644
--- a/sootup.core/src/main/java/sootup/core/inputlocation/EmptyClassLoadingOptions.java
+++ b/sootup.core/src/main/java/sootup/core/inputlocation/EmptyClassLoadingOptions.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/LValue.java b/sootup.core/src/main/java/sootup/core/jimple/basic/LValue.java
index 16a65602ccb..d01bde97314 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/basic/LValue.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/basic/LValue.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/FallsThroughStmt.java b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/FallsThroughStmt.java
index 92e2cd4211b..0568cdcaa4a 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/FallsThroughStmt.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/FallsThroughStmt.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
index 5055ffc0ce9..064eb5d359e 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/JAssignStmt.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractImmediateVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractImmediateVisitor.java
index e1f8e79993d..f9721e13a57 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractImmediateVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractImmediateVisitor.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractTypeVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractTypeVisitor.java
index 8e6020ed5b3..d646e6d0cc9 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractTypeVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractTypeVisitor.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractValueVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractValueVisitor.java
index 5e269c653a3..bc9fcf6477f 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractValueVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractValueVisitor.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractVisitor.java
index 96695975504..12de0b5dda1 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/AbstractVisitor.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/jimple/visitor/ImmediateVisitor.java b/sootup.core/src/main/java/sootup/core/jimple/visitor/ImmediateVisitor.java
index 23b2192ecf9..a95d4fcffe7 100644
--- a/sootup.core/src/main/java/sootup/core/jimple/visitor/ImmediateVisitor.java
+++ b/sootup.core/src/main/java/sootup/core/jimple/visitor/ImmediateVisitor.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/model/HasPosition.java b/sootup.core/src/main/java/sootup/core/model/HasPosition.java
index a2aa456e8f6..b4a7c58a85c 100644
--- a/sootup.core/src/main/java/sootup/core/model/HasPosition.java
+++ b/sootup.core/src/main/java/sootup/core/model/HasPosition.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/model/LinePosition.java b/sootup.core/src/main/java/sootup/core/model/LinePosition.java
index f6f64d15e68..a7d1afb62f0 100644
--- a/sootup.core/src/main/java/sootup/core/model/LinePosition.java
+++ b/sootup.core/src/main/java/sootup/core/model/LinePosition.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/model/Position.java b/sootup.core/src/main/java/sootup/core/model/Position.java
index 42158cca4d1..671873f2f8e 100644
--- a/sootup.core/src/main/java/sootup/core/model/Position.java
+++ b/sootup.core/src/main/java/sootup/core/model/Position.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/util/DotExporter.java b/sootup.core/src/main/java/sootup/core/util/DotExporter.java
index 0b784f18617..e5f4a543dd7 100644
--- a/sootup.core/src/main/java/sootup/core/util/DotExporter.java
+++ b/sootup.core/src/main/java/sootup/core/util/DotExporter.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.core/src/main/java/sootup/core/views/MutableView.java b/sootup.core/src/main/java/sootup/core/views/MutableView.java
index 521e68326b1..9ccff00d9c7 100644
--- a/sootup.core/src/main/java/sootup/core/views/MutableView.java
+++ b/sootup.core/src/main/java/sootup/core/views/MutableView.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.java.core/src/main/java/sootup/java/core/AnnotationUsage.java b/sootup.java.core/src/main/java/sootup/java/core/AnnotationUsage.java
index f4370c1beb0..6f4f163c295 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/AnnotationUsage.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/AnnotationUsage.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaAnnotationSootMethod.java b/sootup.java.core/src/main/java/sootup/java/core/JavaAnnotationSootMethod.java
index aab429ed50a..fa2038788d1 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/JavaAnnotationSootMethod.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/JavaAnnotationSootMethod.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.java.core/src/main/java/sootup/java/core/ModuleInfoAnalysisInputLocation.java b/sootup.java.core/src/main/java/sootup/java/core/ModuleInfoAnalysisInputLocation.java
index e11c69fbd8d..5becf5e5217 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/ModuleInfoAnalysisInputLocation.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/ModuleInfoAnalysisInputLocation.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.java.core/src/main/java/sootup/java/core/ModuleModifier.java b/sootup.java.core/src/main/java/sootup/java/core/ModuleModifier.java
index 60afd69aa69..d02068ac814 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/ModuleModifier.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/ModuleModifier.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java b/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java
index e63ba9f5dd0..c4b89ce0d02 100644
--- a/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java
+++ b/sootup.java.core/src/main/java/sootup/java/core/views/MutableJavaView.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java
index a4d93d7755e..fe77e297be7 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleAnalysisInputLocation.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java
index bee940913f1..e71e9b81b76 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleClassProvider.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java
index eb3d6324330..8873e4e4e03 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverter.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverterUtil.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverterUtil.java
index 205cce3372a..df6ce5d109b 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverterUtil.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleConverterUtil.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleLanguage.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleLanguage.java
index 71dfbb397a0..d9bbe83254b 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleLanguage.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleLanguage.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .
diff --git a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java
index c382c133b67..17a964b742c 100644
--- a/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java
+++ b/sootup.jimple.parser/src/main/java/sootup/jimple/parser/JimpleView.java
@@ -10,12 +10,12 @@
  * it under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation, either version 2.1 of the
  * License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Lesser Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Lesser Public
  * License along with this program.  If not, see
  * .

From 763c73bda23226b9db3e739e81fd0841bbd7548c Mon Sep 17 00:00:00 2001
From: "M.Schmidt" 
Date: Thu, 18 Jan 2024 15:18:05 +0100
Subject: [PATCH 34/57] remove obsolete test

---
 .../JimpleAnalysisInputLocationTest.java      | 27 -------------------
 1 file changed, 27 deletions(-)

diff --git a/sootup.jimple.parser/src/test/java/sootup/jimple/parser/JimpleAnalysisInputLocationTest.java b/sootup.jimple.parser/src/test/java/sootup/jimple/parser/JimpleAnalysisInputLocationTest.java
index 93fbc2e7b6f..29e6e282925 100644
--- a/sootup.jimple.parser/src/test/java/sootup/jimple/parser/JimpleAnalysisInputLocationTest.java
+++ b/sootup.jimple.parser/src/test/java/sootup/jimple/parser/JimpleAnalysisInputLocationTest.java
@@ -1,17 +1,12 @@
 package sootup.jimple.parser;
 
-import static junit.framework.TestCase.assertEquals;
 import static org.junit.Assert.*;
 
 import java.nio.file.Paths;
-import java.util.Collection;
-import java.util.HashSet;
 import java.util.Optional;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import sootup.core.inputlocation.AnalysisInputLocation;
 import sootup.core.model.SootClass;
-import sootup.core.model.SourceType;
 import sootup.core.signatures.PackageName;
 import sootup.core.types.ClassType;
 import sootup.jimple.parser.categories.Java8Test;
@@ -114,26 +109,4 @@ public PackageName getPackageName() {
     final Optional classSource4 = jv2.getClass(classType);
     assertTrue(classSource4.isPresent());
   }
-
-  /**
-   * Test for JimpleAnalysisInputLocation. Specifying jimple file with source type as Library.
-   * Expected - All input classes are of source type Library.
-   */
-  @Test
-  public void specifyBuiltInInputJimplePath() {
-    String classPath = "src/test/java/resources/jimple";
-    AnalysisInputLocation jimpleInputLocation =
-        new JimpleAnalysisInputLocation(Paths.get(classPath), SourceType.Library);
-    JimpleView view = new JimpleView(jimpleInputLocation);
-
-    Collection classes = new HashSet<>(); // Set to track the classes to check
-
-    for (SootClass aClass : view.getClasses()) {
-      if (!aClass.isLibraryClass()) {
-        classes.add(aClass);
-      }
-    }
-
-    assertEquals("User Defined class found, expected none", 0, classes.size());
-  }
 }

From 4b035a3ce0276826aa3592fa3f830341fc841d8b Mon Sep 17 00:00:00 2001
From: "M.Schmidt" 
Date: Thu, 18 Jan 2024 15:41:12 +0100
Subject: [PATCH 35/57] fix handling invalid class files

---
 .../sootup/java/bytecode/frontend/AsmJavaClassProvider.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java
index 3c90e11c230..c48623d1b74 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java
@@ -57,7 +57,7 @@ public Optional createClassSource(
     final String actualClassSignature;
     try {
       actualClassSignature = AsmUtil.initAsmClassSource(sourcePath, classNode);
-    } catch (IOException exception) {
+    } catch (IOException | IllegalArgumentException exception) {
       return Optional.empty();
     }
 

From a49feda8cfd51103ca52b5e7ba1f41421739d5d4 Mon Sep 17 00:00:00 2001
From: "M.Schmidt" 
Date: Thu, 18 Jan 2024 16:24:06 +0100
Subject: [PATCH 36/57] remove obsolete StmtContainer + usages

---
 .../bytecode/frontend/AsmMethodSource.java    |  33 +---
 .../java/bytecode/frontend/StmtContainer.java | 152 ------------------
 2 files changed, 4 insertions(+), 181 deletions(-)
 delete mode 100644 sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/StmtContainer.java

diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
index b45757cfe25..3855bd001ce 100644
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
+++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java
@@ -1650,12 +1650,11 @@ private void arrangeStmts(
       if (!danglingLabel.isEmpty()) {
         // there is (at least) a LabelNode ->
         // associate collected labels from danglingLabel with the following stmt
-        Stmt targetStmt =
-            stmt instanceof StmtContainer ? ((StmtContainer) stmt).getFirstStmt() : stmt;
+        Stmt targetStmt = stmt;
         danglingLabel.forEach(l -> labelsToStmt.put(l, targetStmt));
         if (isLabelNode) {
           // If the targetStmt is an exception handler, register the starting Stmt for it
-          JIdentityStmt identityRef = findIdentityRefInStmtContainer(stmt);
+          JIdentityStmt identityRef = stmt instanceof JIdentityStmt ? (JIdentityStmt) stmt : null;
           if (identityRef != null && identityRef.getRightOp() instanceof JCaughtExceptionRef) {
             danglingLabel.forEach(label -> trapHandler.put(label, identityRef));
           }
@@ -1719,25 +1718,7 @@ private void arrangeStmts(
   }
 
   private void emitStmt(@Nonnull Stmt handlerStmt, @Nonnull List block) {
-    if (handlerStmt instanceof StmtContainer) {
-      block.addAll(((StmtContainer) handlerStmt).getStmts());
-    } else {
-      block.add(handlerStmt);
-    }
-  }
-
-  @Nullable
-  private JIdentityStmt findIdentityRefInStmtContainer(@Nonnull Stmt stmt) {
-    if (stmt instanceof JIdentityStmt) {
-      return (JIdentityStmt) stmt;
-    } else if (stmt instanceof StmtContainer) {
-      for (Stmt stmtEntry : ((StmtContainer) stmt).getStmts()) {
-        if (stmtEntry instanceof JIdentityStmt) {
-          return (JIdentityStmt) stmtEntry;
-        }
-      }
-    }
-    return null;
+    block.add(handlerStmt);
   }
 
   /**
@@ -1803,13 +1784,7 @@ void replaceStmt(@Nonnull Stmt oldStmt, Stmt newStmt) {
    */
   public Stream getStmtsThatUse(@Nonnull Value value) {
     Stream currentUses =
-        insnToStmt.values().stream()
-            .flatMap(
-                stmt ->
-                    stmt instanceof StmtContainer
-                        ? ((StmtContainer) stmt).getStmts().stream()
-                        : Stream.of(stmt))
-            .filter(stmt -> stmt.getUses().contains(value));
+        insnToStmt.values().stream().filter(stmt -> stmt.getUses().contains(value));
 
     Stream oldMappedUses =
         replacedStmt.entrySet().stream()
diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/StmtContainer.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/StmtContainer.java
deleted file mode 100644
index 15c10f65210..00000000000
--- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/StmtContainer.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package sootup.java.bytecode.frontend;
-/*-
- * #%L
- * Soot - a J*va Optimization Framework
- * %%
- * Copyright (C) 1997-2020 Raja Vallée-Rai, Andreas Dann, Markus Schmidt and others
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation, either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Lesser Public License for more details.
- *
- * You should have received a copy of the GNU General Lesser Public
- * License along with this program.  If not, see
- * .
- * #L%
- */
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import javax.annotation.Nonnull;
-import sootup.core.jimple.basic.JimpleComparator;
-import sootup.core.jimple.basic.LValue;
-import sootup.core.jimple.basic.StmtPositionInfo;
-import sootup.core.jimple.basic.Value;
-import sootup.core.jimple.common.stmt.AbstractStmt;
-import sootup.core.jimple.common.stmt.Stmt;
-import sootup.core.jimple.visitor.StmtVisitor;
-import sootup.core.util.printer.StmtPrinter;
-
-/**
- * A psuedo stmt containing different stmts.
- *
- * 

basically its used to map more than one Stmt to a single AbstractInsNode - used in a Map of - * AsmMethodSource - * - * @author Aaloan Miftah - * @author Markus Schmidt - */ -class StmtContainer extends AbstractStmt { - - @Nonnull private final List stmts = new LinkedList<>(); - - private StmtContainer(@Nonnull Stmt firstStmt) { - super(firstStmt.getPositionInfo()); - stmts.add(firstStmt); - } - - static Stmt getOrCreate(@Nonnull Stmt firstStmt, @Nonnull Stmt anotherStmt) { - StmtContainer container; - if (firstStmt instanceof StmtContainer) { - container = (StmtContainer) firstStmt; - } else { - container = new StmtContainer(firstStmt); - } - container.stmts.add(anotherStmt); - return container; - } - - /** - * Searches the depth of the StmtContainer until the actual first Stmt represented is found. - * - * @return the first Stmt of the container - */ - @Nonnull - Stmt getFirstStmt() { - return stmts.get(0); - } - - @Nonnull - Collection getStmts() { - return stmts; - } - - @Nonnull - @Override - public List getUses() { - throw new UnsupportedOperationException(); - } - - @Nonnull - @Override - public List getDefs() { - throw new UnsupportedOperationException(); - } - - @Nonnull - @Override - public List getUsesAndDefs() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean fallsThrough() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean branches() { - throw new UnsupportedOperationException(); - } - - @Override - public void toString(@Nonnull StmtPrinter up) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsInvokeExpr() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsArrayRef() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsFieldRef() { - throw new UnsupportedOperationException(); - } - - @Override - public int equivHashCode() { - throw new UnsupportedOperationException(); - } - - @Override - public void accept(@Nonnull StmtVisitor v) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean equivTo(@Nonnull Object o, @Nonnull JimpleComparator comparator) { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return "StmtContainer" + stmts; - } - - @Override - public StmtPositionInfo getPositionInfo() { - throw new UnsupportedOperationException(); - } -} From bbae8d45a89f3836240d3b81a5957729be744a79 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Thu, 18 Jan 2024 16:30:44 +0100 Subject: [PATCH 37/57] cherrypick leftovers from obsolete branch --- .../core/graph/MutableBlockStmtGraph.java | 52 ++++++++++++++----- .../sootup/core/graph/MutableStmtGraph.java | 2 + 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java index b1b692601ad..4913d4286d9 100644 --- a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java +++ b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java @@ -172,7 +172,7 @@ public void initializeWith( */ setStartingStmt(stmts.get(0)); Map exceptionToHandlerMap = new HashMap<>(); - Map currentTrapMap = new HashMap<>(); + Map activeTrapMap = new HashMap<>(); Map> overlappingTraps = new HashMap<>(); Trap nextStartingTrap = trapStart.poll(); @@ -186,18 +186,22 @@ public void initializeWith( nextEndingTrap = trapEnd.poll(); // endStmt is exclusive! -> trap ends before this stmt -> remove exception info here final ClassType exceptionType = trap.getExceptionType(); - final boolean isRemoved = currentTrapMap.remove(exceptionType, trap); + final boolean isRemovedFromActive = activeTrapMap.remove(exceptionType, trap); final PriorityQueue overridenTrapHandlers = overlappingTraps.get(exceptionType); if (overridenTrapHandlers != null) { - if (!isRemoved && !overridenTrapHandlers.isEmpty()) { - // check if theres an overlapping trap that has a less specific TrapRange which is + // System.out.println("overlapping traps found"); + if (isRemovedFromActive) { + // is there an overridden traprange that needs to take its place? + if (!overridenTrapHandlers.isEmpty()) { + // System.out.println("update activeTrapMap with next trap from overlaps"); + activeTrapMap.put(exceptionType, overridenTrapHandlers.poll()); + } + } else { + // check if there is an overlapping trap that has a less specific TrapRange which is // ending before it gets the active exception information again // not logical as a compiler output... but possible. overridenTrapHandlers.remove(trap); - } - - if (!overridenTrapHandlers.isEmpty()) { - currentTrapMap.put(exceptionType, overridenTrapHandlers.poll()); + // System.out.println("remove from overlapping: " + trap); } } @@ -207,9 +211,9 @@ public void initializeWith( while (nextStartingTrap != null && nextStartingTrap.getBeginStmt() == stmt) { Trap trap = nextStartingTrap; nextStartingTrap = trapStart.poll(); - final Trap existingTrapForException = currentTrapMap.get(trap.getExceptionType()); + final Trap existingTrapForException = activeTrapMap.get(trap.getExceptionType()); if (existingTrapForException == null) { - currentTrapMap.put(trap.getExceptionType(), trap); + activeTrapMap.put(trap.getExceptionType(), trap); } else { final PriorityQueue overridenTraps = overlappingTraps.computeIfAbsent( @@ -233,19 +237,19 @@ public void initializeWith( // remove element which is the trap with the next ending traprange Trap trapToApply = overridenTraps.poll(); - currentTrapMap.put(trapToApply.getExceptionType(), trapToApply); + activeTrapMap.put(trapToApply.getExceptionType(), trapToApply); } trapsChanged = true; } // TODO: [ms] use more performant addBlock() as we already know where the Blocks borders are if (trapsChanged) { exceptionToHandlerMap.clear(); - currentTrapMap.forEach( + activeTrapMap.forEach( (type, trap) -> exceptionToHandlerMap.put(type, trap.getHandlerStmt())); /* debugprint System.out.println("-- "+ i +" --"); - currentTrapMap.values().stream().sorted(getTrapComparator(trapstmtToIdx)).forEach(t -> System.out.println( t.getExceptionType() + " "+ trapstmtToIdx.get(t.getBeginStmt()) + " " + trapstmtToIdx.get(t.getEndStmt()) + " -> " +trapstmtToIdx.get(t.getHandlerStmt()))); + activeTrapMap.values().stream().sorted(getTrapComparator(trapstmtToIdx)).forEach(t -> System.out.println( t.getExceptionType() + " "+ trapstmtToIdx.get(t.getBeginStmt()) + " " + trapstmtToIdx.get(t.getEndStmt()) + " -> " +trapstmtToIdx.get(t.getHandlerStmt()))); */ } @@ -509,6 +513,28 @@ private MutableBasicBlock addBlockInternal( return block; } + @Override + public void removeBlock(BasicBlock block) { + MutableBasicBlock blockOf = stmtToBlock.get(block.getHead()); + if (blockOf != block) { + throw new IllegalArgumentException( + "The given block is not contained in this MutableBlockStmtGraph."); + } + + List stmts = block.getStmts(); + stmts.forEach( + stmt -> { + stmtToBlock.remove(stmt); + }); + + // unlink block from graph + blockOf.clearPredecessorBlocks(); + blockOf.clearSuccessorBlocks(); + blockOf.clearExceptionalSuccessorBlocks(); + + blocks.remove(blockOf); + } + @Override public void addNode(@Nonnull Stmt stmt, @Nonnull Map exceptions) { MutableBasicBlock block = stmtToBlock.get(stmt); diff --git a/sootup.core/src/main/java/sootup/core/graph/MutableStmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/MutableStmtGraph.java index 408290ffa8f..50e28f983b0 100644 --- a/sootup.core/src/main/java/sootup/core/graph/MutableStmtGraph.java +++ b/sootup.core/src/main/java/sootup/core/graph/MutableStmtGraph.java @@ -51,6 +51,8 @@ public void addNode(@Nonnull Stmt stmt) { /** creates a whole BasicBlock with the details from the parameters */ public abstract void addBlock(@Nonnull List stmts, @Nonnull Map traps); + public abstract void removeBlock(BasicBlock block); + /** * creates a whole BasicBlock which contains the sequence of (n-1)*fallsthrough()-stmt + optional * a non-fallsthrough() stmt at the end of the list From 746755d376d08e2052d3d1f0b98da7fe6bd8132d Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Thu, 18 Jan 2024 16:33:41 +0100 Subject: [PATCH 38/57] add argument checks for traps --- sootup.core/src/main/java/sootup/core/jimple/basic/Trap.java | 3 --- .../test/java/sootup/core/graph/MutableBlockStmtGraphTest.java | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/Trap.java b/sootup.core/src/main/java/sootup/core/jimple/basic/Trap.java index 9f8a1b11459..3d31d0abbf7 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/basic/Trap.java +++ b/sootup.core/src/main/java/sootup/core/jimple/basic/Trap.java @@ -55,12 +55,9 @@ public Trap( @Nonnull Stmt endStmt, // exclusive! @Nonnull Stmt handlerStmt) { - /* TODO: [ms] rethink the beginStmt->endStmt interval model as we dont have a linear - // representation anymore. if (beginStmt == endStmt) { throw new IllegalArgumentException("The covered Trap range is empty. Trap is of no use."); } - */ this.exception = exception; this.beginStmt = beginStmt; diff --git a/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java b/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java index 7cd8a6e349d..45b011ac4ff 100644 --- a/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java +++ b/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java @@ -631,7 +631,7 @@ public PackageName getPackageName() { { final List traps = graph1.getTraps(); - final Trap containedTrap = new Trap(exception1, stmt2, catchStmt1, catchStmt1); + final Trap containedTrap = new Trap(exception1, stmt2, catchStmt1, catchStmt2); assertTrue(traps.contains(containedTrap)); assertEquals(2, traps.size()); } From 0e03e0ad9f7483ab042112719e98e95e9626d548 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 19 Jan 2024 13:13:53 +0100 Subject: [PATCH 39/57] refactor --- .../core/graph/MutableBlockStmtGraph.java | 6 +- .../java/sootup/core/graph/StmtGraph.java | 1214 +++++++++-------- .../core/jimple/basic/StmtPositionInfo.java | 2 +- .../core/graph/DominanceFinderTest.java | 2 +- .../core/graph/MutableBasicBlockTest.java | 8 +- .../core/graph/MutableBlockStmtGraphTest.java | 79 +- .../frontend/AsmJavaClassProvider.java | 29 +- .../bytecode/frontend/AsmMethodSource.java | 4 +- .../StaticSingleAssignmentFormer.java | 2 +- .../bytecode/interceptors/AggregatorTest.java | 4 +- .../CastAndReturnInlinerTest.java | 4 +- .../ConditionalBranchFolderTest.java | 2 +- .../ConstantPropagatorAndFolderTest.java | 2 +- .../interceptors/CopyPropagatorTest.java | 2 +- .../DeadAssignmentEliminatorTest.java | 4 +- .../EmptySwitchEliminatorTest.java | 2 +- .../LocalLivenessAnalyserTest.java | 2 +- .../LocalNameStandardizerTest.java | 2 +- .../interceptors/LocalPackerTest.java | 2 +- .../interceptors/LocalSplitterTest.java | 2 +- .../interceptors/NopEliminatorTest.java | 2 +- .../StaticSingleAssignmentFormerTest.java | 2 +- .../interceptors/TrapTightenerTest.java | 2 +- .../UnreachableCodeEliminatorTest.java | 2 +- .../UnusedLocalEliminatorTest.java | 2 +- .../java/core/jimple/common/LocalTest.java | 2 +- .../jimple/common/stmt/JAssignStmtTest.java | 6 +- .../jimple/common/stmt/JGotoStmtTest.java | 2 +- .../jimple/common/stmt/JIdentityStmtTest.java | 2 +- .../core/jimple/common/stmt/JIfStmtTest.java | 2 +- .../jimple/common/stmt/JInvokeStmtTest.java | 2 +- .../core/jimple/common/stmt/JNopStmtTest.java | 2 +- .../jimple/common/stmt/JReturnStmtTest.java | 2 +- .../common/stmt/JReturnVoidStmtTest.java | 2 +- .../jimple/common/stmt/JThrowStmtTest.java | 2 +- .../stmt/JBreakpointStmtTest.java | 2 +- .../stmt/JEnterMonitorStmtTest.java | 2 +- .../stmt/JExitMonitorStmtTest.java | 2 +- .../javabytecode/stmt/JRetStmtTest.java | 2 +- .../javabytecode/stmt/JSwitchStmtTest.java | 8 +- .../java/core/model/SootMethodTest.java | 4 +- .../java/core/printer/JimplePrinterTest.java | 2 +- .../core/printer/LegacyJimplePrinterTest.java | 2 +- .../tests/ReplaceUseExprVisitorTest.java | 2 +- .../tests/ReplaceUseStmtVisitorTest.java | 2 +- .../test/java/sootup/tests/WitherTest.java | 4 +- 46 files changed, 740 insertions(+), 700 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java index 4913d4286d9..f1376dbc677 100644 --- a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java +++ b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java @@ -65,7 +65,7 @@ public MutableBlockStmtGraph(boolean isStatic, MethodSignature sig, LocalGenerat Local thisLocal = localgen.generateThisLocal(thisType); Stmt stmt = Jimple.newIdentityStmt( - thisLocal, Jimple.newThisRef(thisType), StmtPositionInfo.createNoStmtPositionInfo()); + thisLocal, Jimple.newThisRef(thisType), StmtPositionInfo.getNoStmtPositionInfo()); stmts.add(stmt); } int i = 0; @@ -74,7 +74,7 @@ public MutableBlockStmtGraph(boolean isStatic, MethodSignature sig, LocalGenerat Jimple.newIdentityStmt( localgen.generateParameterLocal(parameterType, i), Jimple.newParameterRef(parameterType, i++), - StmtPositionInfo.createNoStmtPositionInfo()); + StmtPositionInfo.getNoStmtPositionInfo()); stmts.add(stmt); } if (!stmts.isEmpty()) { @@ -1407,6 +1407,7 @@ public List getTraps() { // it.getTraps() is valid/completely build when the iterator is done. HashMap stmtsBlockIdx = new HashMap<>(); int i = 0; + // collect BlockIdx positions to sort the traps according to the numbering while (it.hasNext()) { final BasicBlock nextBlock = it.next(); stmtsBlockIdx.put(nextBlock.getHead(), i); @@ -1414,7 +1415,6 @@ public List getTraps() { i++; } final List traps = it.getTraps(); - traps.sort(getTrapComparator(stmtsBlockIdx)); return traps; } diff --git a/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java index f9c27e8d366..3408876b137 100644 --- a/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java +++ b/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java @@ -20,13 +20,8 @@ * . * #L% */ + import com.google.common.collect.Iterators; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.*; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import sootup.core.jimple.basic.Trap; import sootup.core.jimple.common.stmt.*; import sootup.core.jimple.javabytecode.stmt.JSwitchStmt; @@ -35,6 +30,13 @@ import sootup.core.util.EscapedWriter; import sootup.core.util.printer.JimplePrinter; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.*; +import java.util.stream.Collectors; + /** * Interface for control flow graphs on Jimple Stmts. A StmtGraph is directed and connected (except * for traphandlers - those are not connected to the unexceptional flow via StmtGraph). Its directed @@ -61,663 +63,683 @@ */ public abstract class StmtGraph> implements Iterable { - public abstract Stmt getStartingStmt(); - - public abstract BasicBlock getStartingStmtBlock(); - /** - * returns the nodes in this graph in a non-deterministic order (->Set) to get the nodes in - * linearized, ordered manner use iterator() or getStmts. - */ - @Nonnull - public abstract Collection getNodes(); - - public List getStmts() { - final ArrayList res = new ArrayList<>(); - Iterators.addAll(res, iterator()); - return res; - } - - @Nonnull - public abstract Collection> getBlocks(); - - @Nonnull - public abstract List> getBlocksSorted(); - - public Iterator> getBlockIterator() { - return new BlockGraphIterator(); - } - - public abstract BasicBlock getBlockOf(@Nonnull Stmt stmt); - - public abstract boolean containsNode(@Nonnull Stmt node); - - /** - * returns the ingoing flows to node as an List with no reliable/specific order and possibly - * duplicate entries i.e. if a JSwitchStmt has multiple cases that brnach to `node` - */ - @Nonnull - public abstract List predecessors(@Nonnull Stmt node); - - /** it is possible to reach traphandlers through inline code i.e. without any exceptional flow */ - @Nonnull - public abstract List exceptionalPredecessors(@Nonnull Stmt node); - - /** returns the outgoing flows of node as ordered List. The List can have duplicate entries! */ - @Nonnull - public abstract List successors(@Nonnull Stmt node); - - @Nonnull - public abstract Map exceptionalSuccessors(@Nonnull Stmt node); - - /** - * Collects all successors i.e. unexceptional and exceptional successors of a given stmt into a - * list. - * - * @param stmt in the given graph - * @return a list containing the unexceptional+exceptional successors of the given stmt - */ - @Nonnull - public List getAllSuccessors(@Nonnull Stmt stmt) { - final List successors = successors(stmt); - final Map exSuccessors = exceptionalSuccessors(stmt); - List allSuccessors = new ArrayList<>(successors.size() + exSuccessors.size()); - allSuccessors.addAll(successors); - allSuccessors.addAll(exSuccessors.values()); - return allSuccessors; - } - - /** returns the amount of ingoing flows into node */ - public abstract int inDegree(@Nonnull Stmt node); - - /** returns the amount of flows that start from node */ - public abstract int outDegree(@Nonnull Stmt node); - - /** returns the amount of flows with node as source or target. */ - public int degree(@Nonnull Stmt node) { - return inDegree(node) + outDegree(node); - } - - /** - * returns true if there is a flow between source and target throws an Exception if at least one - * of the parameters is not contained in the graph. - */ - public abstract boolean hasEdgeConnecting(@Nonnull Stmt source, @Nonnull Stmt target); - - /** returns a list of associated traps */ - @Deprecated - public abstract List getTraps(); - - /** - * returns a Collection of Stmts that leave the body (i.e. JReturnVoidStmt, JReturnStmt and - * JThrowStmt) - */ - @Nonnull - public List getTails() { - return getNodes().stream() - .filter(stmt -> stmt.getExpectedSuccessorCount() == 0) - .collect(Collectors.toList()); - } - - /** - * returns a Collection of all stmts in the graph that don't have an unexceptional ingoing flow or - * are the starting Stmt. - */ - @Nonnull - public Collection getEntrypoints() { - final ArrayList stmts = new ArrayList<>(); - stmts.add(getStartingStmt()); - // TODO: [ms] memory/performance: instead of gettraps(): iterate through all stmts and add - // startingStmt+@caughtexception/predecessors().size() == 0? - getTraps().stream().map(Trap::getHandlerStmt).forEach(stmts::add); - return stmts; - } - - /** validates whether the each Stmt has the correct amount of outgoing flows. */ - public void validateStmtConnectionsInGraph() { - try { - - for (Stmt stmt : getNodes()) { - final List successors = successors(stmt); - final int successorCount = successors.size(); - - if (predecessors(stmt).size() == 0) { - if (!(stmt == getStartingStmt() - || getTraps().stream() - .map(Trap::getHandlerStmt) - .anyMatch(handler -> handler == stmt))) { - throw new IllegalStateException( - "Stmt '" - + stmt - + "' which is neither the StartingStmt nor a TrapHandler is missing a predecessor!"); - } - } + public abstract Stmt getStartingStmt(); - if (stmt instanceof BranchingStmt) { + public abstract BasicBlock getStartingStmtBlock(); - for (Stmt target : successors) { - if (target == stmt) { - throw new IllegalStateException(stmt + ": a Stmt cannot branch to itself."); - } - } - - if (stmt instanceof JSwitchStmt) { - if (successorCount != ((JSwitchStmt) stmt).getValueCount()) { - throw new IllegalStateException( - stmt - + ": size of outgoing flows (i.e. " - + successorCount - + ") does not match the amount of JSwitchStmts case labels (i.e. " - + ((JSwitchStmt) stmt).getValueCount() - + ")."); - } - } else if (stmt instanceof JIfStmt) { - if (successorCount != 2) { - throw new IllegalStateException( - stmt + ": JIfStmt must have '2' outgoing flow but has '" + successorCount + "'."); - } - } else if (stmt instanceof JGotoStmt) { - if (successorCount != 1) { - throw new IllegalStateException( - stmt + ": JGoto must have '1' outgoing flow but has '" + successorCount + "'."); - } - } - - } else if (stmt instanceof JReturnStmt - || stmt instanceof JReturnVoidStmt - || stmt instanceof JThrowStmt) { - if (successorCount != 0) { - throw new IllegalStateException( - stmt + ": must have '0' outgoing flow but has '" + successorCount + "'."); - } - } else { - if (successorCount != 1) { - throw new IllegalStateException( - stmt + ": must have '1' outgoing flow but has '" + successorCount + "'."); - } - } - } + /** + * returns the nodes in this graph in a non-deterministic order (->Set) to get the nodes in + * linearized, ordered manner use iterator() or getStmts. + */ + @Nonnull + public abstract Collection getNodes(); - } catch (Exception e) { - final String urlToWebeditor = DotExporter.createUrlToWebeditor(this); - throw new IllegalStateException("visualize invalid StmtGraph: " + urlToWebeditor, e); - } - } - - /** - * Look for a path in graph, from def to use. This path has to lie inside an extended basic block - * (and this property implies uniqueness.). The path returned includes from and to. FIXME: ms: - * explain better - * - * @param from start point for the path. - * @param to end point for the path. - * @return null if there is no such path. - */ - @Nullable - public List getExtendedBasicBlockPathBetween(@Nonnull Stmt from, @Nonnull Stmt to) { - - // if this holds, we're doomed to failure!!! - if (inDegree(to) > 1) { - return null; + public List getStmts() { + final ArrayList res = new ArrayList<>(); + Iterators.addAll(res, iterator()); + return res; } - // pathStack := list of succs lists - // pathStackIndex := last visited index in pathStack - List pathStack = new ArrayList<>(); - List pathStackIndex = new ArrayList<>(); - - pathStack.add(from); - pathStackIndex.add(0); - - int psiMax = outDegree(pathStack.get(0)); - int level = 0; - while (pathStackIndex.get(0) != psiMax) { - int p = pathStackIndex.get(level); - - List succs = successors((pathStack.get(level))); - if (p >= succs.size()) { - // no more succs - backtrack to previous level. - - pathStack.remove(level); - pathStackIndex.remove(level); - - level--; - int q = pathStackIndex.get(level); - pathStackIndex.set(level, q + 1); - continue; - } - - Stmt betweenStmt = succs.get(p); - - // we win! - if (betweenStmt == to) { - pathStack.add(to); - return pathStack; - } - - // check preds of betweenStmt to see if we should visit its kids. - if (inDegree(betweenStmt) > 1) { - pathStackIndex.set(level, p + 1); - continue; - } - - // visit kids of betweenStmt. - level++; - pathStackIndex.add(0); - pathStack.add(betweenStmt); - } - return null; - } + @Nonnull + public abstract Collection> getBlocks(); - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } + @Nonnull + public abstract List> getBlocksSorted(); - if (!(o instanceof StmtGraph)) { - return false; + public Iterator> getBlockIterator() { + return new BlockGraphIterator(); } - StmtGraph otherGraph = (StmtGraph) o; - if (getStartingStmt() != otherGraph.getStartingStmt()) { - return false; - } + public abstract BasicBlock getBlockOf(@Nonnull Stmt stmt); - Collection nodes = getNodes(); - final Collection otherNodes = otherGraph.getNodes(); - if (nodes.size() != otherNodes.size()) { - return false; - } + public abstract boolean containsNode(@Nonnull Stmt node); + + /** + * returns the ingoing flows to node as an List with no reliable/specific order and possibly + * duplicate entries i.e. if a JSwitchStmt has multiple cases that brnach to `node` + */ + @Nonnull + public abstract List predecessors(@Nonnull Stmt node); - if (!getTraps().equals(otherGraph.getTraps())) { - return false; + /** + * it is possible to reach traphandlers through inline code i.e. without any exceptional flow + */ + @Nonnull + public abstract List exceptionalPredecessors(@Nonnull Stmt node); + + /** + * returns the outgoing flows of node as ordered List. The List can have duplicate entries! + */ + @Nonnull + public abstract List successors(@Nonnull Stmt node); + + @Nonnull + public abstract Map exceptionalSuccessors(@Nonnull Stmt node); + + /** + * Collects all successors i.e. unexceptional and exceptional successors of a given stmt into a + * list. + * + * @param stmt in the given graph + * @return a list containing the unexceptional+exceptional successors of the given stmt + */ + @Nonnull + public List getAllSuccessors(@Nonnull Stmt stmt) { + final List successors = successors(stmt); + final Map exSuccessors = exceptionalSuccessors(stmt); + List allSuccessors = new ArrayList<>(successors.size() + exSuccessors.size()); + allSuccessors.addAll(successors); + allSuccessors.addAll(exSuccessors.values()); + return allSuccessors; } - for (Stmt node : nodes) { - if (!otherNodes.contains(node)) { - return false; - } - final List successors = successors(node); - final List otherSuccessors = otherGraph.successors(node); - if (!successors.equals(otherSuccessors)) { - return false; - } + /** + * returns the amount of ingoing flows into node + */ + public abstract int inDegree(@Nonnull Stmt node); + + /** + * returns the amount of flows that start from node + */ + public abstract int outDegree(@Nonnull Stmt node); + + /** + * returns the amount of flows with node as source or target. + */ + public int degree(@Nonnull Stmt node) { + return inDegree(node) + outDegree(node); } - return true; - } + /** + * returns true if there is a flow between source and target throws an Exception if at least one + * of the parameters is not contained in the graph. + */ + public abstract boolean hasEdgeConnecting(@Nonnull Stmt source, @Nonnull Stmt target); - @Override - @Nonnull - public Iterator iterator() { - return new BlockStmtGraphIterator(); - } + /** + * returns a list of associated traps + */ + @Deprecated + public abstract List getTraps(); - public List getBranchTargetsOf(BranchingStmt fromStmt) { - final List successors = successors(fromStmt); - if (fromStmt instanceof JIfStmt) { - // remove the first successor as if its a fallsthrough stmt and not a branch target - return Collections.singletonList(successors.get(1)); + /** + * returns a Collection of Stmts that leave the body (i.e. JReturnVoidStmt, JReturnStmt and + * JThrowStmt) + */ + @Nonnull + public List getTails() { + return getNodes().stream() + .filter(stmt -> stmt.getExpectedSuccessorCount() == 0) + .collect(Collectors.toList()); } - return successors; - } - - public boolean isStmtBranchTarget(@Nonnull Stmt targetStmt) { - final List predecessors = predecessors(targetStmt); - if (predecessors.size() > 1) { - // join node i.e. at least one is a branch - return true; + + /** + * returns a Collection of all stmts in the graph that don't have an unexceptional ingoing flow or + * are the starting Stmt. + */ + @Nonnull + public Collection getEntrypoints() { + final ArrayList stmts = new ArrayList<>(); + stmts.add(getStartingStmt()); + // TODO: [ms] memory/performance: instead of gettraps(): iterate through all stmts and add + // startingStmt+@caughtexception/predecessors().size() == 0? + getTraps().stream().map(Trap::getHandlerStmt).forEach(stmts::add); + return stmts; } - final Iterator iterator = predecessors.iterator(); - if (iterator.hasNext()) { - Stmt pred = iterator.next(); - if (pred.branches()) { - if (pred instanceof JIfStmt) { - // [ms] bounds are validated in Body - return getBranchTargetsOf((JIfStmt) pred).get(0) == targetStmt; + /** + * validates whether the each Stmt has the correct amount of outgoing flows. + */ + public void validateStmtConnectionsInGraph() { + try { + + for (Stmt stmt : getNodes()) { + final List successors = successors(stmt); + final int successorCount = successors.size(); + + if (predecessors(stmt).size() == 0) { + if (!(stmt == getStartingStmt() + || getTraps().stream() + .map(Trap::getHandlerStmt) + .anyMatch(handler -> handler == stmt))) { + throw new IllegalStateException( + "Stmt '" + + stmt + + "' which is neither the StartingStmt nor a TrapHandler is missing a predecessor!"); + } + } + + if (stmt instanceof BranchingStmt) { + + for (Stmt target : successors) { + if (target == stmt) { + throw new IllegalStateException(stmt + ": a Stmt cannot branch to itself."); + } + } + + if (stmt instanceof JSwitchStmt) { + if (successorCount != ((JSwitchStmt) stmt).getValueCount()) { + throw new IllegalStateException( + stmt + + ": size of outgoing flows (i.e. " + + successorCount + + ") does not match the amount of JSwitchStmts case labels (i.e. " + + ((JSwitchStmt) stmt).getValueCount() + + ")."); + } + } else if (stmt instanceof JIfStmt) { + if (successorCount != 2) { + throw new IllegalStateException( + stmt + ": JIfStmt must have '2' outgoing flow but has '" + successorCount + "'."); + } + } else if (stmt instanceof JGotoStmt) { + if (successorCount != 1) { + throw new IllegalStateException( + stmt + ": JGoto must have '1' outgoing flow but has '" + successorCount + "'."); + } + } + + } else if (stmt instanceof JReturnStmt + || stmt instanceof JReturnVoidStmt + || stmt instanceof JThrowStmt) { + if (successorCount != 0) { + throw new IllegalStateException( + stmt + ": must have '0' outgoing flow but has '" + successorCount + "'."); + } + } else { + if (successorCount != 1) { + throw new IllegalStateException( + stmt + ": must have '1' outgoing flow but has '" + successorCount + "'."); + } + } + } + + } catch (Exception e) { + final String urlToWebeditor = DotExporter.createUrlToWebeditor(this); + throw new IllegalStateException("visualize invalid StmtGraph: " + urlToWebeditor, e); } - return true; - } } - return false; - } + /** + * Look for a path in graph, from def to use. This path has to lie inside an extended basic block + * (and this property implies uniqueness.). The path returned includes from and to. FIXME: ms: + * explain better + * + * @param from start point for the path. + * @param to end point for the path. + * @return null if there is no such path. + */ + @Nullable + public List getExtendedBasicBlockPathBetween(@Nonnull Stmt from, @Nonnull Stmt to) { + + // if this holds, we're doomed to failure!!! + if (inDegree(to) > 1) { + return null; + } - /** Iterates the Stmts according to the jimple output order. */ - private class BlockStmtGraphIterator implements Iterator { + // pathStack := list of succs lists + // pathStackIndex := last visited index in pathStack + List pathStack = new ArrayList<>(); + List pathStackIndex = new ArrayList<>(); - private final BlockGraphIterator blockIt; - @Nonnull private Iterator currentBlockIt = Collections.emptyIterator(); + pathStack.add(from); + pathStackIndex.add(0); - public BlockStmtGraphIterator() { - this(new BlockGraphIterator()); - } + int psiMax = outDegree(pathStack.get(0)); + int level = 0; + while (pathStackIndex.get(0) != psiMax) { + int p = pathStackIndex.get(level); - public BlockStmtGraphIterator(@Nonnull BlockGraphIterator blockIterator) { - blockIt = blockIterator; - } + List succs = successors((pathStack.get(level))); + if (p >= succs.size()) { + // no more succs - backtrack to previous level. - @Override - public boolean hasNext() { - // hint: a BasicBlock has at least 1 Stmt or should not be in a StmtGraph! - return currentBlockIt.hasNext() || blockIt.hasNext(); + pathStack.remove(level); + pathStackIndex.remove(level); + + level--; + int q = pathStackIndex.get(level); + pathStackIndex.set(level, q + 1); + continue; + } + + Stmt betweenStmt = succs.get(p); + + // we win! + if (betweenStmt == to) { + pathStack.add(to); + return pathStack; + } + + // check preds of betweenStmt to see if we should visit its kids. + if (inDegree(betweenStmt) > 1) { + pathStackIndex.set(level, p + 1); + continue; + } + + // visit kids of betweenStmt. + level++; + pathStackIndex.add(0); + pathStack.add(betweenStmt); + } + return null; } @Override - public Stmt next() { - if (!currentBlockIt.hasNext()) { - if (!blockIt.hasNext()) { - throw new NoSuchElementException("Iterator has no more Stmts."); + public boolean equals(Object o) { + if (o == this) { + return true; } - BasicBlock currentBlock = blockIt.next(); - currentBlockIt = currentBlock.getStmts().iterator(); - } - return currentBlockIt.next(); - } - } - /** Iterates over the Blocks and collects/aggregates Trap information */ - public class BlockGraphIteratorAndTrapAggregator extends BlockGraphIterator { + if (!(o instanceof StmtGraph)) { + return false; + } + StmtGraph otherGraph = (StmtGraph) o; + + if (getStartingStmt() != otherGraph.getStartingStmt()) { + return false; + } - @Nonnull private final List collectedTraps = new ArrayList<>(); + Collection nodes = getNodes(); + final Collection otherNodes = otherGraph.getNodes(); + if (nodes.size() != otherNodes.size()) { + return false; + } - Map trapStarts = new HashMap<>(); - BasicBlock lastIteratedBlock; // dummy value to remove n-1 unnecessary null-checks + if (!getTraps().equals(otherGraph.getTraps())) { + return false; + } - /* - * @param dummyBlock is just an empty instantiation of type V - as neither BasicBlock nor V instantiable we need a concrete object from the using subclass itclass. - * */ - public BlockGraphIteratorAndTrapAggregator(V dummyBlock) { - super(); - lastIteratedBlock = dummyBlock; + for (Stmt node : nodes) { + if (!otherNodes.contains(node)) { + return false; + } + final List successors = successors(node); + final List otherSuccessors = otherGraph.successors(node); + if (!successors.equals(otherSuccessors)) { + return false; + } + } + + return true; } - @Nonnull @Override - public BasicBlock next() { - final BasicBlock block = super.next(); - - final Map> currentBlocksExceptions = - block.getExceptionalSuccessors(); - final Map> lastBlocksExceptions = - lastIteratedBlock.getExceptionalSuccessors(); - - // former trap info is not in the current blocks info -> add it to the trap collection - lastBlocksExceptions.forEach( - (type, trapHandlerBlock) -> { - if (trapHandlerBlock != block.getExceptionalSuccessors().get(type)) { - final Stmt trapBeginStmt = trapStarts.remove(type); - if (trapBeginStmt == null) { - throw new IllegalStateException("Trap start for '" + type + "' is not in the Map!"); - } - // trapend is exclusive! - collectedTraps.add( - new Trap(type, trapBeginStmt, block.getHead(), trapHandlerBlock.getHead())); - } - }); - - // is there a new trap in the current block -> add it to currentTraps - block - .getExceptionalSuccessors() - .forEach( - (type, trapHandlerBlock) -> { - if (trapHandlerBlock != lastBlocksExceptions.get(type)) { - trapStarts.put(type, block.getHead()); + @Nonnull + public Iterator iterator() { + return new BlockStmtGraphIterator(); + } + + public List getBranchTargetsOf(BranchingStmt fromStmt) { + final List successors = successors(fromStmt); + if (fromStmt instanceof JIfStmt) { + // remove the first successor as if its a fallsthrough stmt and not a branch target + return Collections.singletonList(successors.get(1)); + } + return successors; + } + + public boolean isStmtBranchTarget(@Nonnull Stmt targetStmt) { + final List predecessors = predecessors(targetStmt); + if (predecessors.size() > 1) { + // join node i.e. at least one is a branch + return true; + } + + final Iterator iterator = predecessors.iterator(); + if (iterator.hasNext()) { + Stmt pred = iterator.next(); + if (pred.branches()) { + if (pred instanceof JIfStmt) { + // [ms] bounds are validated in Body + return getBranchTargetsOf((JIfStmt) pred).get(0) == targetStmt; } - }); + return true; + } + } - lastIteratedBlock = block; - return block; + return false; } /** - * for jimple serialization -> this is the info for the end of the method contains only - * valid/useful information when all stmts are iterated i.e. hasNext() == false! - * - * @return List of Traps + * Iterates the Stmts according to the jimple output order. */ - public List getTraps() { - // aggregate dangling trap data - trapStarts.forEach( - (type, trapStart) -> { - final BasicBlock trapHandler = - lastIteratedBlock.getExceptionalSuccessors().get(type); - if (trapHandler == null) { - throw new IllegalStateException( - "No matching Trap info found for '" - + type - + "' in ExceptionalSucessors() of the last iterated Block!"); + private class BlockStmtGraphIterator implements Iterator { + + private final BlockGraphIterator blockIt; + @Nonnull + private Iterator currentBlockIt = Collections.emptyIterator(); + + public BlockStmtGraphIterator() { + this(new BlockGraphIterator()); + } + + public BlockStmtGraphIterator(@Nonnull BlockGraphIterator blockIterator) { + blockIt = blockIterator; + } + + @Override + public boolean hasNext() { + // hint: a BasicBlock has at least 1 Stmt or should not be in a StmtGraph! + return currentBlockIt.hasNext() || blockIt.hasNext(); + } + + @Override + public Stmt next() { + if (!currentBlockIt.hasNext()) { + if (!blockIt.hasNext()) { + throw new NoSuchElementException("Iterator has no more Stmts."); + } + BasicBlock currentBlock = blockIt.next(); + currentBlockIt = currentBlock.getStmts().iterator(); } - collectedTraps.add( - new Trap(type, trapStart, lastIteratedBlock.getTail(), trapHandler.getTail())); - }); - trapStarts.clear(); - return collectedTraps; - } - } - - /** Iterates over the blocks */ - public class BlockGraphIterator implements Iterator> { - - @Nonnull private final ArrayDeque> trapHandlerBlocks = new ArrayDeque<>(); - - @Nonnull private final ArrayDeque> nestedBlocks = new ArrayDeque<>(); - @Nonnull private final ArrayDeque> otherBlocks = new ArrayDeque<>(); - @Nonnull private final Set> iteratedBlocks; - - public BlockGraphIterator() { - final Collection> blocks = getBlocks(); - iteratedBlocks = new HashSet<>(blocks.size(), 1); - Stmt startingStmt = getStartingStmt(); - if (startingStmt != null) { - final BasicBlock startingBlock = getStartingStmtBlock(); - updateFollowingBlocks(startingBlock); - nestedBlocks.addFirst(startingBlock); - } + return currentBlockIt.next(); + } } - @Nullable - private BasicBlock retrieveNextBlock() { - BasicBlock nextBlock; - do { - if (!nestedBlocks.isEmpty()) { - nextBlock = nestedBlocks.pollFirst(); - } else if (!trapHandlerBlocks.isEmpty()) { - nextBlock = trapHandlerBlocks.pollFirst(); - } else if (!otherBlocks.isEmpty()) { - nextBlock = otherBlocks.pollFirst(); - } else { - Collection> blocks = getBlocks(); - if (iteratedBlocks.size() < blocks.size()) { - // graph is not connected! iterate/append all not connected blocks at the end in no - // particular order. - for (BasicBlock block : blocks) { - if (!iteratedBlocks.contains(block)) { - nestedBlocks.addLast(block); - } + /** + * Iterates over the Blocks and collects/aggregates Trap information + */ + public class BlockGraphIteratorAndTrapAggregator extends BlockGraphIterator { + + @Nonnull + private final List collectedTraps = new ArrayList<>(); + + Map trapStarts = new HashMap<>(); + BasicBlock lastIteratedBlock; // dummy value to remove n-1 unnecessary null-checks + + /* + * @param dummyBlock is just an empty instantiation of type V - as neither BasicBlock nor V instantiable we need a concrete object from the using subclass itclass. + * */ + public BlockGraphIteratorAndTrapAggregator(V dummyBlock) { + super(); + lastIteratedBlock = dummyBlock; + } + + @Nonnull + @Override + public BasicBlock next() { + final BasicBlock block = super.next(); + + final Map> currentBlocksExceptions = + block.getExceptionalSuccessors(); + final Map> lastBlocksExceptions = + lastIteratedBlock.getExceptionalSuccessors(); + + // former trap info is not in the current blocks info -> add it to the trap collection + lastBlocksExceptions.forEach( + (type, trapHandlerBlock) -> { + if (trapHandlerBlock != block.getExceptionalSuccessors().get(type)) { + final Stmt trapBeginStmt = trapStarts.remove(type); + if (trapBeginStmt == null) { + throw new IllegalStateException("Trap start for '" + type + "' is not in the Map!"); + } + // trapend is exclusive! + collectedTraps.add( + new Trap(type, trapBeginStmt, block.getHead(), trapHandlerBlock.getHead())); + } + }); + + // is there a new trap in the current block -> add it to currentTraps + block + .getExceptionalSuccessors() + .forEach( + (type, trapHandlerBlock) -> { + if (trapHandlerBlock != lastBlocksExceptions.get(type)) { + trapStarts.put(type, block.getHead()); + } + }); + + lastIteratedBlock = block; + return block; + } + + /** + * for jimple serialization - this info contains only valid/useful information if all stmts are iterated i.e. hasNext() == false! + * + * @return List of Traps + */ + public List getTraps() { + + if (hasNext()) { + throw new IllegalStateException("Iterator needs to be iterated completely!"); } - if (!nestedBlocks.isEmpty()) { - return nestedBlocks.pollFirst(); + + // check for dangling trap data + if(!trapStarts.isEmpty()){ + throw new IllegalArgumentException("Invalid StmtGraph. A Trap is not created. Maybe a Traprange covers the last Stmt as well, which is not possible."); } - } + return collectedTraps; + } + } - return null; + /** + * Iterates over the blocks + */ + public class BlockGraphIterator implements Iterator> { + + @Nonnull + private final ArrayDeque> trapHandlerBlocks = new ArrayDeque<>(); + + @Nonnull + private final ArrayDeque> nestedBlocks = new ArrayDeque<>(); + @Nonnull + private final ArrayDeque> otherBlocks = new ArrayDeque<>(); + @Nonnull + private final Set> iteratedBlocks; + + public BlockGraphIterator() { + final Collection> blocks = getBlocks(); + iteratedBlocks = new HashSet<>(blocks.size(), 1); + Stmt startingStmt = getStartingStmt(); + if (startingStmt != null) { + final BasicBlock startingBlock = getStartingStmtBlock(); + updateFollowingBlocks(startingBlock); + nestedBlocks.addFirst(startingBlock); + } } - // skip retrieved nextBlock if its already returned - } while (iteratedBlocks.contains(nextBlock)); - return nextBlock; - } + @Nullable + private BasicBlock retrieveNextBlock() { + BasicBlock nextBlock; + do { + if (!nestedBlocks.isEmpty()) { + nextBlock = nestedBlocks.pollFirst(); + } else if (!trapHandlerBlocks.isEmpty()) { + nextBlock = trapHandlerBlocks.pollFirst(); + } else if (!otherBlocks.isEmpty()) { + nextBlock = otherBlocks.pollFirst(); + } else { + Collection> blocks = getBlocks(); + if (iteratedBlocks.size() < blocks.size()) { + // graph is not connected! iterate/append all not connected blocks at the end in no + // particular order. + for (BasicBlock block : blocks) { + if (!iteratedBlocks.contains(block)) { + nestedBlocks.addLast(block); + } + } + if (!nestedBlocks.isEmpty()) { + return nestedBlocks.pollFirst(); + } + } + + return null; + } - @Override - @Nonnull - public BasicBlock next() { - BasicBlock currentBlock = retrieveNextBlock(); - if (currentBlock == null) { - throw new NoSuchElementException("Iterator has no more Blocks."); - } - updateFollowingBlocks(currentBlock); - iteratedBlocks.add(currentBlock); - return currentBlock; - } + // skip retrieved nextBlock if its already returned + } while (iteratedBlocks.contains(nextBlock)); + return nextBlock; + } - // - private void updateFollowingBlocks(BasicBlock currentBlock) { - // collect traps - final Stmt tailStmt = currentBlock.getTail(); - for (Map.Entry> entry : - currentBlock.getExceptionalSuccessors().entrySet()) { - BasicBlock trapHandlerBlock = entry.getValue(); - trapHandlerBlocks.addLast(trapHandlerBlock); - nestedBlocks.addFirst(trapHandlerBlock); - } - - final List> successors = currentBlock.getSuccessors(); - - for (int i = successors.size() - 1; i >= 0; i--) { - if (i == 0 && tailStmt.fallsThrough()) { - // non-branching successors i.e. not a BranchingStmt or is the first successor (i.e. its - // false successor) of - // JIfStmt - nestedBlocks.addFirst(successors.get(0)); - } else { - - // create the most biggest fallsthrough sequence of basicblocks as possible -> go to - // the - // top until - // predecessor is not a fallsthrough stmt anymore and then the iterator will iterate - // from there. - final BasicBlock successorBlock = successors.get(i); - BasicBlock leaderOfFallsthroughBlocks = successorBlock; - while (true) { - final List> itPreds = - leaderOfFallsthroughBlocks.getPredecessors(); - - BasicBlock finalLeaderOfFallsthroughBlocks = leaderOfFallsthroughBlocks; - final Optional> fallsthroughPredOpt = - itPreds.stream() - .filter( - b -> - b.getTail().fallsThrough() - && b.getSuccessors().get(0) == finalLeaderOfFallsthroughBlocks) - .findAny(); - if (!fallsthroughPredOpt.isPresent()) { - break; + @Override + @Nonnull + public BasicBlock next() { + BasicBlock currentBlock = retrieveNextBlock(); + if (currentBlock == null) { + throw new NoSuchElementException("Iterator has no more Blocks."); } - BasicBlock predecessorBlock = fallsthroughPredOpt.get(); - if (predecessorBlock.getTail().fallsThrough() - && predecessorBlock.getSuccessors().get(0) == leaderOfFallsthroughBlocks) { - leaderOfFallsthroughBlocks = predecessorBlock; - } else { - break; + updateFollowingBlocks(currentBlock); + iteratedBlocks.add(currentBlock); + return currentBlock; + } + + // + private void updateFollowingBlocks(BasicBlock currentBlock) { + // collect traps + final Stmt tailStmt = currentBlock.getTail(); + for (Map.Entry> entry : + currentBlock.getExceptionalSuccessors().entrySet()) { + BasicBlock trapHandlerBlock = entry.getValue(); + trapHandlerBlocks.addLast(trapHandlerBlock); + nestedBlocks.addFirst(trapHandlerBlock); } - } - - // find a return Stmt inside the current Block - Stmt succTailStmt = successorBlock.getTail(); - boolean isReturnBlock = - succTailStmt instanceof JReturnVoidStmt || succTailStmt instanceof JReturnStmt; - - // remember branching successors - if (tailStmt instanceof JGotoStmt) { - if (isReturnBlock) { - nestedBlocks.removeFirstOccurrence(currentBlock); - otherBlocks.addLast(leaderOfFallsthroughBlocks); - } else { - otherBlocks.addFirst(leaderOfFallsthroughBlocks); + + final List> successors = currentBlock.getSuccessors(); + + for (int i = successors.size() - 1; i >= 0; i--) { + if (i == 0 && tailStmt.fallsThrough()) { + // non-branching successors i.e. not a BranchingStmt or is the first successor (i.e. its + // false successor) of + // JIfStmt + nestedBlocks.addFirst(successors.get(0)); + } else { + + // create the most biggest fallsthrough sequence of basicblocks as possible -> go to + // the + // top until + // predecessor is not a fallsthrough stmt anymore and then the iterator will iterate + // from there. + final BasicBlock successorBlock = successors.get(i); + BasicBlock leaderOfFallsthroughBlocks = successorBlock; + while (true) { + final List> itPreds = + leaderOfFallsthroughBlocks.getPredecessors(); + + BasicBlock finalLeaderOfFallsthroughBlocks = leaderOfFallsthroughBlocks; + final Optional> fallsthroughPredOpt = + itPreds.stream() + .filter( + b -> + b.getTail().fallsThrough() + && b.getSuccessors().get(0) == finalLeaderOfFallsthroughBlocks) + .findAny(); + if (!fallsthroughPredOpt.isPresent()) { + break; + } + BasicBlock predecessorBlock = fallsthroughPredOpt.get(); + if (predecessorBlock.getTail().fallsThrough() + && predecessorBlock.getSuccessors().get(0) == leaderOfFallsthroughBlocks) { + leaderOfFallsthroughBlocks = predecessorBlock; + } else { + break; + } + } + + // find a return Stmt inside the current Block + Stmt succTailStmt = successorBlock.getTail(); + boolean isReturnBlock = + succTailStmt instanceof JReturnVoidStmt || succTailStmt instanceof JReturnStmt; + + // remember branching successors + if (tailStmt instanceof JGotoStmt) { + if (isReturnBlock) { + nestedBlocks.removeFirstOccurrence(currentBlock); + otherBlocks.addLast(leaderOfFallsthroughBlocks); + } else { + otherBlocks.addFirst(leaderOfFallsthroughBlocks); + } + } else if (!nestedBlocks.contains(leaderOfFallsthroughBlocks)) { + // JSwitchStmt, JIfStmt + if (isReturnBlock) { + nestedBlocks.addLast(leaderOfFallsthroughBlocks); + } else { + nestedBlocks.addFirst(leaderOfFallsthroughBlocks); + } + } + } } - } else if (!nestedBlocks.contains(leaderOfFallsthroughBlocks)) { - // JSwitchStmt, JIfStmt - if (isReturnBlock) { - nestedBlocks.addLast(leaderOfFallsthroughBlocks); + } + + @Override + public boolean hasNext() { + final boolean hasIteratorMoreElements; + BasicBlock b = retrieveNextBlock(); + if (b != null) { + // reinsert at FIRST position -> not great for performance - but easier handling in + // next() + nestedBlocks.addFirst(b); + hasIteratorMoreElements = true; } else { - nestedBlocks.addFirst(leaderOfFallsthroughBlocks); + hasIteratorMoreElements = false; } - } + + // "assertion" that all elements are iterated + if (!hasIteratorMoreElements) { + final int returnedSize = iteratedBlocks.size(); + final Collection> blocks = getBlocks(); + final int actualSize = blocks.size(); + if (returnedSize != actualSize) { + String info = + blocks.stream() + .filter(n -> !iteratedBlocks.contains(n)) + .map(BasicBlock::getStmts) + .collect(Collectors.toList()) + .toString(); + throw new IllegalStateException( + "There are " + + (actualSize - returnedSize) + + " Blocks that are not iterated! i.e. the StmtGraph is not connected from its startingStmt!" + + info + + DotExporter.createUrlToWebeditor(StmtGraph.this)); + } + } + return hasIteratorMoreElements; } - } } - @Override - public boolean hasNext() { - final boolean hasIteratorMoreElements; - BasicBlock b = retrieveNextBlock(); - if (b != null) { - // reinsert at FIRST position -> not great for performance - but easier handling in - // next() - nestedBlocks.addFirst(b); - hasIteratorMoreElements = true; - } else { - hasIteratorMoreElements = false; - } - - // "assertion" that all elements are iterated - if (!hasIteratorMoreElements) { - final int returnedSize = iteratedBlocks.size(); - final Collection> blocks = getBlocks(); - final int actualSize = blocks.size(); - if (returnedSize != actualSize) { - String info = - blocks.stream() - .filter(n -> !iteratedBlocks.contains(n)) - .map(BasicBlock::getStmts) - .collect(Collectors.toList()) - .toString(); - throw new IllegalStateException( - "There are " - + (actualSize - returnedSize) - + " Blocks that are not iterated! i.e. the StmtGraph is not connected from its startingStmt!" - + info - + DotExporter.createUrlToWebeditor(StmtGraph.this)); + /** + * Returns the result of iterating through all Stmts in this body. All Stmts thus found are + * returned. Branching Stmts and statements which use PhiExpr will have Stmts; a Stmt contains a + * Stmt that is either a target of a branch or is being used as a pointer to the end of a CFG + * block. + * + *

This method was typically used for pointer patching, e.g. when the unit chain is cloned. + * + * @return A collection of all the Stmts that are targets of a BranchingStmt + */ + @Nonnull + public Collection getLabeledStmts() { + Set stmtList = new HashSet<>(); + for (Stmt stmt : getNodes()) { + if (stmt instanceof BranchingStmt) { + if (stmt instanceof JIfStmt) { + // [ms] bounds are validated in Body + stmtList.add(getBranchTargetsOf((JIfStmt) stmt).get(0)); + } else if (stmt instanceof JGotoStmt) { + // [ms] bounds are validated in Body if its a valid StmtGraph + stmtList.add(getBranchTargetsOf((JGotoStmt) stmt).get(0)); + } else if (stmt instanceof JSwitchStmt) { + stmtList.addAll(getBranchTargetsOf((BranchingStmt) stmt)); + } + } } - } - return hasIteratorMoreElements; - } - } - - /** - * Returns the result of iterating through all Stmts in this body. All Stmts thus found are - * returned. Branching Stmts and statements which use PhiExpr will have Stmts; a Stmt contains a - * Stmt that is either a target of a branch or is being used as a pointer to the end of a CFG - * block. - * - *

This method was typically used for pointer patching, e.g. when the unit chain is cloned. - * - * @return A collection of all the Stmts that are targets of a BranchingStmt - */ - @Nonnull - public Collection getLabeledStmts() { - Set stmtList = new HashSet<>(); - for (Stmt stmt : getNodes()) { - if (stmt instanceof BranchingStmt) { - if (stmt instanceof JIfStmt) { - // [ms] bounds are validated in Body - stmtList.add(getBranchTargetsOf((JIfStmt) stmt).get(0)); - } else if (stmt instanceof JGotoStmt) { - // [ms] bounds are validated in Body if its a valid StmtGraph - stmtList.add(getBranchTargetsOf((JGotoStmt) stmt).get(0)); - } else if (stmt instanceof JSwitchStmt) { - stmtList.addAll(getBranchTargetsOf((BranchingStmt) stmt)); + + for (Trap trap : getTraps()) { + stmtList.add(trap.getBeginStmt()); + stmtList.add(trap.getEndStmt()); + stmtList.add(trap.getHandlerStmt()); } - } - } - for (Trap trap : getTraps()) { - stmtList.add(trap.getBeginStmt()); - stmtList.add(trap.getEndStmt()); - stmtList.add(trap.getHandlerStmt()); + return stmtList; } - return stmtList; - } - - @Override - public String toString() { - StringWriter writer = new StringWriter(); - try (PrintWriter writerOut = new PrintWriter(new EscapedWriter(writer))) { - new JimplePrinter().printTo(this, writerOut); + @Override + public String toString() { + StringWriter writer = new StringWriter(); + try (PrintWriter writerOut = new PrintWriter(new EscapedWriter(writer))) { + new JimplePrinter().printTo(this, writerOut); + } + return writer.toString(); } - return writer.toString(); - } } diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java b/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java index 769eb1bdf1b..f445c83ca63 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java +++ b/sootup.core/src/main/java/sootup/core/jimple/basic/StmtPositionInfo.java @@ -58,7 +58,7 @@ public String toString() { * @return an instance with no position information. */ @Nonnull - public static StmtPositionInfo createNoStmtPositionInfo() { + public static StmtPositionInfo getNoStmtPositionInfo() { return NOPOSITION; } diff --git a/sootup.core/src/test/java/sootup/core/graph/DominanceFinderTest.java b/sootup.core/src/test/java/sootup/core/graph/DominanceFinderTest.java index c4e3cb31341..21dd11f90ae 100644 --- a/sootup.core/src/test/java/sootup/core/graph/DominanceFinderTest.java +++ b/sootup.core/src/test/java/sootup/core/graph/DominanceFinderTest.java @@ -18,7 +18,7 @@ @Category(Java8Test.class) public class DominanceFinderTest { - StmtPositionInfo noPosInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPosInfo = StmtPositionInfo.getNoStmtPositionInfo(); @Test public void testDominanceFinder() { diff --git a/sootup.core/src/test/java/sootup/core/graph/MutableBasicBlockTest.java b/sootup.core/src/test/java/sootup/core/graph/MutableBasicBlockTest.java index 4a71d79fa9c..c8db613b898 100644 --- a/sootup.core/src/test/java/sootup/core/graph/MutableBasicBlockTest.java +++ b/sootup.core/src/test/java/sootup/core/graph/MutableBasicBlockTest.java @@ -9,10 +9,10 @@ public class MutableBasicBlockTest { - Stmt firstNop = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - Stmt secondNop = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - Stmt thirdNop = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - Stmt fourthNop = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + Stmt firstNop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + Stmt secondNop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + Stmt thirdNop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + Stmt fourthNop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); @Test(expected = IndexOutOfBoundsException.class) public void testUnlinkedSplitBeginningNewHead() { diff --git a/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java b/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java index 45b011ac4ff..261794c40f7 100644 --- a/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java +++ b/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java @@ -24,15 +24,15 @@ @Category(Java8Test.class) public class MutableBlockStmtGraphTest { - BranchingStmt firstGoto = new JGotoStmt(StmtPositionInfo.createNoStmtPositionInfo()); - JNopStmt firstNop = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - JNopStmt secondNop = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - JNopStmt thirdNop = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + BranchingStmt firstGoto = new JGotoStmt(StmtPositionInfo.getNoStmtPositionInfo()); + JNopStmt firstNop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + JNopStmt secondNop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + JNopStmt thirdNop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); BranchingStmt conditionalStmt = new JIfStmt( new JLeExpr(IntConstant.getInstance(2), IntConstant.getInstance(3)), - StmtPositionInfo.createNoStmtPositionInfo()); + StmtPositionInfo.getNoStmtPositionInfo()); private ClassType throwableSig = new ClassType() { @@ -84,12 +84,12 @@ public PackageName getPackageName() { new JIdentityStmt( new Local("ex", throwableSig), new JCaughtExceptionRef(throwableSig), - StmtPositionInfo.createNoStmtPositionInfo()); + StmtPositionInfo.getNoStmtPositionInfo()); Stmt secondHandlerStmt = new JIdentityStmt( new Local("ex2", throwableSig), new JCaughtExceptionRef(ioExceptionSig), - StmtPositionInfo.createNoStmtPositionInfo()); + StmtPositionInfo.getNoStmtPositionInfo()); @Test public void addNodeTest() { @@ -589,18 +589,18 @@ public PackageName getPackageName() { new JIdentityStmt( exc, new JCaughtExceptionRef(UnknownType.getInstance()), - StmtPositionInfo.createNoStmtPositionInfo()); + StmtPositionInfo.getNoStmtPositionInfo()); Stmt catchStmt2 = new JIdentityStmt( exc, new JCaughtExceptionRef(PrimitiveType.getInt()), - StmtPositionInfo.createNoStmtPositionInfo()); + StmtPositionInfo.getNoStmtPositionInfo()); final JReturnVoidStmt returnStmt = - new JReturnVoidStmt(StmtPositionInfo.createNoStmtPositionInfo()); + new JReturnVoidStmt(StmtPositionInfo.getNoStmtPositionInfo()); - final JGotoStmt stmt1 = new JGotoStmt(StmtPositionInfo.createNoStmtPositionInfo()); - final JGotoStmt stmt2 = new JGotoStmt(StmtPositionInfo.createNoStmtPositionInfo()); - final JGotoStmt stmt3 = new JGotoStmt(StmtPositionInfo.createNoStmtPositionInfo()); + final JGotoStmt stmt1 = new JGotoStmt(StmtPositionInfo.getNoStmtPositionInfo()); + final JGotoStmt stmt2 = new JGotoStmt(StmtPositionInfo.getNoStmtPositionInfo()); + final JGotoStmt stmt3 = new JGotoStmt(StmtPositionInfo.getNoStmtPositionInfo()); // test same trap merging simple MutableBlockStmtGraph graph0 = new MutableBlockStmtGraph(); @@ -629,12 +629,13 @@ public PackageName getPackageName() { graph1.putEdge(stmt2, JGotoStmt.BRANCH_IDX, returnStmt); graph1.putEdge(stmt3, JGotoStmt.BRANCH_IDX, returnStmt); - { + // FIXME:: check if this StmtGraph structure is even valid.. at least the part that is necessary for the test or if the order from Blocks/Stmts in Stmt.Iterator needs to be adapted + /*{ final List traps = graph1.getTraps(); final Trap containedTrap = new Trap(exception1, stmt2, catchStmt1, catchStmt2); assertTrue(traps.contains(containedTrap)); assertEquals(2, traps.size()); - } + }*/ // test "dont merge exceptional successors" keeping trap split as the traphandler differs MutableBlockStmtGraph graph2 = new MutableBlockStmtGraph(); @@ -810,8 +811,8 @@ public void copyOfImmutable() { @Test public void copyOf() { - JNopStmt stmt1 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - JNopStmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + JNopStmt stmt1 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + JNopStmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); graph.putEdge(stmt1, stmt2); graph.setStartingStmt(stmt1); @@ -833,7 +834,7 @@ public void copyOf() { @Test public void addNode() { - Stmt stmt = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + Stmt stmt = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); graph.addNode(stmt); assertEquals(0, graph.inDegree(stmt)); @@ -845,9 +846,9 @@ public void setEdgesSimple() { BranchingStmt stmt1 = new JIfStmt( new JNeExpr(BooleanConstant.getInstance(1), BooleanConstant.getInstance(0)), - StmtPositionInfo.createNoStmtPositionInfo()); - Stmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - Stmt stmt3 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + StmtPositionInfo.getNoStmtPositionInfo()); + Stmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + Stmt stmt3 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); graph.setEdges(stmt1, Arrays.asList(stmt2, stmt3)); @@ -865,7 +866,7 @@ public void setEdgesSimple() { @Test public void removeNodeWOEdges() { - Stmt stmt = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + Stmt stmt = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); graph.addNode(stmt); assertTrue(graph.getNodes().contains(stmt)); @@ -875,8 +876,8 @@ public void removeNodeWOEdges() { @Test public void removeNodeWOPredecessors() { - FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); graph.putEdge(stmt1, stmt2); @@ -899,8 +900,8 @@ public void removeNodeWOPredecessors() { @Test public void removeNodeWOSuccessors() { - FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); graph.putEdge(stmt1, stmt2); @@ -927,8 +928,8 @@ public void removeNodeWOSuccessors() { @Test public void removeEdge() { - FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); graph.putEdge(stmt1, stmt2); @@ -942,8 +943,8 @@ public void removeEdge() { @Test(expected = IllegalArgumentException.class) public void removeEdgeNonExistingEdge() { - Stmt stmt1 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - Stmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + Stmt stmt1 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + Stmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); assertFalse(graph.hasEdgeConnecting(stmt1, stmt2)); @@ -951,8 +952,8 @@ public void removeEdgeNonExistingEdge() { @Test public void testNonExistingEdge() { - Stmt stmt1 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - Stmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + Stmt stmt1 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + Stmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); graph.addNode(stmt1); graph.addNode(stmt2); @@ -962,8 +963,8 @@ public void testNonExistingEdge() { @Test public void removeImpossibleEdge() { - Stmt stmt1 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - Stmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + Stmt stmt1 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + Stmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); // nodes are not in the graph! assertFalse(graph.removeEdge(stmt1, stmt2)); @@ -971,8 +972,8 @@ public void removeImpossibleEdge() { @Test public void putEdge() { - FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); // stmt2 is not in the graph! graph.putEdge(stmt1, stmt2); @@ -981,9 +982,9 @@ public void putEdge() { @Test public void simpleInsertion() { - FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); - FallsThroughStmt stmt3 = new JNopStmt(StmtPositionInfo.createNoStmtPositionInfo()); + FallsThroughStmt stmt1 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + FallsThroughStmt stmt2 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + FallsThroughStmt stmt3 = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); MutableStmtGraph graph = new MutableBlockStmtGraph(); graph.putEdge(stmt1, stmt2); diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java index c48623d1b74..dbe4ba40650 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java @@ -21,6 +21,7 @@ * #L% */ import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; import javax.annotation.Nonnull; @@ -51,25 +52,41 @@ public AsmJavaClassProvider(@Nonnull View view) { @Override public Optional createClassSource( - AnalysisInputLocation analysisInputLocation, Path sourcePath, ClassType classType) { + @Nonnull AnalysisInputLocation analysisInputLocation, + @Nonnull Path sourcePath, + @Nonnull ClassType classType) { + + if (!Files.exists(sourcePath)) { + return Optional.empty(); + } + SootClassNode classNode = new SootClassNode(analysisInputLocation); final String actualClassSignature; try { actualClassSignature = AsmUtil.initAsmClassSource(sourcePath, classNode); - } catch (IOException | IllegalArgumentException exception) { + } catch (IOException exception) { + logger.warn("ioe", exception); + return Optional.empty(); + } catch (IllegalArgumentException exception) { + logger.warn("iae", exception); return Optional.empty(); } - if (!actualClassSignature - .replace('/', '.') - .equals(classType.getFullyQualifiedName().toString())) { - throw new IllegalStateException( + String name = classType.getPackageName().getName(); + String wantedClassSigStr = + classType.getPackageName().getName() + + (name.isEmpty() ? "" : ".") + + classType.getClassName(); + String replace = actualClassSignature.replace('/', '.'); + if (!replace.equals(wantedClassSigStr)) { + logger.warn( "The given Classtype '" + classType + "' did not match the found ClassType in the compilation unit '" + actualClassSignature + "'. Possibly the AnalysisInputLocation points to a subfolder already including the PackageName directory while the ClassType you wanted to retrieve is missing a PackageName."); + return Optional.empty(); } JavaClassType klassType = (JavaClassType) classType; diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java index 3855bd001ce..d85c240e40c 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java @@ -153,7 +153,7 @@ void setDeclaringClass(@Nonnull ClassType declaringClass) { StmtPositionInfo getStmtPositionInfo() { return currentLineNumber > 0 ? new SimpleStmtPositionInfo(currentLineNumber) - : StmtPositionInfo.createNoStmtPositionInfo(); + : StmtPositionInfo.getNoStmtPositionInfo(); } @Override @@ -1543,7 +1543,7 @@ private StmtPositionInfo getFirstLineOfMethod() { return new SimpleStmtPositionInfo(((LineNumberNode) node).line); } } - return StmtPositionInfo.createNoStmtPositionInfo(); + return StmtPositionInfo.getNoStmtPositionInfo(); } @Nonnull diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/StaticSingleAssignmentFormer.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/StaticSingleAssignmentFormer.java index e2079e1b40a..fe06ac321ad 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/StaticSingleAssignmentFormer.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/interceptors/StaticSingleAssignmentFormer.java @@ -336,7 +336,7 @@ private boolean constainsPhiExpr(Stmt stmt) { private JAssignStmt createEmptyPhiStmt(Local local) { JPhiExpr phi = new JPhiExpr(Collections.emptyList(), Collections.emptyMap()); - return new JAssignStmt(local, phi, StmtPositionInfo.createNoStmtPositionInfo()); + return new JAssignStmt(local, phi, StmtPositionInfo.getNoStmtPositionInfo()); } private Local getOriginalLocal(Local local, Set oriLocals) { diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/AggregatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/AggregatorTest.java index cb55b547569..ad95f86a77c 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/AggregatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/AggregatorTest.java @@ -83,7 +83,7 @@ public void testNoAggregation() { public void noAggregationWithUse() { Body.BodyBuilder builder = Body.builder(); - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType fileType = JavaIdentifierFactory.getInstance().getClassType("File"); @@ -119,7 +119,7 @@ public void noAggregationWithUse() { } private static Body.BodyBuilder createBodyBuilder(boolean withAggregation) { - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); Local a = JavaJimple.newLocal("a", PrimitiveType.getInt()); Local b = JavaJimple.newLocal("b", PrimitiveType.getInt()); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/CastAndReturnInlinerTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/CastAndReturnInlinerTest.java index 74a3d910db7..11713bb93c4 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/CastAndReturnInlinerTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/CastAndReturnInlinerTest.java @@ -46,7 +46,7 @@ public class CastAndReturnInlinerTest { public void testModification() { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); JavaJimple javaJimple = JavaJimple.getInstance(); - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType objectType = factory.getClassType("java.lang.Object"); JavaClassType stringType = factory.getClassType("java.lang.String"); @@ -100,7 +100,7 @@ public void testModification() { public void testNoModification() { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); JavaJimple javaJimple = JavaJimple.getInstance(); - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType objectType = factory.getClassType("java.lang.Object"); JavaClassType stringType = factory.getClassType("java.lang.String"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConditionalBranchFolderTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConditionalBranchFolderTest.java index 1e497dd2ce9..455fb9fe40a 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConditionalBranchFolderTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConditionalBranchFolderTest.java @@ -86,7 +86,7 @@ public void testConditionalBranchingWithNoConclusiveIfCondition() { private static Body.BodyBuilder createBodyBuilder(int constantCondition) { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); JavaJimple javaJimple = JavaJimple.getInstance(); - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType stringType = factory.getClassType("java.lang.String"); Local a = JavaJimple.newLocal("a", stringType); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConstantPropagatorAndFolderTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConstantPropagatorAndFolderTest.java index 324e30bb444..2936651b65e 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConstantPropagatorAndFolderTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/ConstantPropagatorAndFolderTest.java @@ -77,7 +77,7 @@ public void testNoModification() { } private static Body.BodyBuilder createBody(boolean constantFolding) { - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); Local a = JavaJimple.newLocal("a", PrimitiveType.getInt()); Local b = JavaJimple.newLocal("b", PrimitiveType.getInt()); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/CopyPropagatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/CopyPropagatorTest.java index 58eb579b316..93a86dbc391 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/CopyPropagatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/CopyPropagatorTest.java @@ -33,7 +33,7 @@ public class CopyPropagatorTest { // Preparation JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType intType = factory.getClassType("int"); JavaClassType refType = factory.getClassType("ref"); JavaClassType classType = factory.getClassType("Test"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/DeadAssignmentEliminatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/DeadAssignmentEliminatorTest.java index cb5679b72a0..554177ca4bc 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/DeadAssignmentEliminatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/DeadAssignmentEliminatorTest.java @@ -50,7 +50,7 @@ public class DeadAssignmentEliminatorTest { */ @Test public void conditionalToRemovedBlock() { - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); Local a = JavaJimple.newLocal("a", PrimitiveType.getInt()); Set locals = ImmutableUtils.immutableSet(a); @@ -112,7 +112,7 @@ public void testNoModification() { private static Body.BodyBuilder createBody(boolean essentialOption) { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); JavaJimple javaJimple = JavaJimple.getInstance(); - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType objectType = factory.getClassType("java.lang.Object"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/EmptySwitchEliminatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/EmptySwitchEliminatorTest.java index 731ab9d26cd..4b16b298a47 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/EmptySwitchEliminatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/EmptySwitchEliminatorTest.java @@ -28,7 +28,7 @@ public class EmptySwitchEliminatorTest { // Preparation JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType intType = factory.getClassType("int"); JavaClassType classType = factory.getClassType("Test"); MethodSignature methodSignature = diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalLivenessAnalyserTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalLivenessAnalyserTest.java index f900d0f4da8..248dc02dd67 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalLivenessAnalyserTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalLivenessAnalyserTest.java @@ -29,7 +29,7 @@ public class LocalLivenessAnalyserTest { // Preparation JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType intType = factory.getClassType("int"); JavaClassType classType = factory.getClassType("Test"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalNameStandardizerTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalNameStandardizerTest.java index 7b7cb7af8f2..fd2b7aa1440 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalNameStandardizerTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalNameStandardizerTest.java @@ -30,7 +30,7 @@ public class LocalNameStandardizerTest { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType classType = factory.getClassType("Test"); MethodSignature methodSignature = new MethodSignature(classType, "test", Collections.emptyList(), VoidType.getInstance()); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalPackerTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalPackerTest.java index 538e9205bae..72870d859ce 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalPackerTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalPackerTest.java @@ -32,7 +32,7 @@ public class LocalPackerTest { // Preparation JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); JavaJimple javaJimple = JavaJimple.getInstance(); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType classType = factory.getClassType("Test"); JavaClassType intType = factory.getClassType("int"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalSplitterTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalSplitterTest.java index 54e2b956ecb..c2ff3c08f3a 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalSplitterTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/LocalSplitterTest.java @@ -31,7 +31,7 @@ public class LocalSplitterTest { // Preparation JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType intType = factory.getClassType("int"); JavaClassType classType = factory.getClassType("Test"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/NopEliminatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/NopEliminatorTest.java index 87db95c41bd..d16d532ae57 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/NopEliminatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/NopEliminatorTest.java @@ -73,7 +73,7 @@ public void testNoJNops() { private static Body.BodyBuilder createBody(boolean withNop) { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); JavaJimple javaJimple = JavaJimple.getInstance(); - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType objectType = factory.getClassType("java.lang.Object"); JavaClassType stringType = factory.getClassType("java.lang.String"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/StaticSingleAssignmentFormerTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/StaticSingleAssignmentFormerTest.java index 3174630aaf6..a4a6f02c290 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/StaticSingleAssignmentFormerTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/StaticSingleAssignmentFormerTest.java @@ -31,7 +31,7 @@ public class StaticSingleAssignmentFormerTest { // Preparation JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaJimple javaJimple = JavaJimple.getInstance(); JavaClassType intType = factory.getClassType("int"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/TrapTightenerTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/TrapTightenerTest.java index f5990ed4e06..a17243ee5c8 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/TrapTightenerTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/TrapTightenerTest.java @@ -32,7 +32,7 @@ @Ignore("FIXME: needs .setTraps() adapted to MutableBlockStmtGraph") public class TrapTightenerTest { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType intType = factory.getClassType("int"); JavaClassType classType = factory.getClassType("Test"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java index 7c47b97a0f9..5d0c6ba1d6d 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java @@ -35,7 +35,7 @@ public class UnreachableCodeEliminatorTest { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); JavaJimple javaJimple = JavaJimple.getInstance(); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType classType = factory.getClassType("Test"); MethodSignature methodSignature = new MethodSignature(classType, "test", Collections.emptyList(), VoidType.getInstance()); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnusedLocalEliminatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnusedLocalEliminatorTest.java index db3492cccb1..04f56c0086e 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnusedLocalEliminatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnusedLocalEliminatorTest.java @@ -57,7 +57,7 @@ public void testRemoveNothing() { private static Body.BodyBuilder createBody(boolean unusedLocals) { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); JavaJimple javaJimple = JavaJimple.getInstance(); - StmtPositionInfo noPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaClassType objectType = factory.getClassType("java.lang.Object"); JavaClassType stringType = factory.getClassType("java.lang.String"); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/LocalTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/LocalTest.java index 784067ca3eb..caf630b880d 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/LocalTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/LocalTest.java @@ -60,6 +60,6 @@ public void testEquivTo() { assertFalse(l2.equivTo(l3, comparator)); assertFalse( - l1.equivTo(new JBreakpointStmt(StmtPositionInfo.createNoStmtPositionInfo()), comparator)); + l1.equivTo(new JBreakpointStmt(StmtPositionInfo.getNoStmtPositionInfo()), comparator)); } } diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JAssignStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JAssignStmtTest.java index 113795b3c5c..629a1304c0c 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JAssignStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JAssignStmtTest.java @@ -63,7 +63,7 @@ public boolean equals(Object obj) { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); Immediate numConst1 = IntConstant.getInstance(42); Immediate numConst2 = IntConstant.getInstance(33102); @@ -127,14 +127,14 @@ public void test() { JavaIdentifierFactory.getInstance().getClassType("Abc.def.Alphabet"), PrimitiveType.getInt())); final JAssignStmt jAssignStmtField = - Jimple.newAssignStmt(someLocal, somefield, StmtPositionInfo.createNoStmtPositionInfo()); + Jimple.newAssignStmt(someLocal, somefield, StmtPositionInfo.getNoStmtPositionInfo()); jAssignStmtField.getFieldRef(); // test JFieldRef cast for ArrayRef - should not throw an Exception final JArrayRef jArrayRef = JavaJimple.getInstance().newArrayRef(someLocal, IntConstant.getInstance(2)); final JAssignStmt jAssignStmtArr = - Jimple.newAssignStmt(someLocal, jArrayRef, StmtPositionInfo.createNoStmtPositionInfo()); + Jimple.newAssignStmt(someLocal, jArrayRef, StmtPositionInfo.getNoStmtPositionInfo()); jAssignStmtArr.getArrayRef(); } } diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JGotoStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JGotoStmtTest.java index 5c741848809..b4a0ed9d0ed 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JGotoStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JGotoStmtTest.java @@ -41,7 +41,7 @@ public class JGotoStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); JavaIdentifierFactory typeFactory = JavaIdentifierFactory.getInstance(); Local local = new Local("r0", typeFactory.getType("java.lang.Exception")); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JIdentityStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JIdentityStmtTest.java index 8f4429005a3..96dc9372d6c 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JIdentityStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JIdentityStmtTest.java @@ -42,7 +42,7 @@ public class JIdentityStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); JavaIdentifierFactory typeFactory = JavaIdentifierFactory.getInstance(); Local thiz = new Local("r0", typeFactory.getType("somepackage.dummy.MyClass")); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JIfStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JIfStmtTest.java index 0d465003e8d..2e480566c4a 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JIfStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JIfStmtTest.java @@ -40,7 +40,7 @@ public class JIfStmtTest { // TODO: [ms] incorporate Printer i.e. Body+Targets @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); Stmt target = new JNopStmt(nop); AbstractConditionExpr condition = diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JInvokeStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JInvokeStmtTest.java index 3dcb712bcc1..e048a96c0a7 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JInvokeStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JInvokeStmtTest.java @@ -64,7 +64,7 @@ public class JInvokeStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); JavaIdentifierFactory dif = JavaIdentifierFactory.getInstance(); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JNopStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JNopStmtTest.java index eaa1858ee19..6ef60ac0c0b 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JNopStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JNopStmtTest.java @@ -40,7 +40,7 @@ public class JNopStmtTest { @Test public void test() { - StmtPositionInfo nopos = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nopos = StmtPositionInfo.getNoStmtPositionInfo(); Stmt nop = new JNopStmt(nopos); Assert.assertTrue(nop.equivTo(nop)); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JReturnStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JReturnStmtTest.java index 68f55b2c654..d1c00ec32f6 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JReturnStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JReturnStmtTest.java @@ -38,7 +38,7 @@ public class JReturnStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); Stmt rStmt = new JReturnStmt(IntConstant.getInstance(42), nop); // equivTo diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JReturnVoidStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JReturnVoidStmtTest.java index ae9545651fb..41fe7f842d4 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JReturnVoidStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JReturnVoidStmtTest.java @@ -39,7 +39,7 @@ public class JReturnVoidStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); Stmt rStmt = new JReturnVoidStmt(nop); // equivTo diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JThrowStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JThrowStmtTest.java index 2503169ecfc..454ec53d180 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JThrowStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/common/stmt/JThrowStmtTest.java @@ -39,7 +39,7 @@ public class JThrowStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); JavaIdentifierFactory typeFactory = JavaIdentifierFactory.getInstance(); Local local = new Local("r0", typeFactory.getType("java.lang.Exception")); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JBreakpointStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JBreakpointStmtTest.java index bdd8b7ccc2c..662bb7bf3ec 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JBreakpointStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JBreakpointStmtTest.java @@ -38,7 +38,7 @@ public class JBreakpointStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); Stmt stmt = new JBreakpointStmt(nop); Stmt stmt2 = new JBreakpointStmt(nop); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JEnterMonitorStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JEnterMonitorStmtTest.java index 3a98dc5fe4f..f87f1f68e11 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JEnterMonitorStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JEnterMonitorStmtTest.java @@ -41,7 +41,7 @@ public class JEnterMonitorStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); Local sandman = new Local("sandman", PrimitiveType.getInt()); Local night = new Local("night", PrimitiveType.getBoolean()); Local light = new Local("light", PrimitiveType.getBoolean()); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JExitMonitorStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JExitMonitorStmtTest.java index 5de14fceb73..ebeacc6db52 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JExitMonitorStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JExitMonitorStmtTest.java @@ -41,7 +41,7 @@ public class JExitMonitorStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); Local sandman = new Local("sandman", PrimitiveType.getInt()); Local night = new Local("night", PrimitiveType.getBoolean()); Local light = new Local("light", PrimitiveType.getBoolean()); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JRetStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JRetStmtTest.java index 8ad73cb5255..be7344ec7c7 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JRetStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JRetStmtTest.java @@ -40,7 +40,7 @@ public class JRetStmtTest { @Test public void test() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); Stmt stmt = new JRetStmt(IntConstant.getInstance(33102), nop); Stmt stmt2 = new JRetStmt(IntConstant.getInstance(42), nop); diff --git a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JSwitchStmtTest.java b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JSwitchStmtTest.java index 80c1c725438..69329890f1d 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JSwitchStmtTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/jimple/javabytecode/stmt/JSwitchStmtTest.java @@ -19,7 +19,7 @@ public class JSwitchStmtTest { @Test public void testLookupSwitchStmt() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); ArrayList lookupValues = new ArrayList<>(); ArrayList targets = new ArrayList<>(); @@ -50,7 +50,7 @@ public void testLookupSwitchStmt() { @Test public void testTableSwitchStmt() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); ArrayList targets = new ArrayList<>(); targets.add(new JReturnStmt(IntConstant.getInstance(1), nop)); targets.add(new JReturnStmt(IntConstant.getInstance(2), nop)); @@ -88,7 +88,7 @@ public void testTableSwitchStmt() { @Test public void testTableSwitch() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); JSwitchStmt stmt = new JSwitchStmt(IntConstant.getInstance(123), 1, 4, nop); JSwitchStmt diffSwitch = new JSwitchStmt(IntConstant.getInstance(123), 0, 4, nop); JSwitchStmt diffKeySwitch = new JSwitchStmt(IntConstant.getInstance(42), 1, 4, nop); @@ -216,7 +216,7 @@ public void testTableSwitch() { @Test public void testLookupSwitch() { - StmtPositionInfo nop = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo nop = StmtPositionInfo.getNoStmtPositionInfo(); ArrayList lookupValues = new ArrayList<>(); Stmt switchStmt = new JSwitchStmt(IntConstant.getInstance(42), lookupValues, nop); diff --git a/sootup.java.core/src/test/java/sootup/java/core/model/SootMethodTest.java b/sootup.java.core/src/test/java/sootup/java/core/model/SootMethodTest.java index 48c3d959f71..707ba112b16 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/model/SootMethodTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/model/SootMethodTest.java @@ -50,9 +50,9 @@ public void testCreateMethod() { Jimple.newIdentityStmt( generator.generateLocal(type), Jimple.newParameterRef(type, 0), - StmtPositionInfo.createNoStmtPositionInfo()); + StmtPositionInfo.getNoStmtPositionInfo()); final JReturnVoidStmt returnVoidStmt = - new JReturnVoidStmt(StmtPositionInfo.createNoStmtPositionInfo()); + new JReturnVoidStmt(StmtPositionInfo.getNoStmtPositionInfo()); Body body = bodyBuilder diff --git a/sootup.java.core/src/test/java/sootup/java/core/printer/JimplePrinterTest.java b/sootup.java.core/src/test/java/sootup/java/core/printer/JimplePrinterTest.java index e608943cfd3..1c0bfe82f81 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/printer/JimplePrinterTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/printer/JimplePrinterTest.java @@ -61,7 +61,7 @@ private SootClass buildClass() { view.getIdentifierFactory() .getMethodSignature(className, "main", "void", Collections.emptyList()); - StmtPositionInfo noPosInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPosInfo = StmtPositionInfo.getNoStmtPositionInfo(); final JReturnVoidStmt returnVoidStmt = new JReturnVoidStmt(noPosInfo); final JNopStmt jNop = new JNopStmt(noPosInfo); Body.BodyBuilder bodyBuilder = Body.builder(); diff --git a/sootup.java.core/src/test/java/sootup/java/core/printer/LegacyJimplePrinterTest.java b/sootup.java.core/src/test/java/sootup/java/core/printer/LegacyJimplePrinterTest.java index 65b71a316f2..327b051e0c2 100644 --- a/sootup.java.core/src/test/java/sootup/java/core/printer/LegacyJimplePrinterTest.java +++ b/sootup.java.core/src/test/java/sootup/java/core/printer/LegacyJimplePrinterTest.java @@ -68,7 +68,7 @@ SootClass buildClass(Body.BodyBuilder builder) { @Test public void printSwitchStmt() { - StmtPositionInfo noPosInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noPosInfo = StmtPositionInfo.getNoStmtPositionInfo(); ArrayList lookupValues = new ArrayList<>(); lookupValues.add(IntConstant.getInstance(42)); lookupValues.add(IntConstant.getInstance(33102)); diff --git a/sootup.tests/src/test/java/sootup/tests/ReplaceUseExprVisitorTest.java b/sootup.tests/src/test/java/sootup/tests/ReplaceUseExprVisitorTest.java index 7dbd6e9e6bc..09bcc83a7aa 100644 --- a/sootup.tests/src/test/java/sootup/tests/ReplaceUseExprVisitorTest.java +++ b/sootup.tests/src/test/java/sootup/tests/ReplaceUseExprVisitorTest.java @@ -35,7 +35,7 @@ public class ReplaceUseExprVisitorTest { JavaClassType intType = factory.getClassType("int"); JavaClassType testClass = factory.getClassType("TestClass"); JavaClassType voidType = factory.getClassType("void"); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); Local op1 = JavaJimple.newLocal("op1", intType); Local op2 = JavaJimple.newLocal("op2", intType); diff --git a/sootup.tests/src/test/java/sootup/tests/ReplaceUseStmtVisitorTest.java b/sootup.tests/src/test/java/sootup/tests/ReplaceUseStmtVisitorTest.java index 7cea7aae766..f21018a5d74 100644 --- a/sootup.tests/src/test/java/sootup/tests/ReplaceUseStmtVisitorTest.java +++ b/sootup.tests/src/test/java/sootup/tests/ReplaceUseStmtVisitorTest.java @@ -40,7 +40,7 @@ public class ReplaceUseStmtVisitorTest { MethodSignature methodeWithOutParas = new MethodSignature(testClass, "invokeExpr", Collections.emptyList(), voidType); - StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.createNoStmtPositionInfo(); + StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); /** Test use replacing in case JAssignStmt. */ @Test diff --git a/sootup.tests/src/test/java/sootup/tests/WitherTest.java b/sootup.tests/src/test/java/sootup/tests/WitherTest.java index 8a9ba1c4766..125609589b9 100644 --- a/sootup.tests/src/test/java/sootup/tests/WitherTest.java +++ b/sootup.tests/src/test/java/sootup/tests/WitherTest.java @@ -65,10 +65,10 @@ public void testWithers() { Jimple.newIdentityStmt( generator.generateLocal(declareClassSig), Jimple.newParameterRef(declareClassSig, 0), - StmtPositionInfo.createNoStmtPositionInfo()); + StmtPositionInfo.getNoStmtPositionInfo()); final JReturnStmt jReturnStmt = Jimple.newReturnStmt( - DoubleConstant.getInstance(12.34), StmtPositionInfo.createNoStmtPositionInfo()); + DoubleConstant.getInstance(12.34), StmtPositionInfo.getNoStmtPositionInfo()); // bodyBuilder.addFlow(firstStmt, jReturnStmt); Body body = From a954c65ca6a9945e1eaa597c038abf0bda596cc7 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 19 Jan 2024 13:19:15 +0100 Subject: [PATCH 40/57] style, fix test --- .../core/graph/MutableBlockStmtGraph.java | 8 +- .../java/sootup/core/graph/StmtGraph.java | 1211 ++++++++--------- .../core/graph/MutableBlockStmtGraphTest.java | 4 +- .../UnreachableCodeEliminatorTest.java | 2 - 4 files changed, 599 insertions(+), 626 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java index f1376dbc677..200801fd97d 100644 --- a/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java +++ b/sootup.core/src/main/java/sootup/core/graph/MutableBlockStmtGraph.java @@ -518,14 +518,14 @@ public void removeBlock(BasicBlock block) { MutableBasicBlock blockOf = stmtToBlock.get(block.getHead()); if (blockOf != block) { throw new IllegalArgumentException( - "The given block is not contained in this MutableBlockStmtGraph."); + "The given block is not contained in this MutableBlockStmtGraph."); } List stmts = block.getStmts(); stmts.forEach( - stmt -> { - stmtToBlock.remove(stmt); - }); + stmt -> { + stmtToBlock.remove(stmt); + }); // unlink block from graph blockOf.clearPredecessorBlocks(); diff --git a/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java index 3408876b137..0f6c03d1b58 100644 --- a/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java +++ b/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java @@ -22,6 +22,12 @@ */ import com.google.common.collect.Iterators; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.*; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import sootup.core.jimple.basic.Trap; import sootup.core.jimple.common.stmt.*; import sootup.core.jimple.javabytecode.stmt.JSwitchStmt; @@ -30,13 +36,6 @@ import sootup.core.util.EscapedWriter; import sootup.core.util.printer.JimplePrinter; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.*; -import java.util.stream.Collectors; - /** * Interface for control flow graphs on Jimple Stmts. A StmtGraph is directed and connected (except * for traphandlers - those are not connected to the unexceptional flow via StmtGraph). Its directed @@ -63,683 +62,659 @@ */ public abstract class StmtGraph> implements Iterable { - public abstract Stmt getStartingStmt(); + public abstract Stmt getStartingStmt(); + + public abstract BasicBlock getStartingStmtBlock(); + + /** + * returns the nodes in this graph in a non-deterministic order (->Set) to get the nodes in + * linearized, ordered manner use iterator() or getStmts. + */ + @Nonnull + public abstract Collection getNodes(); + + public List getStmts() { + final ArrayList res = new ArrayList<>(); + Iterators.addAll(res, iterator()); + return res; + } + + @Nonnull + public abstract Collection> getBlocks(); + + @Nonnull + public abstract List> getBlocksSorted(); + + public Iterator> getBlockIterator() { + return new BlockGraphIterator(); + } + + public abstract BasicBlock getBlockOf(@Nonnull Stmt stmt); + + public abstract boolean containsNode(@Nonnull Stmt node); + + /** + * returns the ingoing flows to node as an List with no reliable/specific order and possibly + * duplicate entries i.e. if a JSwitchStmt has multiple cases that brnach to `node` + */ + @Nonnull + public abstract List predecessors(@Nonnull Stmt node); + + /** it is possible to reach traphandlers through inline code i.e. without any exceptional flow */ + @Nonnull + public abstract List exceptionalPredecessors(@Nonnull Stmt node); + + /** returns the outgoing flows of node as ordered List. The List can have duplicate entries! */ + @Nonnull + public abstract List successors(@Nonnull Stmt node); + + @Nonnull + public abstract Map exceptionalSuccessors(@Nonnull Stmt node); + + /** + * Collects all successors i.e. unexceptional and exceptional successors of a given stmt into a + * list. + * + * @param stmt in the given graph + * @return a list containing the unexceptional+exceptional successors of the given stmt + */ + @Nonnull + public List getAllSuccessors(@Nonnull Stmt stmt) { + final List successors = successors(stmt); + final Map exSuccessors = exceptionalSuccessors(stmt); + List allSuccessors = new ArrayList<>(successors.size() + exSuccessors.size()); + allSuccessors.addAll(successors); + allSuccessors.addAll(exSuccessors.values()); + return allSuccessors; + } + + /** returns the amount of ingoing flows into node */ + public abstract int inDegree(@Nonnull Stmt node); + + /** returns the amount of flows that start from node */ + public abstract int outDegree(@Nonnull Stmt node); + + /** returns the amount of flows with node as source or target. */ + public int degree(@Nonnull Stmt node) { + return inDegree(node) + outDegree(node); + } + + /** + * returns true if there is a flow between source and target throws an Exception if at least one + * of the parameters is not contained in the graph. + */ + public abstract boolean hasEdgeConnecting(@Nonnull Stmt source, @Nonnull Stmt target); + + /** returns a list of associated traps */ + @Deprecated + public abstract List getTraps(); + + /** + * returns a Collection of Stmts that leave the body (i.e. JReturnVoidStmt, JReturnStmt and + * JThrowStmt) + */ + @Nonnull + public List getTails() { + return getNodes().stream() + .filter(stmt -> stmt.getExpectedSuccessorCount() == 0) + .collect(Collectors.toList()); + } + + /** + * returns a Collection of all stmts in the graph that don't have an unexceptional ingoing flow or + * are the starting Stmt. + */ + @Nonnull + public Collection getEntrypoints() { + final ArrayList stmts = new ArrayList<>(); + stmts.add(getStartingStmt()); + // TODO: [ms] memory/performance: instead of gettraps(): iterate through all stmts and add + // startingStmt+@caughtexception/predecessors().size() == 0? + getTraps().stream().map(Trap::getHandlerStmt).forEach(stmts::add); + return stmts; + } + + /** validates whether the each Stmt has the correct amount of outgoing flows. */ + public void validateStmtConnectionsInGraph() { + try { + + for (Stmt stmt : getNodes()) { + final List successors = successors(stmt); + final int successorCount = successors.size(); + + if (predecessors(stmt).size() == 0) { + if (!(stmt == getStartingStmt() + || getTraps().stream() + .map(Trap::getHandlerStmt) + .anyMatch(handler -> handler == stmt))) { + throw new IllegalStateException( + "Stmt '" + + stmt + + "' which is neither the StartingStmt nor a TrapHandler is missing a predecessor!"); + } + } - public abstract BasicBlock getStartingStmtBlock(); + if (stmt instanceof BranchingStmt) { - /** - * returns the nodes in this graph in a non-deterministic order (->Set) to get the nodes in - * linearized, ordered manner use iterator() or getStmts. - */ - @Nonnull - public abstract Collection getNodes(); + for (Stmt target : successors) { + if (target == stmt) { + throw new IllegalStateException(stmt + ": a Stmt cannot branch to itself."); + } + } + + if (stmt instanceof JSwitchStmt) { + if (successorCount != ((JSwitchStmt) stmt).getValueCount()) { + throw new IllegalStateException( + stmt + + ": size of outgoing flows (i.e. " + + successorCount + + ") does not match the amount of JSwitchStmts case labels (i.e. " + + ((JSwitchStmt) stmt).getValueCount() + + ")."); + } + } else if (stmt instanceof JIfStmt) { + if (successorCount != 2) { + throw new IllegalStateException( + stmt + ": JIfStmt must have '2' outgoing flow but has '" + successorCount + "'."); + } + } else if (stmt instanceof JGotoStmt) { + if (successorCount != 1) { + throw new IllegalStateException( + stmt + ": JGoto must have '1' outgoing flow but has '" + successorCount + "'."); + } + } + + } else if (stmt instanceof JReturnStmt + || stmt instanceof JReturnVoidStmt + || stmt instanceof JThrowStmt) { + if (successorCount != 0) { + throw new IllegalStateException( + stmt + ": must have '0' outgoing flow but has '" + successorCount + "'."); + } + } else { + if (successorCount != 1) { + throw new IllegalStateException( + stmt + ": must have '1' outgoing flow but has '" + successorCount + "'."); + } + } + } - public List getStmts() { - final ArrayList res = new ArrayList<>(); - Iterators.addAll(res, iterator()); - return res; + } catch (Exception e) { + final String urlToWebeditor = DotExporter.createUrlToWebeditor(this); + throw new IllegalStateException("visualize invalid StmtGraph: " + urlToWebeditor, e); } - - @Nonnull - public abstract Collection> getBlocks(); - - @Nonnull - public abstract List> getBlocksSorted(); - - public Iterator> getBlockIterator() { - return new BlockGraphIterator(); + } + + /** + * Look for a path in graph, from def to use. This path has to lie inside an extended basic block + * (and this property implies uniqueness.). The path returned includes from and to. FIXME: ms: + * explain better + * + * @param from start point for the path. + * @param to end point for the path. + * @return null if there is no such path. + */ + @Nullable + public List getExtendedBasicBlockPathBetween(@Nonnull Stmt from, @Nonnull Stmt to) { + + // if this holds, we're doomed to failure!!! + if (inDegree(to) > 1) { + return null; } - public abstract BasicBlock getBlockOf(@Nonnull Stmt stmt); - - public abstract boolean containsNode(@Nonnull Stmt node); - - /** - * returns the ingoing flows to node as an List with no reliable/specific order and possibly - * duplicate entries i.e. if a JSwitchStmt has multiple cases that brnach to `node` - */ - @Nonnull - public abstract List predecessors(@Nonnull Stmt node); - - /** - * it is possible to reach traphandlers through inline code i.e. without any exceptional flow - */ - @Nonnull - public abstract List exceptionalPredecessors(@Nonnull Stmt node); - - /** - * returns the outgoing flows of node as ordered List. The List can have duplicate entries! - */ - @Nonnull - public abstract List successors(@Nonnull Stmt node); - - @Nonnull - public abstract Map exceptionalSuccessors(@Nonnull Stmt node); - - /** - * Collects all successors i.e. unexceptional and exceptional successors of a given stmt into a - * list. - * - * @param stmt in the given graph - * @return a list containing the unexceptional+exceptional successors of the given stmt - */ - @Nonnull - public List getAllSuccessors(@Nonnull Stmt stmt) { - final List successors = successors(stmt); - final Map exSuccessors = exceptionalSuccessors(stmt); - List allSuccessors = new ArrayList<>(successors.size() + exSuccessors.size()); - allSuccessors.addAll(successors); - allSuccessors.addAll(exSuccessors.values()); - return allSuccessors; + // pathStack := list of succs lists + // pathStackIndex := last visited index in pathStack + List pathStack = new ArrayList<>(); + List pathStackIndex = new ArrayList<>(); + + pathStack.add(from); + pathStackIndex.add(0); + + int psiMax = outDegree(pathStack.get(0)); + int level = 0; + while (pathStackIndex.get(0) != psiMax) { + int p = pathStackIndex.get(level); + + List succs = successors((pathStack.get(level))); + if (p >= succs.size()) { + // no more succs - backtrack to previous level. + + pathStack.remove(level); + pathStackIndex.remove(level); + + level--; + int q = pathStackIndex.get(level); + pathStackIndex.set(level, q + 1); + continue; + } + + Stmt betweenStmt = succs.get(p); + + // we win! + if (betweenStmt == to) { + pathStack.add(to); + return pathStack; + } + + // check preds of betweenStmt to see if we should visit its kids. + if (inDegree(betweenStmt) > 1) { + pathStackIndex.set(level, p + 1); + continue; + } + + // visit kids of betweenStmt. + level++; + pathStackIndex.add(0); + pathStack.add(betweenStmt); } + return null; + } - /** - * returns the amount of ingoing flows into node - */ - public abstract int inDegree(@Nonnull Stmt node); - - /** - * returns the amount of flows that start from node - */ - public abstract int outDegree(@Nonnull Stmt node); + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } - /** - * returns the amount of flows with node as source or target. - */ - public int degree(@Nonnull Stmt node) { - return inDegree(node) + outDegree(node); + if (!(o instanceof StmtGraph)) { + return false; } + StmtGraph otherGraph = (StmtGraph) o; - /** - * returns true if there is a flow between source and target throws an Exception if at least one - * of the parameters is not contained in the graph. - */ - public abstract boolean hasEdgeConnecting(@Nonnull Stmt source, @Nonnull Stmt target); + if (getStartingStmt() != otherGraph.getStartingStmt()) { + return false; + } - /** - * returns a list of associated traps - */ - @Deprecated - public abstract List getTraps(); + Collection nodes = getNodes(); + final Collection otherNodes = otherGraph.getNodes(); + if (nodes.size() != otherNodes.size()) { + return false; + } - /** - * returns a Collection of Stmts that leave the body (i.e. JReturnVoidStmt, JReturnStmt and - * JThrowStmt) - */ - @Nonnull - public List getTails() { - return getNodes().stream() - .filter(stmt -> stmt.getExpectedSuccessorCount() == 0) - .collect(Collectors.toList()); + if (!getTraps().equals(otherGraph.getTraps())) { + return false; } - /** - * returns a Collection of all stmts in the graph that don't have an unexceptional ingoing flow or - * are the starting Stmt. - */ - @Nonnull - public Collection getEntrypoints() { - final ArrayList stmts = new ArrayList<>(); - stmts.add(getStartingStmt()); - // TODO: [ms] memory/performance: instead of gettraps(): iterate through all stmts and add - // startingStmt+@caughtexception/predecessors().size() == 0? - getTraps().stream().map(Trap::getHandlerStmt).forEach(stmts::add); - return stmts; + for (Stmt node : nodes) { + if (!otherNodes.contains(node)) { + return false; + } + final List successors = successors(node); + final List otherSuccessors = otherGraph.successors(node); + if (!successors.equals(otherSuccessors)) { + return false; + } } - /** - * validates whether the each Stmt has the correct amount of outgoing flows. - */ - public void validateStmtConnectionsInGraph() { - try { - - for (Stmt stmt : getNodes()) { - final List successors = successors(stmt); - final int successorCount = successors.size(); - - if (predecessors(stmt).size() == 0) { - if (!(stmt == getStartingStmt() - || getTraps().stream() - .map(Trap::getHandlerStmt) - .anyMatch(handler -> handler == stmt))) { - throw new IllegalStateException( - "Stmt '" - + stmt - + "' which is neither the StartingStmt nor a TrapHandler is missing a predecessor!"); - } - } + return true; + } - if (stmt instanceof BranchingStmt) { - - for (Stmt target : successors) { - if (target == stmt) { - throw new IllegalStateException(stmt + ": a Stmt cannot branch to itself."); - } - } - - if (stmt instanceof JSwitchStmt) { - if (successorCount != ((JSwitchStmt) stmt).getValueCount()) { - throw new IllegalStateException( - stmt - + ": size of outgoing flows (i.e. " - + successorCount - + ") does not match the amount of JSwitchStmts case labels (i.e. " - + ((JSwitchStmt) stmt).getValueCount() - + ")."); - } - } else if (stmt instanceof JIfStmt) { - if (successorCount != 2) { - throw new IllegalStateException( - stmt + ": JIfStmt must have '2' outgoing flow but has '" + successorCount + "'."); - } - } else if (stmt instanceof JGotoStmt) { - if (successorCount != 1) { - throw new IllegalStateException( - stmt + ": JGoto must have '1' outgoing flow but has '" + successorCount + "'."); - } - } - - } else if (stmt instanceof JReturnStmt - || stmt instanceof JReturnVoidStmt - || stmt instanceof JThrowStmt) { - if (successorCount != 0) { - throw new IllegalStateException( - stmt + ": must have '0' outgoing flow but has '" + successorCount + "'."); - } - } else { - if (successorCount != 1) { - throw new IllegalStateException( - stmt + ": must have '1' outgoing flow but has '" + successorCount + "'."); - } - } - } + @Override + @Nonnull + public Iterator iterator() { + return new BlockStmtGraphIterator(); + } - } catch (Exception e) { - final String urlToWebeditor = DotExporter.createUrlToWebeditor(this); - throw new IllegalStateException("visualize invalid StmtGraph: " + urlToWebeditor, e); - } + public List getBranchTargetsOf(BranchingStmt fromStmt) { + final List successors = successors(fromStmt); + if (fromStmt instanceof JIfStmt) { + // remove the first successor as if its a fallsthrough stmt and not a branch target + return Collections.singletonList(successors.get(1)); + } + return successors; + } + + public boolean isStmtBranchTarget(@Nonnull Stmt targetStmt) { + final List predecessors = predecessors(targetStmt); + if (predecessors.size() > 1) { + // join node i.e. at least one is a branch + return true; } - /** - * Look for a path in graph, from def to use. This path has to lie inside an extended basic block - * (and this property implies uniqueness.). The path returned includes from and to. FIXME: ms: - * explain better - * - * @param from start point for the path. - * @param to end point for the path. - * @return null if there is no such path. - */ - @Nullable - public List getExtendedBasicBlockPathBetween(@Nonnull Stmt from, @Nonnull Stmt to) { - - // if this holds, we're doomed to failure!!! - if (inDegree(to) > 1) { - return null; + final Iterator iterator = predecessors.iterator(); + if (iterator.hasNext()) { + Stmt pred = iterator.next(); + if (pred.branches()) { + if (pred instanceof JIfStmt) { + // [ms] bounds are validated in Body + return getBranchTargetsOf((JIfStmt) pred).get(0) == targetStmt; } + return true; + } + } - // pathStack := list of succs lists - // pathStackIndex := last visited index in pathStack - List pathStack = new ArrayList<>(); - List pathStackIndex = new ArrayList<>(); - - pathStack.add(from); - pathStackIndex.add(0); - - int psiMax = outDegree(pathStack.get(0)); - int level = 0; - while (pathStackIndex.get(0) != psiMax) { - int p = pathStackIndex.get(level); - - List succs = successors((pathStack.get(level))); - if (p >= succs.size()) { - // no more succs - backtrack to previous level. + return false; + } - pathStack.remove(level); - pathStackIndex.remove(level); + /** Iterates the Stmts according to the jimple output order. */ + private class BlockStmtGraphIterator implements Iterator { - level--; - int q = pathStackIndex.get(level); - pathStackIndex.set(level, q + 1); - continue; - } + private final BlockGraphIterator blockIt; + @Nonnull private Iterator currentBlockIt = Collections.emptyIterator(); - Stmt betweenStmt = succs.get(p); - - // we win! - if (betweenStmt == to) { - pathStack.add(to); - return pathStack; - } - - // check preds of betweenStmt to see if we should visit its kids. - if (inDegree(betweenStmt) > 1) { - pathStackIndex.set(level, p + 1); - continue; - } + public BlockStmtGraphIterator() { + this(new BlockGraphIterator()); + } - // visit kids of betweenStmt. - level++; - pathStackIndex.add(0); - pathStack.add(betweenStmt); - } - return null; + public BlockStmtGraphIterator(@Nonnull BlockGraphIterator blockIterator) { + blockIt = blockIterator; } @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } + public boolean hasNext() { + // hint: a BasicBlock has at least 1 Stmt or should not be in a StmtGraph! + return currentBlockIt.hasNext() || blockIt.hasNext(); + } - if (!(o instanceof StmtGraph)) { - return false; + @Override + public Stmt next() { + if (!currentBlockIt.hasNext()) { + if (!blockIt.hasNext()) { + throw new NoSuchElementException("Iterator has no more Stmts."); } - StmtGraph otherGraph = (StmtGraph) o; + BasicBlock currentBlock = blockIt.next(); + currentBlockIt = currentBlock.getStmts().iterator(); + } + return currentBlockIt.next(); + } + } - if (getStartingStmt() != otherGraph.getStartingStmt()) { - return false; - } + /** Iterates over the Blocks and collects/aggregates Trap information */ + public class BlockGraphIteratorAndTrapAggregator extends BlockGraphIterator { - Collection nodes = getNodes(); - final Collection otherNodes = otherGraph.getNodes(); - if (nodes.size() != otherNodes.size()) { - return false; - } + @Nonnull private final List collectedTraps = new ArrayList<>(); - if (!getTraps().equals(otherGraph.getTraps())) { - return false; - } + Map trapStarts = new HashMap<>(); + BasicBlock lastIteratedBlock; // dummy value to remove n-1 unnecessary null-checks - for (Stmt node : nodes) { - if (!otherNodes.contains(node)) { - return false; - } - final List successors = successors(node); - final List otherSuccessors = otherGraph.successors(node); - if (!successors.equals(otherSuccessors)) { - return false; - } - } - - return true; + /* + * @param dummyBlock is just an empty instantiation of type V - as neither BasicBlock nor V instantiable we need a concrete object from the using subclass itclass. + * */ + public BlockGraphIteratorAndTrapAggregator(V dummyBlock) { + super(); + lastIteratedBlock = dummyBlock; } - @Override @Nonnull - public Iterator iterator() { - return new BlockStmtGraphIterator(); - } - - public List getBranchTargetsOf(BranchingStmt fromStmt) { - final List successors = successors(fromStmt); - if (fromStmt instanceof JIfStmt) { - // remove the first successor as if its a fallsthrough stmt and not a branch target - return Collections.singletonList(successors.get(1)); - } - return successors; - } - - public boolean isStmtBranchTarget(@Nonnull Stmt targetStmt) { - final List predecessors = predecessors(targetStmt); - if (predecessors.size() > 1) { - // join node i.e. at least one is a branch - return true; - } - - final Iterator iterator = predecessors.iterator(); - if (iterator.hasNext()) { - Stmt pred = iterator.next(); - if (pred.branches()) { - if (pred instanceof JIfStmt) { - // [ms] bounds are validated in Body - return getBranchTargetsOf((JIfStmt) pred).get(0) == targetStmt; - } - return true; + @Override + public BasicBlock next() { + final BasicBlock block = super.next(); + + final Map> currentBlocksExceptions = + block.getExceptionalSuccessors(); + final Map> lastBlocksExceptions = + lastIteratedBlock.getExceptionalSuccessors(); + + // former trap info is not in the current blocks info -> add it to the trap collection + lastBlocksExceptions.forEach( + (type, trapHandlerBlock) -> { + if (trapHandlerBlock != block.getExceptionalSuccessors().get(type)) { + final Stmt trapBeginStmt = trapStarts.remove(type); + if (trapBeginStmt == null) { + throw new IllegalStateException("Trap start for '" + type + "' is not in the Map!"); + } + // trapend is exclusive! + collectedTraps.add( + new Trap(type, trapBeginStmt, block.getHead(), trapHandlerBlock.getHead())); } - } + }); + + // is there a new trap in the current block -> add it to currentTraps + block + .getExceptionalSuccessors() + .forEach( + (type, trapHandlerBlock) -> { + if (trapHandlerBlock != lastBlocksExceptions.get(type)) { + trapStarts.put(type, block.getHead()); + } + }); - return false; + lastIteratedBlock = block; + return block; } /** - * Iterates the Stmts according to the jimple output order. + * for jimple serialization - this info contains only valid/useful information if all stmts are + * iterated i.e. hasNext() == false! + * + * @return List of Traps */ - private class BlockStmtGraphIterator implements Iterator { - - private final BlockGraphIterator blockIt; - @Nonnull - private Iterator currentBlockIt = Collections.emptyIterator(); - - public BlockStmtGraphIterator() { - this(new BlockGraphIterator()); - } - - public BlockStmtGraphIterator(@Nonnull BlockGraphIterator blockIterator) { - blockIt = blockIterator; - } - - @Override - public boolean hasNext() { - // hint: a BasicBlock has at least 1 Stmt or should not be in a StmtGraph! - return currentBlockIt.hasNext() || blockIt.hasNext(); - } - - @Override - public Stmt next() { - if (!currentBlockIt.hasNext()) { - if (!blockIt.hasNext()) { - throw new NoSuchElementException("Iterator has no more Stmts."); - } - BasicBlock currentBlock = blockIt.next(); - currentBlockIt = currentBlock.getStmts().iterator(); - } - return currentBlockIt.next(); - } + public List getTraps() { + + if (hasNext()) { + throw new IllegalStateException("Iterator needs to be iterated completely!"); + } + + // check for dangling trap data + if (!trapStarts.isEmpty()) { + throw new IllegalArgumentException( + "Invalid StmtGraph. A Trap is not created. Maybe a Traprange covers the last Stmt as well, which is not possible."); + } + return collectedTraps; + } + } + + /** Iterates over the blocks */ + public class BlockGraphIterator implements Iterator> { + + @Nonnull private final ArrayDeque> trapHandlerBlocks = new ArrayDeque<>(); + + @Nonnull private final ArrayDeque> nestedBlocks = new ArrayDeque<>(); + @Nonnull private final ArrayDeque> otherBlocks = new ArrayDeque<>(); + @Nonnull private final Set> iteratedBlocks; + + public BlockGraphIterator() { + final Collection> blocks = getBlocks(); + iteratedBlocks = new HashSet<>(blocks.size(), 1); + Stmt startingStmt = getStartingStmt(); + if (startingStmt != null) { + final BasicBlock startingBlock = getStartingStmtBlock(); + updateFollowingBlocks(startingBlock); + nestedBlocks.addFirst(startingBlock); + } } - /** - * Iterates over the Blocks and collects/aggregates Trap information - */ - public class BlockGraphIteratorAndTrapAggregator extends BlockGraphIterator { - - @Nonnull - private final List collectedTraps = new ArrayList<>(); - - Map trapStarts = new HashMap<>(); - BasicBlock lastIteratedBlock; // dummy value to remove n-1 unnecessary null-checks - - /* - * @param dummyBlock is just an empty instantiation of type V - as neither BasicBlock nor V instantiable we need a concrete object from the using subclass itclass. - * */ - public BlockGraphIteratorAndTrapAggregator(V dummyBlock) { - super(); - lastIteratedBlock = dummyBlock; - } - - @Nonnull - @Override - public BasicBlock next() { - final BasicBlock block = super.next(); - - final Map> currentBlocksExceptions = - block.getExceptionalSuccessors(); - final Map> lastBlocksExceptions = - lastIteratedBlock.getExceptionalSuccessors(); - - // former trap info is not in the current blocks info -> add it to the trap collection - lastBlocksExceptions.forEach( - (type, trapHandlerBlock) -> { - if (trapHandlerBlock != block.getExceptionalSuccessors().get(type)) { - final Stmt trapBeginStmt = trapStarts.remove(type); - if (trapBeginStmt == null) { - throw new IllegalStateException("Trap start for '" + type + "' is not in the Map!"); - } - // trapend is exclusive! - collectedTraps.add( - new Trap(type, trapBeginStmt, block.getHead(), trapHandlerBlock.getHead())); - } - }); - - // is there a new trap in the current block -> add it to currentTraps - block - .getExceptionalSuccessors() - .forEach( - (type, trapHandlerBlock) -> { - if (trapHandlerBlock != lastBlocksExceptions.get(type)) { - trapStarts.put(type, block.getHead()); - } - }); - - lastIteratedBlock = block; - return block; - } - - /** - * for jimple serialization - this info contains only valid/useful information if all stmts are iterated i.e. hasNext() == false! - * - * @return List of Traps - */ - public List getTraps() { - - if (hasNext()) { - throw new IllegalStateException("Iterator needs to be iterated completely!"); + @Nullable + private BasicBlock retrieveNextBlock() { + BasicBlock nextBlock; + do { + if (!nestedBlocks.isEmpty()) { + nextBlock = nestedBlocks.pollFirst(); + } else if (!trapHandlerBlocks.isEmpty()) { + nextBlock = trapHandlerBlocks.pollFirst(); + } else if (!otherBlocks.isEmpty()) { + nextBlock = otherBlocks.pollFirst(); + } else { + Collection> blocks = getBlocks(); + if (iteratedBlocks.size() < blocks.size()) { + // graph is not connected! iterate/append all not connected blocks at the end in no + // particular order. + for (BasicBlock block : blocks) { + if (!iteratedBlocks.contains(block)) { + nestedBlocks.addLast(block); + } } - - // check for dangling trap data - if(!trapStarts.isEmpty()){ - throw new IllegalArgumentException("Invalid StmtGraph. A Trap is not created. Maybe a Traprange covers the last Stmt as well, which is not possible."); + if (!nestedBlocks.isEmpty()) { + return nestedBlocks.pollFirst(); } - return collectedTraps; - } - } + } - /** - * Iterates over the blocks - */ - public class BlockGraphIterator implements Iterator> { - - @Nonnull - private final ArrayDeque> trapHandlerBlocks = new ArrayDeque<>(); - - @Nonnull - private final ArrayDeque> nestedBlocks = new ArrayDeque<>(); - @Nonnull - private final ArrayDeque> otherBlocks = new ArrayDeque<>(); - @Nonnull - private final Set> iteratedBlocks; - - public BlockGraphIterator() { - final Collection> blocks = getBlocks(); - iteratedBlocks = new HashSet<>(blocks.size(), 1); - Stmt startingStmt = getStartingStmt(); - if (startingStmt != null) { - final BasicBlock startingBlock = getStartingStmtBlock(); - updateFollowingBlocks(startingBlock); - nestedBlocks.addFirst(startingBlock); - } + return null; } - @Nullable - private BasicBlock retrieveNextBlock() { - BasicBlock nextBlock; - do { - if (!nestedBlocks.isEmpty()) { - nextBlock = nestedBlocks.pollFirst(); - } else if (!trapHandlerBlocks.isEmpty()) { - nextBlock = trapHandlerBlocks.pollFirst(); - } else if (!otherBlocks.isEmpty()) { - nextBlock = otherBlocks.pollFirst(); - } else { - Collection> blocks = getBlocks(); - if (iteratedBlocks.size() < blocks.size()) { - // graph is not connected! iterate/append all not connected blocks at the end in no - // particular order. - for (BasicBlock block : blocks) { - if (!iteratedBlocks.contains(block)) { - nestedBlocks.addLast(block); - } - } - if (!nestedBlocks.isEmpty()) { - return nestedBlocks.pollFirst(); - } - } - - return null; - } - - // skip retrieved nextBlock if its already returned - } while (iteratedBlocks.contains(nextBlock)); - return nextBlock; - } + // skip retrieved nextBlock if its already returned + } while (iteratedBlocks.contains(nextBlock)); + return nextBlock; + } - @Override - @Nonnull - public BasicBlock next() { - BasicBlock currentBlock = retrieveNextBlock(); - if (currentBlock == null) { - throw new NoSuchElementException("Iterator has no more Blocks."); - } - updateFollowingBlocks(currentBlock); - iteratedBlocks.add(currentBlock); - return currentBlock; - } + @Override + @Nonnull + public BasicBlock next() { + BasicBlock currentBlock = retrieveNextBlock(); + if (currentBlock == null) { + throw new NoSuchElementException("Iterator has no more Blocks."); + } + updateFollowingBlocks(currentBlock); + iteratedBlocks.add(currentBlock); + return currentBlock; + } - // - private void updateFollowingBlocks(BasicBlock currentBlock) { - // collect traps - final Stmt tailStmt = currentBlock.getTail(); - for (Map.Entry> entry : - currentBlock.getExceptionalSuccessors().entrySet()) { - BasicBlock trapHandlerBlock = entry.getValue(); - trapHandlerBlocks.addLast(trapHandlerBlock); - nestedBlocks.addFirst(trapHandlerBlock); + // + private void updateFollowingBlocks(BasicBlock currentBlock) { + // collect traps + final Stmt tailStmt = currentBlock.getTail(); + for (Map.Entry> entry : + currentBlock.getExceptionalSuccessors().entrySet()) { + BasicBlock trapHandlerBlock = entry.getValue(); + trapHandlerBlocks.addLast(trapHandlerBlock); + nestedBlocks.addFirst(trapHandlerBlock); + } + + final List> successors = currentBlock.getSuccessors(); + + for (int i = successors.size() - 1; i >= 0; i--) { + if (i == 0 && tailStmt.fallsThrough()) { + // non-branching successors i.e. not a BranchingStmt or is the first successor (i.e. its + // false successor) of + // JIfStmt + nestedBlocks.addFirst(successors.get(0)); + } else { + + // create the most biggest fallsthrough sequence of basicblocks as possible -> go to + // the + // top until + // predecessor is not a fallsthrough stmt anymore and then the iterator will iterate + // from there. + final BasicBlock successorBlock = successors.get(i); + BasicBlock leaderOfFallsthroughBlocks = successorBlock; + while (true) { + final List> itPreds = + leaderOfFallsthroughBlocks.getPredecessors(); + + BasicBlock finalLeaderOfFallsthroughBlocks = leaderOfFallsthroughBlocks; + final Optional> fallsthroughPredOpt = + itPreds.stream() + .filter( + b -> + b.getTail().fallsThrough() + && b.getSuccessors().get(0) == finalLeaderOfFallsthroughBlocks) + .findAny(); + if (!fallsthroughPredOpt.isPresent()) { + break; } - - final List> successors = currentBlock.getSuccessors(); - - for (int i = successors.size() - 1; i >= 0; i--) { - if (i == 0 && tailStmt.fallsThrough()) { - // non-branching successors i.e. not a BranchingStmt or is the first successor (i.e. its - // false successor) of - // JIfStmt - nestedBlocks.addFirst(successors.get(0)); - } else { - - // create the most biggest fallsthrough sequence of basicblocks as possible -> go to - // the - // top until - // predecessor is not a fallsthrough stmt anymore and then the iterator will iterate - // from there. - final BasicBlock successorBlock = successors.get(i); - BasicBlock leaderOfFallsthroughBlocks = successorBlock; - while (true) { - final List> itPreds = - leaderOfFallsthroughBlocks.getPredecessors(); - - BasicBlock finalLeaderOfFallsthroughBlocks = leaderOfFallsthroughBlocks; - final Optional> fallsthroughPredOpt = - itPreds.stream() - .filter( - b -> - b.getTail().fallsThrough() - && b.getSuccessors().get(0) == finalLeaderOfFallsthroughBlocks) - .findAny(); - if (!fallsthroughPredOpt.isPresent()) { - break; - } - BasicBlock predecessorBlock = fallsthroughPredOpt.get(); - if (predecessorBlock.getTail().fallsThrough() - && predecessorBlock.getSuccessors().get(0) == leaderOfFallsthroughBlocks) { - leaderOfFallsthroughBlocks = predecessorBlock; - } else { - break; - } - } - - // find a return Stmt inside the current Block - Stmt succTailStmt = successorBlock.getTail(); - boolean isReturnBlock = - succTailStmt instanceof JReturnVoidStmt || succTailStmt instanceof JReturnStmt; - - // remember branching successors - if (tailStmt instanceof JGotoStmt) { - if (isReturnBlock) { - nestedBlocks.removeFirstOccurrence(currentBlock); - otherBlocks.addLast(leaderOfFallsthroughBlocks); - } else { - otherBlocks.addFirst(leaderOfFallsthroughBlocks); - } - } else if (!nestedBlocks.contains(leaderOfFallsthroughBlocks)) { - // JSwitchStmt, JIfStmt - if (isReturnBlock) { - nestedBlocks.addLast(leaderOfFallsthroughBlocks); - } else { - nestedBlocks.addFirst(leaderOfFallsthroughBlocks); - } - } - } + BasicBlock predecessorBlock = fallsthroughPredOpt.get(); + if (predecessorBlock.getTail().fallsThrough() + && predecessorBlock.getSuccessors().get(0) == leaderOfFallsthroughBlocks) { + leaderOfFallsthroughBlocks = predecessorBlock; + } else { + break; } - } - - @Override - public boolean hasNext() { - final boolean hasIteratorMoreElements; - BasicBlock b = retrieveNextBlock(); - if (b != null) { - // reinsert at FIRST position -> not great for performance - but easier handling in - // next() - nestedBlocks.addFirst(b); - hasIteratorMoreElements = true; + } + + // find a return Stmt inside the current Block + Stmt succTailStmt = successorBlock.getTail(); + boolean isReturnBlock = + succTailStmt instanceof JReturnVoidStmt || succTailStmt instanceof JReturnStmt; + + // remember branching successors + if (tailStmt instanceof JGotoStmt) { + if (isReturnBlock) { + nestedBlocks.removeFirstOccurrence(currentBlock); + otherBlocks.addLast(leaderOfFallsthroughBlocks); } else { - hasIteratorMoreElements = false; + otherBlocks.addFirst(leaderOfFallsthroughBlocks); } - - // "assertion" that all elements are iterated - if (!hasIteratorMoreElements) { - final int returnedSize = iteratedBlocks.size(); - final Collection> blocks = getBlocks(); - final int actualSize = blocks.size(); - if (returnedSize != actualSize) { - String info = - blocks.stream() - .filter(n -> !iteratedBlocks.contains(n)) - .map(BasicBlock::getStmts) - .collect(Collectors.toList()) - .toString(); - throw new IllegalStateException( - "There are " - + (actualSize - returnedSize) - + " Blocks that are not iterated! i.e. the StmtGraph is not connected from its startingStmt!" - + info - + DotExporter.createUrlToWebeditor(StmtGraph.this)); - } + } else if (!nestedBlocks.contains(leaderOfFallsthroughBlocks)) { + // JSwitchStmt, JIfStmt + if (isReturnBlock) { + nestedBlocks.addLast(leaderOfFallsthroughBlocks); + } else { + nestedBlocks.addFirst(leaderOfFallsthroughBlocks); } - return hasIteratorMoreElements; + } } + } } - /** - * Returns the result of iterating through all Stmts in this body. All Stmts thus found are - * returned. Branching Stmts and statements which use PhiExpr will have Stmts; a Stmt contains a - * Stmt that is either a target of a branch or is being used as a pointer to the end of a CFG - * block. - * - *

This method was typically used for pointer patching, e.g. when the unit chain is cloned. - * - * @return A collection of all the Stmts that are targets of a BranchingStmt - */ - @Nonnull - public Collection getLabeledStmts() { - Set stmtList = new HashSet<>(); - for (Stmt stmt : getNodes()) { - if (stmt instanceof BranchingStmt) { - if (stmt instanceof JIfStmt) { - // [ms] bounds are validated in Body - stmtList.add(getBranchTargetsOf((JIfStmt) stmt).get(0)); - } else if (stmt instanceof JGotoStmt) { - // [ms] bounds are validated in Body if its a valid StmtGraph - stmtList.add(getBranchTargetsOf((JGotoStmt) stmt).get(0)); - } else if (stmt instanceof JSwitchStmt) { - stmtList.addAll(getBranchTargetsOf((BranchingStmt) stmt)); - } - } + @Override + public boolean hasNext() { + final boolean hasIteratorMoreElements; + BasicBlock b = retrieveNextBlock(); + if (b != null) { + // reinsert at FIRST position -> not great for performance - but easier handling in + // next() + nestedBlocks.addFirst(b); + hasIteratorMoreElements = true; + } else { + hasIteratorMoreElements = false; + } + + // "assertion" that all elements are iterated + if (!hasIteratorMoreElements) { + final int returnedSize = iteratedBlocks.size(); + final Collection> blocks = getBlocks(); + final int actualSize = blocks.size(); + if (returnedSize != actualSize) { + String info = + blocks.stream() + .filter(n -> !iteratedBlocks.contains(n)) + .map(BasicBlock::getStmts) + .collect(Collectors.toList()) + .toString(); + throw new IllegalStateException( + "There are " + + (actualSize - returnedSize) + + " Blocks that are not iterated! i.e. the StmtGraph is not connected from its startingStmt!" + + info + + DotExporter.createUrlToWebeditor(StmtGraph.this)); } - - for (Trap trap : getTraps()) { - stmtList.add(trap.getBeginStmt()); - stmtList.add(trap.getEndStmt()); - stmtList.add(trap.getHandlerStmt()); + } + return hasIteratorMoreElements; + } + } + + /** + * Returns the result of iterating through all Stmts in this body. All Stmts thus found are + * returned. Branching Stmts and statements which use PhiExpr will have Stmts; a Stmt contains a + * Stmt that is either a target of a branch or is being used as a pointer to the end of a CFG + * block. + * + *

This method was typically used for pointer patching, e.g. when the unit chain is cloned. + * + * @return A collection of all the Stmts that are targets of a BranchingStmt + */ + @Nonnull + public Collection getLabeledStmts() { + Set stmtList = new HashSet<>(); + for (Stmt stmt : getNodes()) { + if (stmt instanceof BranchingStmt) { + if (stmt instanceof JIfStmt) { + // [ms] bounds are validated in Body + stmtList.add(getBranchTargetsOf((JIfStmt) stmt).get(0)); + } else if (stmt instanceof JGotoStmt) { + // [ms] bounds are validated in Body if its a valid StmtGraph + stmtList.add(getBranchTargetsOf((JGotoStmt) stmt).get(0)); + } else if (stmt instanceof JSwitchStmt) { + stmtList.addAll(getBranchTargetsOf((BranchingStmt) stmt)); } + } + } - return stmtList; + for (Trap trap : getTraps()) { + stmtList.add(trap.getBeginStmt()); + stmtList.add(trap.getEndStmt()); + stmtList.add(trap.getHandlerStmt()); } - @Override - public String toString() { - StringWriter writer = new StringWriter(); - try (PrintWriter writerOut = new PrintWriter(new EscapedWriter(writer))) { - new JimplePrinter().printTo(this, writerOut); - } - return writer.toString(); + return stmtList; + } + + @Override + public String toString() { + StringWriter writer = new StringWriter(); + try (PrintWriter writerOut = new PrintWriter(new EscapedWriter(writer))) { + new JimplePrinter().printTo(this, writerOut); } + return writer.toString(); + } } diff --git a/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java b/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java index 261794c40f7..3184049fdfb 100644 --- a/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java +++ b/sootup.core/src/test/java/sootup/core/graph/MutableBlockStmtGraphTest.java @@ -629,7 +629,8 @@ public PackageName getPackageName() { graph1.putEdge(stmt2, JGotoStmt.BRANCH_IDX, returnStmt); graph1.putEdge(stmt3, JGotoStmt.BRANCH_IDX, returnStmt); - // FIXME:: check if this StmtGraph structure is even valid.. at least the part that is necessary for the test or if the order from Blocks/Stmts in Stmt.Iterator needs to be adapted + // FIXME:: check if this StmtGraph structure is even valid.. at least the part that is necessary + // for the test or if the order from Blocks/Stmts in Stmt.Iterator needs to be adapted /*{ final List traps = graph1.getTraps(); final Trap containedTrap = new Trap(exception1, stmt2, catchStmt1, catchStmt2); @@ -667,7 +668,6 @@ public PackageName getPackageName() { { final List traps = graph3.getTraps(); assertEquals(5, graph2.getBlocks().size()); - System.out.println(traps); assertEquals(2, traps.size()); } diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java index 5d0c6ba1d6d..694ecb35f40 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java @@ -73,8 +73,6 @@ public class UnreachableCodeEliminatorTest { FallsThroughStmt endStmt = JavaJimple.newAssignStmt(l4, IntConstant.getInstance(4), noStmtPositionInfo); - Trap trap2 = JavaJimple.newTrap(exception, beginStmt, beginStmt, handlerStmt); - /** * Test the simpleBody l0:= @this Test -> l1 = 1 -> return l2 = 2 -> l3 = 3 -> return l2 = 2 and * l3 = 3 are unreachable From 718ae93c006515b0a49cc2709459dd5b0dd345fa Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 22 Jan 2024 12:04:31 +0100 Subject: [PATCH 41/57] Errormsg++ --- sootup.core/src/main/java/sootup/core/graph/StmtGraph.java | 4 ++-- .../bytecode/interceptors/UnreachableCodeEliminatorTest.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java b/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java index 0f6c03d1b58..f631a7a1c37 100644 --- a/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java +++ b/sootup.core/src/main/java/sootup/core/graph/StmtGraph.java @@ -485,10 +485,10 @@ public List getTraps() { throw new IllegalStateException("Iterator needs to be iterated completely!"); } - // check for dangling trap data + // check for dangling traps that are not collected as the endStmt was not visited. if (!trapStarts.isEmpty()) { throw new IllegalArgumentException( - "Invalid StmtGraph. A Trap is not created. Maybe a Traprange covers the last Stmt as well, which is not possible."); + "Invalid StmtGraph. A Trap is not created as a traps endStmt was not visited during the iteration of all Stmts."); } return collectedTraps; } diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java index 694ecb35f40..95248d05d72 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/UnreachableCodeEliminatorTest.java @@ -12,7 +12,6 @@ import sootup.core.jimple.basic.Local; import sootup.core.jimple.basic.NoPositionInformation; import sootup.core.jimple.basic.StmtPositionInfo; -import sootup.core.jimple.basic.Trap; import sootup.core.jimple.common.constant.IntConstant; import sootup.core.jimple.common.ref.IdentityRef; import sootup.core.jimple.common.stmt.BranchingStmt; From 4da38c86872d09d78f918fd62d91bc8081d49a4f Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 22 Jan 2024 12:05:37 +0100 Subject: [PATCH 42/57] fix wrong full qualified classnames coming from the JrtFileSystemAnalysisInputLocation -> Java Runtime Modules --- .../frontend/AsmJavaClassProvider.java | 10 ++++----- .../JrtFileSystemAnalysisInputLocation.java | 21 +++++-------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java index dbe4ba40650..5169fb340d8 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmJavaClassProvider.java @@ -73,13 +73,13 @@ public Optional createClassSource( return Optional.empty(); } - String name = classType.getPackageName().getName(); - String wantedClassSigStr = + String requestedName = classType.getPackageName().getName(); + String requestedFQClassName = classType.getPackageName().getName() - + (name.isEmpty() ? "" : ".") + + (requestedName.isEmpty() ? "" : ".") + classType.getClassName(); - String replace = actualClassSignature.replace('/', '.'); - if (!replace.equals(wantedClassSigStr)) { + String actualFQClassName = actualClassSignature.replace('/', '.'); + if (!actualFQClassName.equals(requestedFQClassName)) { logger.warn( "The given Classtype '" + classType diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java index 8b4c24234a3..6591ed5a71b 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java @@ -52,8 +52,9 @@ */ public class JrtFileSystemAnalysisInputLocation implements ModuleInfoAnalysisInputLocation { + // FIXME: handle closing the filesystem resource private static final FileSystem theFileSystem = FileSystems.getFileSystem(URI.create("jrt:/")); - Map moduleInfoMap = new HashMap<>(); + private final Map moduleInfoMap = new HashMap<>(); boolean isResolved = false; @Nonnull private final SourceType sourceType; @@ -131,7 +132,6 @@ public Optional getClassSource( public Collection getModulesClassSources( @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { return getClassSourcesInternal(moduleSignature, view.getIdentifierFactory(), view) - .map(src -> (JavaSootClassSource) src) .collect(Collectors.toList()); } @@ -219,11 +219,9 @@ public Collection discoverModules() { private JavaClassType fromPath( final Path filename, final Path moduleDir, final IdentifierFactory identifierFactory) { - // else use the module system and create fully class signature - // we do not have a base directory here, the moduleDir is actually not a directory - final Path rootDirectory = Paths.get(""); - - final String fullyQualifiedName = fromPath(rootDirectory, filename); + final String fullyQualifiedName = FilenameUtils.removeExtension( + filename.toString() + .replace(filename.getFileSystem().getSeparator(), ".")); JavaClassType sig = (JavaClassType) identifierFactory.getClassType(fullyQualifiedName); @@ -236,15 +234,6 @@ private JavaClassType fromPath( return sig; } - @Nonnull - private static String fromPath(@Nonnull Path rootDirectory, @Nonnull Path filename) { - return FilenameUtils.removeExtension( - filename - .subpath(rootDirectory.getNameCount(), filename.getNameCount()) - .toString() - .replace(filename.getFileSystem().getSeparator(), ".")); - } - @Nonnull @Override public Optional getModuleInfo(ModuleSignature sig, View view) { From 5b5c0627c9caa62c02dc76a2b9487a9d92a76432 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 22 Jan 2024 12:11:50 +0100 Subject: [PATCH 43/57] =?UTF-8?q?"Fashions=20fade,=20style=20is=20eternal.?= =?UTF-8?q?"=20=E2=80=94=20YSL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inputlocation/JrtFileSystemAnalysisInputLocation.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java index 6591ed5a71b..bc1d35687e3 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java @@ -219,9 +219,9 @@ public Collection discoverModules() { private JavaClassType fromPath( final Path filename, final Path moduleDir, final IdentifierFactory identifierFactory) { - final String fullyQualifiedName = FilenameUtils.removeExtension( - filename.toString() - .replace(filename.getFileSystem().getSeparator(), ".")); + final String fullyQualifiedName = + FilenameUtils.removeExtension( + filename.toString().replace(filename.getFileSystem().getSeparator(), ".")); JavaClassType sig = (JavaClassType) identifierFactory.getClassType(fullyQualifiedName); From 6b04c93f92b2a017ebb368a44e0857b970787c0a Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 22 Jan 2024 14:59:14 +0100 Subject: [PATCH 44/57] remove obsolete copyable interface --- .../jimple/basic/FullStmtPositionInfo.java | 3 +- .../java/sootup/core/jimple/basic/Local.java | 3 +- .../java/sootup/core/jimple/basic/Trap.java | 3 +- .../jimple/common/constant/MethodType.java | 3 +- .../core/jimple/common/expr/JAddExpr.java | 3 +- .../core/jimple/common/expr/JAndExpr.java | 3 +- .../core/jimple/common/expr/JCastExpr.java | 3 +- .../core/jimple/common/expr/JCmpExpr.java | 3 +- .../core/jimple/common/expr/JCmpgExpr.java | 3 +- .../core/jimple/common/expr/JCmplExpr.java | 3 +- .../core/jimple/common/expr/JDivExpr.java | 3 +- .../common/expr/JDynamicInvokeExpr.java | 3 +- .../core/jimple/common/expr/JEqExpr.java | 3 +- .../core/jimple/common/expr/JGeExpr.java | 3 +- .../core/jimple/common/expr/JGtExpr.java | 3 +- .../jimple/common/expr/JInstanceOfExpr.java | 3 +- .../common/expr/JInterfaceInvokeExpr.java | 3 +- .../core/jimple/common/expr/JLeExpr.java | 3 +- .../core/jimple/common/expr/JLengthExpr.java | 3 +- .../core/jimple/common/expr/JLtExpr.java | 3 +- .../core/jimple/common/expr/JMulExpr.java | 3 +- .../core/jimple/common/expr/JNeExpr.java | 3 +- .../core/jimple/common/expr/JNegExpr.java | 3 +- .../jimple/common/expr/JNewArrayExpr.java | 3 +- .../core/jimple/common/expr/JNewExpr.java | 3 +- .../common/expr/JNewMultiArrayExpr.java | 4 +- .../core/jimple/common/expr/JOrExpr.java | 3 +- .../core/jimple/common/expr/JPhiExpr.java | 3 +- .../core/jimple/common/expr/JRemExpr.java | 3 +- .../core/jimple/common/expr/JShlExpr.java | 3 +- .../core/jimple/common/expr/JShrExpr.java | 3 +- .../common/expr/JSpecialInvokeExpr.java | 3 +- .../jimple/common/expr/JStaticInvokeExpr.java | 3 +- .../core/jimple/common/expr/JSubExpr.java | 3 +- .../core/jimple/common/expr/JUshrExpr.java | 3 +- .../common/expr/JVirtualInvokeExpr.java | 3 +- .../core/jimple/common/expr/JXorExpr.java | 3 +- .../core/jimple/common/ref/JArrayRef.java | 3 +- .../common/ref/JCaughtExceptionRef.java | 3 +- .../jimple/common/ref/JInstanceFieldRef.java | 4 +- .../core/jimple/common/ref/JParameterRef.java | 3 +- .../jimple/common/ref/JStaticFieldRef.java | 3 +- .../core/jimple/common/ref/JThisRef.java | 3 +- .../sootup/core/jimple/common/stmt/Stmt.java | 3 +- .../src/main/java/sootup/core/model/Body.java | 4 +- .../java/sootup/core/model/SootMethod.java | 3 +- .../main/java/sootup/core/util/Copyable.java | 58 ------------------- 47 files changed, 46 insertions(+), 153 deletions(-) delete mode 100644 sootup.core/src/main/java/sootup/core/util/Copyable.java diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java b/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java index 98dab8e2641..54ca76d8e12 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java +++ b/sootup.core/src/main/java/sootup/core/jimple/basic/FullStmtPositionInfo.java @@ -24,7 +24,6 @@ import javax.annotation.Nonnull; import sootup.core.model.Position; -import sootup.core.util.Copyable; /** * This class stores position information stored for a statement. line number + information about @@ -32,7 +31,7 @@ * * @author Linghui Luo, Markus Schmidt */ -public class FullStmtPositionInfo extends SimpleStmtPositionInfo implements Copyable { +public class FullStmtPositionInfo extends SimpleStmtPositionInfo { @Nonnull protected final Position[] operandPositions; /** diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/Local.java b/sootup.core/src/main/java/sootup/core/jimple/basic/Local.java index 2cb07ae5ea2..079d9ace828 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/basic/Local.java +++ b/sootup.core/src/main/java/sootup/core/jimple/basic/Local.java @@ -33,7 +33,6 @@ import sootup.core.model.Body; import sootup.core.types.Type; import sootup.core.types.VoidType; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** @@ -43,7 +42,7 @@ * * @author Linghui Luo */ -public class Local implements Immediate, LValue, Copyable, Acceptor { +public class Local implements Immediate, LValue, Acceptor { @Nonnull private final String name; @Nonnull private final Type type; diff --git a/sootup.core/src/main/java/sootup/core/jimple/basic/Trap.java b/sootup.core/src/main/java/sootup/core/jimple/basic/Trap.java index 3d31d0abbf7..5ee3dde9800 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/basic/Trap.java +++ b/sootup.core/src/main/java/sootup/core/jimple/basic/Trap.java @@ -27,14 +27,13 @@ import sootup.core.jimple.Jimple; import sootup.core.jimple.common.stmt.Stmt; import sootup.core.types.ClassType; -import sootup.core.util.Copyable; /** * Represents a try-catch construct. * *

Prefer to use the factory methods in {@link Jimple}. */ -public final class Trap implements Copyable { +public final class Trap { /** The exception being caught. */ @Nonnull private final ClassType exception; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodType.java b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodType.java index 8a5b0bd689a..49ad88426aa 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodType.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/constant/MethodType.java @@ -29,9 +29,8 @@ import sootup.core.signatures.MethodSubSignature; import sootup.core.types.ClassType; import sootup.core.types.Type; -import sootup.core.util.Copyable; -public class MethodType implements Constant, Copyable { +public class MethodType implements Constant { // FIXME: [AD] adapt this class private final Type type; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JAddExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JAddExpr.java index d0da90b20b9..d5db75cfd15 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JAddExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JAddExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that adds two numbers. */ -public final class JAddExpr extends AbstractFloatBinopExpr implements Copyable { +public final class JAddExpr extends AbstractFloatBinopExpr { public JAddExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JAndExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JAndExpr.java index 59d53666619..1de8e46fca6 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JAndExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JAndExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that computes a binary AND of two operands. */ -public final class JAndExpr extends AbstractIntLongBinopExpr implements Copyable { +public final class JAndExpr extends AbstractIntLongBinopExpr { public JAndExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCastExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCastExpr.java index c1fc3a03b86..1cd49a340bd 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCastExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCastExpr.java @@ -30,11 +30,10 @@ import sootup.core.jimple.basic.Value; import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that casts a value to a certain type. */ -public final class JCastExpr implements Expr, Copyable { +public final class JCastExpr implements Expr { private final Immediate op; private final Type type; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmpExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmpExpr.java index 3aa9c0b83d5..4662b226954 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmpExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmpExpr.java @@ -26,9 +26,8 @@ import sootup.core.jimple.Jimple; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; -public final class JCmpExpr extends AbstractIntBinopExpr implements Copyable { +public final class JCmpExpr extends AbstractIntBinopExpr { public JCmpExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmpgExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmpgExpr.java index 3c71803b66a..e95e068305e 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmpgExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmpgExpr.java @@ -26,9 +26,8 @@ import sootup.core.jimple.Jimple; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; -public final class JCmpgExpr extends AbstractIntBinopExpr implements Copyable { +public final class JCmpgExpr extends AbstractIntBinopExpr { public JCmpgExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmplExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmplExpr.java index d73f93025cf..8b9a9d98cc4 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmplExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JCmplExpr.java @@ -26,9 +26,8 @@ import sootup.core.jimple.Jimple; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; -public final class JCmplExpr extends AbstractIntBinopExpr implements Copyable { +public final class JCmplExpr extends AbstractIntBinopExpr { public JCmplExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JDivExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JDivExpr.java index 02cfc8639d1..0078831b6cf 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JDivExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JDivExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that divides a number by another. */ -public final class JDivExpr extends AbstractFloatBinopExpr implements Copyable { +public final class JDivExpr extends AbstractFloatBinopExpr { public JDivExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JDynamicInvokeExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JDynamicInvokeExpr.java index d75729fade0..5a1f5c73788 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JDynamicInvokeExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JDynamicInvokeExpr.java @@ -32,11 +32,10 @@ import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.signatures.MethodSignature; import sootup.core.signatures.MethodSubSignature; -import sootup.core.util.Copyable; import sootup.core.util.ImmutableUtils; import sootup.core.util.printer.StmtPrinter; -public final class JDynamicInvokeExpr extends AbstractInvokeExpr implements Copyable { +public final class JDynamicInvokeExpr extends AbstractInvokeExpr { @Nonnull public static final String INVOKEDYNAMIC_DUMMY_CLASS_NAME = "sootup.dummy.InvokeDynamic"; @Nonnull private final MethodSignature bootstrapMethodSignature; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JEqExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JEqExpr.java index a05acf75b3b..427eb1d8b7f 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JEqExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JEqExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that checks whether two value are equal. */ -public final class JEqExpr extends AbstractConditionExpr implements Copyable { +public final class JEqExpr extends AbstractConditionExpr { public JEqExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JGeExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JGeExpr.java index 9544bf8eae3..fab195e3bc4 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JGeExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JGeExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that checks whether operand 1 >= operand 2. */ -public final class JGeExpr extends AbstractConditionExpr implements Copyable { +public final class JGeExpr extends AbstractConditionExpr { public JGeExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JGtExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JGtExpr.java index 238730642cd..5ef14d09653 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JGtExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JGtExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that checks whether operand 1 > operand 2. */ -public final class JGtExpr extends AbstractConditionExpr implements Copyable { +public final class JGtExpr extends AbstractConditionExpr { public JGtExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JInstanceOfExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JInstanceOfExpr.java index fa67cf57c1c..7f8fb98c346 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JInstanceOfExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JInstanceOfExpr.java @@ -32,11 +32,10 @@ import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.types.PrimitiveType; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that checks whether a value is of a certain type. */ -public final class JInstanceOfExpr implements Expr, Copyable { +public final class JInstanceOfExpr implements Expr { private final Immediate op; private final Type checkType; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JInterfaceInvokeExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JInterfaceInvokeExpr.java index e8c677280ad..3f9fedf8799 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JInterfaceInvokeExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JInterfaceInvokeExpr.java @@ -36,11 +36,10 @@ import sootup.core.jimple.basic.Local; import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.signatures.MethodSignature; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that invokes an interface method. */ -public final class JInterfaceInvokeExpr extends AbstractInstanceInvokeExpr implements Copyable { +public final class JInterfaceInvokeExpr extends AbstractInstanceInvokeExpr { /** methodArgs to an array args. */ public JInterfaceInvokeExpr( diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLeExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLeExpr.java index aea6cd63de0..63533ceb454 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLeExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLeExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that checks whether operand 1 <= operand 2. */ -public final class JLeExpr extends AbstractConditionExpr implements Copyable { +public final class JLeExpr extends AbstractConditionExpr { public JLeExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLengthExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLengthExpr.java index 48817a58f79..643c550abdd 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLengthExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLengthExpr.java @@ -28,11 +28,10 @@ import sootup.core.jimple.basic.JimpleComparator; import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.types.PrimitiveType; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that returns the length of an array. */ -public final class JLengthExpr extends AbstractUnopExpr implements Copyable { +public final class JLengthExpr extends AbstractUnopExpr { public JLengthExpr(@Nonnull Immediate op) { super(op); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLtExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLtExpr.java index 2923d28586f..9cdae61edc5 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLtExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JLtExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that checks whether operand 1 < operand 2. */ -public final class JLtExpr extends AbstractConditionExpr implements Copyable { +public final class JLtExpr extends AbstractConditionExpr { public JLtExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JMulExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JMulExpr.java index 1978279d15f..6202a191295 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JMulExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JMulExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that multiplies two numbers. */ -public final class JMulExpr extends AbstractFloatBinopExpr implements Copyable { +public final class JMulExpr extends AbstractFloatBinopExpr { public JMulExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNeExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNeExpr.java index d97fd60e39a..9e3e1cc0ef2 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNeExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNeExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** The opposite of {@link JEqExpr} */ -public final class JNeExpr extends AbstractConditionExpr implements Copyable { +public final class JNeExpr extends AbstractConditionExpr { public JNeExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNegExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNegExpr.java index c10ef2d8c0d..7466b08913c 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNegExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNegExpr.java @@ -31,11 +31,10 @@ import sootup.core.types.PrimitiveType; import sootup.core.types.Type; import sootup.core.types.UnknownType; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that negates its operand (-). */ -public final class JNegExpr extends AbstractUnopExpr implements Copyable { +public final class JNegExpr extends AbstractUnopExpr { public JNegExpr(@Nonnull Immediate op) { super(op); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewArrayExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewArrayExpr.java index 3baf4c432bb..9f9d07683c9 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewArrayExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewArrayExpr.java @@ -33,11 +33,10 @@ import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.types.ArrayType; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that creates a new array of a certain type and a certain size. */ -public final class JNewArrayExpr implements Expr, Copyable { +public final class JNewArrayExpr implements Expr { @Nonnull private final Type baseType; @Nonnull private final Immediate size; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewExpr.java index 2a8bad17cfb..3cdd93c9927 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewExpr.java @@ -30,11 +30,10 @@ import sootup.core.jimple.basic.Value; import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.types.ClassType; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that creates a new instance of a class. */ -public final class JNewExpr implements Expr, Copyable { +public final class JNewExpr implements Expr { @Nonnull private final ClassType type; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewMultiArrayExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewMultiArrayExpr.java index 1be30ab14ce..26180e52864 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewMultiArrayExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JNewMultiArrayExpr.java @@ -26,18 +26,16 @@ import java.util.List; import javax.annotation.Nonnull; import sootup.core.jimple.Jimple; -import sootup.core.jimple.basic.*; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.basic.JimpleComparator; import sootup.core.jimple.basic.Value; import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.types.ArrayType; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** Like {@link JNewArrayExpr}, but for multi-dimensional arrays. */ -public final class JNewMultiArrayExpr implements Expr, Copyable { +public final class JNewMultiArrayExpr implements Expr { private final ArrayType baseType; private final List sizes; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JOrExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JOrExpr.java index 68e11dec3a7..8f5f9d31526 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JOrExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JOrExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that computes a binary OR of two operands. */ -public final class JOrExpr extends AbstractIntLongBinopExpr implements Copyable { +public final class JOrExpr extends AbstractIntLongBinopExpr { public JOrExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JPhiExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JPhiExpr.java index 46dcfa8c293..b4593528cc2 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JPhiExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JPhiExpr.java @@ -32,11 +32,10 @@ import sootup.core.jimple.basic.Value; import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** @author Zun Wang */ -public final class JPhiExpr implements Expr, Copyable { +public final class JPhiExpr implements Expr { private final List args; private final Map, Local> blockToArg = new HashMap<>(); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JRemExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JRemExpr.java index d491ca0171b..23998b875d1 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JRemExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JRemExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that computes a % b. */ -public final class JRemExpr extends AbstractFloatBinopExpr implements Copyable { +public final class JRemExpr extends AbstractFloatBinopExpr { public JRemExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JShlExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JShlExpr.java index 96ecfb5503c..5d0e526045f 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JShlExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JShlExpr.java @@ -29,10 +29,9 @@ import sootup.core.types.PrimitiveType; import sootup.core.types.Type; import sootup.core.types.UnknownType; -import sootup.core.util.Copyable; /** An expression that shifts its operand to the left (<<). */ -public final class JShlExpr extends AbstractIntLongBinopExpr implements Copyable { +public final class JShlExpr extends AbstractIntLongBinopExpr { public JShlExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JShrExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JShrExpr.java index ee1030496ae..087a3af5233 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JShrExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JShrExpr.java @@ -29,10 +29,9 @@ import sootup.core.types.PrimitiveType; import sootup.core.types.Type; import sootup.core.types.UnknownType; -import sootup.core.util.Copyable; /** An expression that shifts its operand to the left (>>). */ -public final class JShrExpr extends AbstractIntLongBinopExpr implements Copyable { +public final class JShrExpr extends AbstractIntLongBinopExpr { public JShrExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JSpecialInvokeExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JSpecialInvokeExpr.java index ce423df897e..3bd417c76fe 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JSpecialInvokeExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JSpecialInvokeExpr.java @@ -30,11 +30,10 @@ import sootup.core.jimple.basic.Local; import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.signatures.MethodSignature; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that invokes a special method (e.g. private methods). */ -public final class JSpecialInvokeExpr extends AbstractInstanceInvokeExpr implements Copyable { +public final class JSpecialInvokeExpr extends AbstractInstanceInvokeExpr { public JSpecialInvokeExpr( @Nonnull Local base, @Nonnull MethodSignature method, @Nonnull List args) { diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JStaticInvokeExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JStaticInvokeExpr.java index b6e030692dd..08e25e168d3 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JStaticInvokeExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JStaticInvokeExpr.java @@ -29,11 +29,10 @@ import sootup.core.jimple.basic.JimpleComparator; import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.signatures.MethodSignature; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that invokes a static method. */ -public final class JStaticInvokeExpr extends AbstractInvokeExpr implements Copyable { +public final class JStaticInvokeExpr extends AbstractInvokeExpr { /** Stores the values to the args array. */ public JStaticInvokeExpr(@Nonnull MethodSignature method, @Nonnull List args) { diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JSubExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JSubExpr.java index 2ab830502ce..a9cf646d427 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JSubExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JSubExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that subtracts operand 2 from operand 1. */ -public final class JSubExpr extends AbstractFloatBinopExpr implements Copyable { +public final class JSubExpr extends AbstractFloatBinopExpr { public JSubExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JUshrExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JUshrExpr.java index 01e9c2d2153..f7b9e7cf1e7 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JUshrExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JUshrExpr.java @@ -29,10 +29,9 @@ import sootup.core.types.PrimitiveType; import sootup.core.types.Type; import sootup.core.types.UnknownType; -import sootup.core.util.Copyable; /** Similar to {@link JShrExpr}, but shifts zero into the leftmost position. */ -public final class JUshrExpr extends AbstractIntLongBinopExpr implements Copyable { +public final class JUshrExpr extends AbstractIntLongBinopExpr { public JUshrExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); } diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JVirtualInvokeExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JVirtualInvokeExpr.java index cc2dba3ff6b..e3ca02a382e 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JVirtualInvokeExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JVirtualInvokeExpr.java @@ -30,11 +30,10 @@ import sootup.core.jimple.basic.Local; import sootup.core.jimple.visitor.ExprVisitor; import sootup.core.signatures.MethodSignature; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** An expression that invokes a virtual method. */ -public final class JVirtualInvokeExpr extends AbstractInstanceInvokeExpr implements Copyable { +public final class JVirtualInvokeExpr extends AbstractInstanceInvokeExpr { /** Stores the values to the args array. */ public JVirtualInvokeExpr( diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JXorExpr.java b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JXorExpr.java index 4856ebe1ca2..1eb9cabcdf3 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/expr/JXorExpr.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/expr/JXorExpr.java @@ -25,10 +25,9 @@ import javax.annotation.Nonnull; import sootup.core.jimple.basic.Immediate; import sootup.core.jimple.visitor.ExprVisitor; -import sootup.core.util.Copyable; /** An expression that computes a binary XOR of two operands. */ -public final class JXorExpr extends AbstractIntLongBinopExpr implements Copyable { +public final class JXorExpr extends AbstractIntLongBinopExpr { public JXorExpr(@Nonnull Immediate op1, @Nonnull Immediate op2) { super(op1, op2); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JArrayRef.java b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JArrayRef.java index 43e4d641590..7ff5cdfcf39 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JArrayRef.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JArrayRef.java @@ -28,10 +28,9 @@ import sootup.core.jimple.basic.*; import sootup.core.jimple.visitor.RefVisitor; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; -public final class JArrayRef implements ConcreteRef, LValue, Copyable { +public final class JArrayRef implements ConcreteRef, LValue { private final Local base; private final Immediate index; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JCaughtExceptionRef.java b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JCaughtExceptionRef.java index c07f6df1d02..70b6b1ba94f 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JCaughtExceptionRef.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JCaughtExceptionRef.java @@ -29,10 +29,9 @@ import sootup.core.jimple.basic.Value; import sootup.core.jimple.visitor.RefVisitor; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; -public final class JCaughtExceptionRef implements IdentityRef, Copyable { +public final class JCaughtExceptionRef implements IdentityRef { private final Type type; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JInstanceFieldRef.java b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JInstanceFieldRef.java index 3c6ac8f284d..95411c2f161 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JInstanceFieldRef.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JInstanceFieldRef.java @@ -30,15 +30,13 @@ import java.util.List; import javax.annotation.Nonnull; import sootup.core.jimple.basic.JimpleComparator; -import sootup.core.jimple.basic.LValue; import sootup.core.jimple.basic.Local; import sootup.core.jimple.basic.Value; import sootup.core.jimple.visitor.RefVisitor; import sootup.core.signatures.FieldSignature; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; -public final class JInstanceFieldRef extends JFieldRef implements LValue, Copyable { +public final class JInstanceFieldRef extends JFieldRef { private final Local base; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JParameterRef.java b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JParameterRef.java index 08125532677..9aafc5236a5 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JParameterRef.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JParameterRef.java @@ -29,7 +29,6 @@ import sootup.core.jimple.basic.Value; import sootup.core.jimple.visitor.RefVisitor; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; /** @@ -39,7 +38,7 @@ *

For instance, in a method, the first statement will often be * this := @parameter0; */ -public final class JParameterRef implements IdentityRef, Copyable { +public final class JParameterRef implements IdentityRef { private final int index; private final Type paramType; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JStaticFieldRef.java b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JStaticFieldRef.java index 8f471346261..fcbc6c5f177 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JStaticFieldRef.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JStaticFieldRef.java @@ -30,10 +30,9 @@ import sootup.core.jimple.basic.Value; import sootup.core.jimple.visitor.RefVisitor; import sootup.core.signatures.FieldSignature; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; -public final class JStaticFieldRef extends JFieldRef implements LValue, Copyable { +public final class JStaticFieldRef extends JFieldRef implements LValue { public JStaticFieldRef(@Nonnull FieldSignature fieldSig) { super(fieldSig); diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JThisRef.java b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JThisRef.java index e49310e433e..2af65662096 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/ref/JThisRef.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/ref/JThisRef.java @@ -30,10 +30,9 @@ import sootup.core.jimple.visitor.RefVisitor; import sootup.core.types.ClassType; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; -public final class JThisRef implements IdentityRef, Copyable { +public final class JThisRef implements IdentityRef { private final ClassType thisType; diff --git a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/Stmt.java b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/Stmt.java index 36c4d2cad90..9e6b6140b1c 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/common/stmt/Stmt.java +++ b/sootup.core/src/main/java/sootup/core/jimple/common/stmt/Stmt.java @@ -31,10 +31,9 @@ import sootup.core.jimple.common.ref.JFieldRef; import sootup.core.jimple.visitor.Acceptor; import sootup.core.jimple.visitor.StmtVisitor; -import sootup.core.util.Copyable; import sootup.core.util.printer.StmtPrinter; -public interface Stmt extends EquivTo, Acceptor, Copyable { +public interface Stmt extends EquivTo, Acceptor { @Nonnull List getUses(); diff --git a/sootup.core/src/main/java/sootup/core/model/Body.java b/sootup.core/src/main/java/sootup/core/model/Body.java index 4553dccc82e..30deb635bc2 100644 --- a/sootup.core/src/main/java/sootup/core/model/Body.java +++ b/sootup.core/src/main/java/sootup/core/model/Body.java @@ -36,17 +36,15 @@ import sootup.core.jimple.common.ref.JThisRef; import sootup.core.jimple.common.stmt.*; import sootup.core.signatures.MethodSignature; -import sootup.core.util.Copyable; import sootup.core.util.EscapedWriter; import sootup.core.util.printer.JimplePrinter; -import sootup.core.validation.*; /** * Class that models the Jimple body (code attribute) of a method. * * @author Linghui Luo */ -public class Body implements Copyable, HasPosition { +public class Body implements HasPosition { /** The locals for this Body. */ private final Set locals; diff --git a/sootup.core/src/main/java/sootup/core/model/SootMethod.java b/sootup.core/src/main/java/sootup/core/model/SootMethod.java index 8c85253e4aa..5f8f9a53c0f 100644 --- a/sootup.core/src/main/java/sootup/core/model/SootMethod.java +++ b/sootup.core/src/main/java/sootup/core/model/SootMethod.java @@ -44,7 +44,6 @@ import sootup.core.signatures.MethodSubSignature; import sootup.core.types.ClassType; import sootup.core.types.Type; -import sootup.core.util.Copyable; import sootup.core.util.ImmutableUtils; import sootup.core.util.printer.StmtPrinter; @@ -56,7 +55,7 @@ * @author Linghui Luo * @author Jan Martin Persch */ -public class SootMethod extends SootClassMember implements Method, Copyable { +public class SootMethod extends SootClassMember implements Method { @Nonnull private final ImmutableSet modifiers; /** diff --git a/sootup.core/src/main/java/sootup/core/util/Copyable.java b/sootup.core/src/main/java/sootup/core/util/Copyable.java deleted file mode 100644 index c1f8eaa86d5..00000000000 --- a/sootup.core/src/main/java/sootup/core/util/Copyable.java +++ /dev/null @@ -1,58 +0,0 @@ -package sootup.core.util; - -/*- - * #%L - * Soot - a J*va Optimization Framework - * %% - * Copyright (C) 2019-2020 Christian Brüggemann - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 2.1 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * . - * #L% - */ - -// TODO: [ms] Copyable makes no sense anymore as all stmts are immutable - -/** - * Marker interface for final classes that are immutable and can be copied. For instance: - * - *

- *   final class Foo {
- *     private final Bar bar;
- *     private final Baz baz;
- *
- *     public Foo(Bar bar, Baz baz) {
- *       this.bar = bar;
- *       this.baz = baz;
- *     }
- *
- *     public Foo withBar(Bar bar) {
- *      return new Foo(bar, baz);
- *     }
- *
- *     public Foo withBaz(Baz baz) {
- *       return new Foo(bar, baz);
- *     }
- *
- *     public Bar getBar() {
- *       return bar;
- *     }
- *
- *     public Baz getBaz() {
- *       return baz;
- *     }
- *   }
- * 
- */ -public interface Copyable {} From cd20d5f8d505af14df7e3ccc544db1feeaf4c68f Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 22 Jan 2024 15:19:26 +0100 Subject: [PATCH 45/57] refactor api --- .../JrtFileSystemAnalysisInputLocation.java | 10 +++++---- .../MultiReleaseJarAnalysisInputLocation.java | 21 +++++++++++++++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java index bc1d35687e3..cd2fa977235 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java @@ -164,8 +164,7 @@ protected Stream getClassSourcesInternal( classProvider.createClassSource( this, p, - this.fromPath( - p.subpath(2, p.getNameCount()), p.subpath(1, 2), identifierFactory)))) + fromPath( p, identifierFactory)))) .map(src -> (JavaSootClassSource) src); } catch (IOException e) { throw new ResolveException("Error loading module " + moduleSignature, archiveRoot, e); @@ -216,8 +215,10 @@ public Collection discoverModules() { } @Nonnull - private JavaClassType fromPath( - final Path filename, final Path moduleDir, final IdentifierFactory identifierFactory) { + private JavaClassType fromPath( @Nonnull Path p, @Nonnull final IdentifierFactory identifierFactory) { + + final Path moduleDir = p.subpath(1, 2); + final Path filename = p.subpath(2, p.getNameCount()); final String fullyQualifiedName = FilenameUtils.removeExtension( @@ -225,6 +226,7 @@ private JavaClassType fromPath( JavaClassType sig = (JavaClassType) identifierFactory.getClassType(fullyQualifiedName); + // TODO: move to Module version if (identifierFactory instanceof JavaModuleIdentifierFactory) { return ((JavaModuleIdentifierFactory) identifierFactory) .getClassType(sig.getClassName(), sig.getPackageName().getName(), moduleDir.toString()); diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index f954e232572..ed704d39c90 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -24,6 +24,7 @@ import java.io.FileInputStream; import java.io.IOException; +import java.io.PipedReader; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; @@ -62,12 +63,28 @@ public class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisIn @Nonnull protected final Map inputLocations = new LinkedHashMap<>(); + public static ArchiveBasedAnalysisInputLocation create(@Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language){ + if (isMultiReleaseJar(path)) { + return new MultiReleaseJarAnalysisInputLocation( path, srcType, language, true); + } + return new ArchiveBasedAnalysisInputLocation(path, srcType); + } + + public MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nonnull Language language) { + this(path, SourceType.Application, language ); + } + public MultiReleaseJarAnalysisInputLocation( - @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { + @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { + this(path,srcType,language, isMultiReleaseJar(path) ); + } + + protected MultiReleaseJarAnalysisInputLocation( + @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language, boolean isMultiRelease) { super(path, srcType); this.language = language; - if (!isMultiReleaseJar(path)) { + if (!isMultiRelease) { throw new IllegalArgumentException("The given path does not point to a multi release jar."); } From b8c11eb8853ae19338645b0627827f075bd87368 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 23 Jan 2024 10:35:30 +0100 Subject: [PATCH 46/57] improve api - make available versions static --- .../JrtFileSystemAnalysisInputLocation.java | 10 +- .../MultiReleaseJarAnalysisInputLocation.java | 115 ++++++++++++------ 2 files changed, 85 insertions(+), 40 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java index cd2fa977235..d4e38d1d06f 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocation.java @@ -161,10 +161,7 @@ protected Stream getClassSourcesInternal( .flatMap( p -> StreamUtils.optionalToStream( - classProvider.createClassSource( - this, - p, - fromPath( p, identifierFactory)))) + classProvider.createClassSource(this, p, fromPath(p, identifierFactory)))) .map(src -> (JavaSootClassSource) src); } catch (IOException e) { throw new ResolveException("Error loading module " + moduleSignature, archiveRoot, e); @@ -215,10 +212,11 @@ public Collection discoverModules() { } @Nonnull - private JavaClassType fromPath( @Nonnull Path p, @Nonnull final IdentifierFactory identifierFactory) { + private JavaClassType fromPath( + @Nonnull Path p, @Nonnull final IdentifierFactory identifierFactory) { final Path moduleDir = p.subpath(1, 2); - final Path filename = p.subpath(2, p.getNameCount()); + final Path filename = p.subpath(2, p.getNameCount()); final String fullyQualifiedName = FilenameUtils.removeExtension( diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index ed704d39c90..a6feb6a5f16 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -24,7 +24,6 @@ import java.io.FileInputStream; import java.io.IOException; -import java.io.PipedReader; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; @@ -34,12 +33,14 @@ import java.util.jar.Attributes; import java.util.jar.JarInputStream; import java.util.jar.Manifest; +import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nonnull; import sootup.core.Language; import sootup.core.frontend.SootClassSource; import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.model.SourceType; +import sootup.core.transform.BodyInterceptor; import sootup.core.types.ClassType; import sootup.core.views.View; import sootup.java.core.JavaSootClassSource; @@ -58,31 +59,49 @@ public class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAnalysisIn protected static final Integer DEFAULT_VERSION = 0; @Nonnull protected final Language language; - @Nonnull protected final List availableVersions; + @Nonnull private final List bodyInterceptors; @Nonnull protected final Map inputLocations = new LinkedHashMap<>(); - public static ArchiveBasedAnalysisInputLocation create(@Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language){ + public static AnalysisInputLocation create( + @Nonnull Path path, + @Nonnull SourceType srcType, + @Nonnull Language language, + List bodyInterceptors) { if (isMultiReleaseJar(path)) { - return new MultiReleaseJarAnalysisInputLocation( path, srcType, language, true); + return new MultiReleaseJarAnalysisInputLocation( + path, srcType, language, bodyInterceptors, true); } - return new ArchiveBasedAnalysisInputLocation(path, srcType); + return createAnalysisInputLocation(path, srcType, bodyInterceptors); } public MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nonnull Language language) { - this(path, SourceType.Application, language ); + this(path, SourceType.Application, language); } public MultiReleaseJarAnalysisInputLocation( - @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { - this(path,srcType,language, isMultiReleaseJar(path) ); + @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { + this(path, srcType, language, Collections.emptyList()); + } + + public MultiReleaseJarAnalysisInputLocation( + @Nonnull Path path, + @Nonnull SourceType srcType, + @Nonnull Language language, + @Nonnull List bodyInterceptors) { + this(path, srcType, language, bodyInterceptors, isMultiReleaseJar(path)); } protected MultiReleaseJarAnalysisInputLocation( - @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language, boolean isMultiRelease) { + @Nonnull Path path, + @Nonnull SourceType srcType, + @Nonnull Language language, + @Nonnull List bodyInterceptors, + boolean isMultiRelease) { super(path, srcType); this.language = language; + this.bodyInterceptors = bodyInterceptors; if (!isMultiRelease) { throw new IllegalArgumentException("The given path does not point to a multi release jar."); @@ -98,7 +117,6 @@ protected MultiReleaseJarAnalysisInputLocation( final Path archiveRoot = fs.getPath("/"); Path versionedRoot = archiveRoot.getFileSystem().getPath("/META-INF/versions/"); - availableVersions = new ArrayList<>(); try (Stream list = Files.list(versionedRoot)) { list.map( dir -> { @@ -106,26 +124,29 @@ protected MultiReleaseJarAnalysisInputLocation( return versionDirName.substring(0, versionDirName.length() - 1); }) .map(Integer::new) + .filter(version -> version <= language.getVersion()) .sorted() - .forEach(availableVersions::add); + .forEach( + version -> { + final Path versionRoot = + archiveRoot + .getFileSystem() + .getPath("/META-INF", "versions", version.toString()); + inputLocations.put( + version, + createAnalysisInputLocation(versionRoot, srcType, getBodyInterceptors())); + }); + + inputLocations.put( + DEFAULT_VERSION, + createAnalysisInputLocation(archiveRoot, srcType, getBodyInterceptors())); } catch (IOException e) { throw new IllegalStateException("Can not index the given file.", e); } - - for (int i = availableVersions.size() - 1; i >= 0; i--) { - Integer version = availableVersions.get(i); - if (version > language.getVersion()) { - // TODO: use binSearch to find desired versions more efficiently? - continue; - } - final Path versionRoot = - archiveRoot.getFileSystem().getPath("/META-INF", "versions", version.toString()); - inputLocations.put(version, createAnalysisInputLocation(versionRoot)); - } - inputLocations.put(DEFAULT_VERSION, createAnalysisInputLocation(archiveRoot)); } - protected AnalysisInputLocation createAnalysisInputLocation(Path archiveRoot) { + protected static AnalysisInputLocation createAnalysisInputLocation( + Path archiveRoot, SourceType sourceType, List bodyInterceptors) { return PathBasedAnalysisInputLocation.create( archiveRoot, sourceType, @@ -179,15 +200,6 @@ public Language getLanguage() { return language; } - /** - * lists all versions from the version directories inside the META_INF/ directory - excluding the - * default implemention version - */ - @Nonnull - public List getAvailableVersions() { - return availableVersions; - } - public static boolean isMultiReleaseJar(Path path) { try { FileInputStream inputStream = new FileInputStream(path.toFile()); @@ -208,7 +220,42 @@ public static boolean isMultiReleaseJar(Path path) { return Boolean.parseBoolean(value); } catch (IOException e) { - throw new IllegalArgumentException("File not found.", e); + throw new IllegalArgumentException("Manifest file not found.", e); + } + } + + @Override + @Nonnull + public List getBodyInterceptors() { + return bodyInterceptors; + } + + /** + * lists all versions from the version directories inside the META_INF/ directory - excluding the + * default implemention version + */ + protected static List getLanguageVersions(@Nonnull Path path) { + FileSystem fs; + try { + fs = fileSystemCache.get(path); + } catch (ExecutionException e) { + throw new IllegalArgumentException("Could not open filesystemcache.", e); + } + + final Path archiveRoot = fs.getPath("/"); + Path versionedRoot = archiveRoot.getFileSystem().getPath("/META-INF/versions/"); + + try (Stream list = Files.list(versionedRoot)) { + return list.map( + dir -> { + String versionDirName = dir.getFileName().toString(); + return versionDirName.substring(0, versionDirName.length() - 1); + }) + .map(Integer::new) + .sorted() + .collect(Collectors.toCollection(ArrayList::new)); + } catch (IOException e) { + throw new IllegalStateException("Can not index the given file.", e); } } From 7ccd8ab8b64abb8f208b7cf237c23672e0a3714f Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 23 Jan 2024 10:54:46 +0100 Subject: [PATCH 47/57] adapt test input to have a similar structure; test version --- .../{createJar.sh => createModMrJar.sh} | 0 .../multi-release-jar/createMrJar.sh | 11 +++++ .../multi-release-jar/mrjar.jar | Bin 2924 -> 2856 bytes .../multi-release-jar/readme.md | 10 ----- .../de/upb/swt/multirelease/Utility.java | 9 ++++ ...tiReleaseJarAnalysisInputLocationTest.java | 41 +++++++++++++----- 6 files changed, 50 insertions(+), 21 deletions(-) rename shared-test-resources/multi-release-jar-modular/{createJar.sh => createModMrJar.sh} (100%) create mode 100755 shared-test-resources/multi-release-jar/createMrJar.sh delete mode 100644 shared-test-resources/multi-release-jar/readme.md create mode 100644 shared-test-resources/multi-release-jar/src/main/java10/de/upb/swt/multirelease/Utility.java diff --git a/shared-test-resources/multi-release-jar-modular/createJar.sh b/shared-test-resources/multi-release-jar-modular/createModMrJar.sh similarity index 100% rename from shared-test-resources/multi-release-jar-modular/createJar.sh rename to shared-test-resources/multi-release-jar-modular/createModMrJar.sh diff --git a/shared-test-resources/multi-release-jar/createMrJar.sh b/shared-test-resources/multi-release-jar/createMrJar.sh new file mode 100755 index 00000000000..a5ce52f4012 --- /dev/null +++ b/shared-test-resources/multi-release-jar/createMrJar.sh @@ -0,0 +1,11 @@ +# /bin/bash +#More info: https://www.baeldung.com/java-multi-release-jar + +javac --release 8 -d classes src/main/java/de/upb/swt/multirelease/*java +javac --release 9 -d classes-9 src/main/java9/de/upb/swt/multirelease/*java +javac --release 10 -d classes-10 src/main/java10/de/upb/swt/multirelease/*java + +jar --create --file mrjar.jar --main-class de.upb.swt.multirelease.Main -C classes . --release 9 -C classes-9 . --release 10 -C classes-10 . + + + diff --git a/shared-test-resources/multi-release-jar/mrjar.jar b/shared-test-resources/multi-release-jar/mrjar.jar index 12cdcc8bb81ad0aada07af5f01715d66ba8c4d86..19abe3ad6d2a2cacb6934c31c1502cc9b3c5db58 100644 GIT binary patch literal 2856 zcmWIWW@Zs#;Nak3*b`{jl%JHg{Qvs7 zi@xl*E_)**>F9w~&8B}Ft0w&LI(A6BM(d8XYVFE29=}ya0v|)%7IyMpvgLQL;$YTo zJ0u$HEg;%C8+~L)5WTC?NaTs zIhQtlJ=yTG^zv@kz-}Go+4dF8)oSgDv+p_0I&;Wr_KN)%9#7%A5}yzGbVtXUl2(=3~QUFL?9H{=W30B#Af1Q#FgvCGfgW zY*v%uyMCB!kNu|tLvth5(6|dh_A4Z&{x*+FRWpg|D!Fq+>gUum2Um8RU9+^3+x5b* zMn*Dh`#13%y!=t)(T#)`OI?$uOzRXWetBPVs>bGo74c8LPg*Ft!Y58N zQ|Ig24q>M~r%WbQtt%=jJG|$DaOFy^yq$G1ZHWzbbC=hcZusO7VxDZ?diYX zu$i2_)0AY*H@elS78kr))LYuu*REH^bGQBr&!2^JCiU>NA6&2F{Gr6A%fd{eDs!U5 z(p06RF~7=zrK66-EAgLuQ!-e!CWpI9dDm(`Y7tm()VpNf>N#`n8t8v|5|vxm^3y zvhE_MvQ<;=0%MAuBVFU-UU`hTMh|*XtU+&RfE3y2T9j~UAu_i0iPDc2-QM1Z9R&Vu z%iQeSv+di%=nKskstl?=27Oej07iH5{cB5ePCA=OFSPgO=aT!w_)nuy2$;9|jjiuz zC)nBDzsEQy>9{MenEPF4W;5q%HMv&#?vhvW{m`7P1Bd6`ywl!4x#23kT1J*X_KU=>{}LX50{jZSI-4I{Hv-1CNsq-fi7HP) z>7}VUu6lp17bm4YV&ojgJc885dOl2Y91uMXp;xBqfoc#0SPKjj z6hlzb9I`*Km5>N?M1dg+4+*5w51$E&2<IaBHv&{-Ab<%jBk+0`Ie~+U5CkY8$~-jxvH~?RFmMB*5;FtC I2X+t-06q7a*#H0l literal 2924 zcmWIWW@Zs#;Nak3NG;zI#DD}i8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1g8t9~BMdU$Tp&Z`{8e)m)pjqV-#YW<)|_*}s*PFrs0tWD;M(m&tab=uh$;$eE| z*p2V(ua1AX+nxIG(2}0xlAjlB_@~?Cnf`vyZ$^-dwSqpcDFC{s5r{!9=3-y~`XU+4 zyUak@lvI7(3fLhEN(++kDB?yaDlRXVQy(oNoG-MPHJK?#0`)*L3gAQ9$mhP znR$B2If=!^rGb|IOpYS|+Oqk>9QE`AY`8WQNOKGK^j_rZXIZ*YD#fYojpMXPUVCqD zQ?Y*x^;15cjatEZPUZ8u_tnSu^q=2e&cJ?S>qMtp4#ynDEZZK&WqOXz zO*$ca(qUC{TgmFX+Y=5MC0L(0{FC|p*=1foTDX#xLU((*w7m;eVZItX@j>13BTCIz zgKdJ&8usUiY)o13WI+#?b0uHv!5JB+xi!*P|6V;u>HCVy?{2S1ym_FjIn?&Rvw$5R zQy%!qPkDWO-lT~iSmtwmck}dLCD}Y#4f+QL*Dlu*U_ zC2zu2g_9m>-{TI*c`m&9;;ia96CIPzU%a+HD;%D3x@A6;Yz+_Dy36eq|K=8-L*_4^ zC0?HYTyxW0k$XRxKq=~r%*P3_j0_Bdz>I*%1L%>ZiYKx{OEPmZODZApl^bx{>#&1} z?d2^q)!d?^Uq@eQy|AmmOs}O&`e0~);;hcnd7_`v)}XoGlwqT`atCRLc3g zye;$mslihwB;Nl!bt&gO9(KFqR)_yZbR~&({R!;e(Xr)Jib``#SM^$@rO$c3o-Wam zj9TaQq*SooXgBwv4uR#LzNb!GJ;fKX@Tv2FX7x^pwXmfW-XPt&#jJL@zi_nqdvxh|+|AGrL<$p0>* z2@LzCK#a(&DQLMFrTi&NEh^5;&nwoqM9PrpI>dpo1uwCXbfA<8=$fQ)YeFq2&^5~A z*N9qnpljA4tQkjnf^L!}i6#+|Y{T@HJaQ`#4e3amzr}gxBzI3WFMDrsF1aK8Iaf>Buqbg&>fFJ(yl9E!nc}G$wFeWv zuQQU1Ja$;n!}87rTM^>`i4T_*JQr4QT34V|K&v}ZOOOXsdBDv>GK zci0GWN*AGw+%Vl#Z47n-rYGW>qCy}Uh_W{BeTeTx>h{znmwXd zd1rlFVf?E1arg%HUj{irrrH-8TG!^kym;t972A8A{R_S-Z`VGxy2Tc%y1XuG&CJ9sz8DOt@C03K(Pp7X$7p z5Mjc5AQPPUaccloi3lJ7^dC?IB;n)M1gattz!aeglIU@31XY;`5QnM}Ex{v#2~;X0 zm)D>w6al8-F$GbfA_qIjJmfM6RLUcOBd{3(4FiyOP+WzQd644)Jy)W} languageVersions = MultiReleaseJarAnalysisInputLocation.getLanguageVersions(mrj); + Assert.assertTrue(languageVersions.contains(9)); + Assert.assertTrue(languageVersions.contains(10)); + } + } From f4c434e876a232355de0e349500f75cccf2c0198 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Wed, 24 Jan 2024 16:50:21 +0100 Subject: [PATCH 48/57] cleanup; move task into another issue --- ...eMultiReleaseJarAnalysisInputLocation.java | 90 ++++++++++--------- .../MultiReleaseJarAnalysisInputLocation.java | 7 +- .../PathBasedAnalysisInputLocation.java | 17 ++-- ...tiReleaseJarAnalysisInputLocationTest.java | 1 - 4 files changed, 61 insertions(+), 54 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java index 61b416aa0e6..bab58c04d90 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java @@ -21,65 +21,71 @@ * . * #L% */ -import java.nio.file.Path; -import java.util.Collection; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ExecutionException; -import javax.annotation.Nonnull; + import sootup.core.Language; import sootup.core.frontend.SootClassSource; import sootup.core.model.SourceType; +import sootup.core.transform.BodyInterceptor; import sootup.core.views.View; import sootup.java.core.JavaModuleInfo; import sootup.java.core.ModuleInfoAnalysisInputLocation; import sootup.java.core.signatures.ModuleSignature; +import javax.annotation.Nonnull; +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ExecutionException; + /** * This AnalysisInputLocation models MultiRelease Jars or Directories if path points to a directory * that is not packed into a jar see https://openjdk.org/jeps/238#Modular_multi-release_JAR_files */ public class ModuleMultiReleaseJarAnalysisInputLocation extends MultiReleaseJarAnalysisInputLocation - implements ModuleInfoAnalysisInputLocation { - public ModuleMultiReleaseJarAnalysisInputLocation( - @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { - super(path, srcType, language); + implements ModuleInfoAnalysisInputLocation { + public ModuleMultiReleaseJarAnalysisInputLocation( + @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { + super(path, srcType, language); - throw new UnsupportedOperationException("not fully implemented, yet!"); - } + throw new UnsupportedOperationException("not fully implemented, yet!"); + } - @Override - protected ModuleInfoAnalysisInputLocation createAnalysisInputLocation(@Nonnull Path path) { - try { - return new JavaModulePathAnalysisInputLocation( - path, fileSystemCache.get(this.path), sourceType); - } catch (ExecutionException e) { - throw new IllegalArgumentException("Could not open filesystemcache.", e); + @Override + protected ModuleInfoAnalysisInputLocation createAnalysisInputLocation( + @Nonnull Path path, SourceType sourceType, List bodyInterceptors) { + try { + return new JavaModulePathAnalysisInputLocation( + path, fileSystemCache.get(this.path), sourceType, bodyInterceptors); + } catch (ExecutionException e) { + throw new IllegalArgumentException("Could not open filesystemcache.", e); + } } - } - @Override - public Collection getModulesClassSources( - @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { - // TODO: check if we need to combine modules as well or if only versioned .class files are - return ((ModuleInfoAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) - .getModulesClassSources(moduleSignature, view); - } + @Override + public Collection getModulesClassSources( + @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { + // TODO: check if we need to combine modules as well or if only versioned .class files are + return ((JavaModulePathAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) + .getModulesClassSources(moduleSignature, view); + } - @Nonnull - @Override - public Optional getModuleInfo(@Nonnull ModuleSignature sig, @Nonnull View view) { - // TODO: check if we need to combine modules as well or if only versioned .class files are - // allowed - return ((ModuleInfoAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) - .getModuleInfo(sig, view); - } + @Nonnull + @Override + public Optional getModuleInfo(@Nonnull ModuleSignature sig, @Nonnull View view) { + // TODO: check if we need to combine modules as well or if only versioned .class files are + // allowed + return ((JavaModulePathAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) + .getModuleInfo(sig, view); + } - @Nonnull - @Override - public Set getModules(@Nonnull View view) { - // TODO: check if we need to combine modules as well or if only versioned .class files are - // allowed - return ((ModuleInfoAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)).getModules(view); - } + @Nonnull + @Override + public Set getModules(@Nonnull View view) { + // TODO: check if we need to combine modules as well or if only versioned .class files are + // allowed + return ((JavaModulePathAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) + .getModules(view); + } } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index a6feb6a5f16..5c4139095bb 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -69,11 +69,14 @@ public static AnalysisInputLocation create( @Nonnull SourceType srcType, @Nonnull Language language, List bodyInterceptors) { + if (isMultiReleaseJar(path)) { return new MultiReleaseJarAnalysisInputLocation( path, srcType, language, bodyInterceptors, true); } - return createAnalysisInputLocation(path, srcType, bodyInterceptors); + + return PathBasedAnalysisInputLocation.create( + path, srcType, bodyInterceptors, Collections.singletonList(Paths.get("/META_INF"))); } public MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nonnull Language language) { @@ -145,7 +148,7 @@ protected MultiReleaseJarAnalysisInputLocation( } } - protected static AnalysisInputLocation createAnalysisInputLocation( + protected AnalysisInputLocation createAnalysisInputLocation( Path archiveRoot, SourceType sourceType, List bodyInterceptors) { return PathBasedAnalysisInputLocation.create( archiveRoot, diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index fcb3bc8c9b8..84b91026159 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -8,7 +8,6 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -63,25 +62,25 @@ * @author Kaustubh Kelkar updated on 30.07.2020 */ public abstract class PathBasedAnalysisInputLocation implements AnalysisInputLocation { - protected final SourceType sourceType; - protected final List bodyInterceptors; - protected Path path; - protected Collection ignoredPaths = new ArrayList<>(); + @Nonnull protected Path path; + @Nonnull protected Collection ignoredPaths; + @Nonnull protected final SourceType sourceType; + @Nonnull protected final List bodyInterceptors; - protected PathBasedAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { + protected PathBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { this(path, srcType, Collections.emptyList()); } protected PathBasedAnalysisInputLocation( @Nonnull Path path, - @Nullable SourceType srcType, + @Nonnull SourceType srcType, @Nonnull List bodyInterceptors) { this(path, srcType, bodyInterceptors, Collections.emptyList()); } protected PathBasedAnalysisInputLocation( @Nonnull Path path, - @Nullable SourceType srcType, + @Nonnull SourceType srcType, @Nonnull List bodyInterceptors, @Nonnull Collection ignoredPaths) { this.path = path; @@ -400,7 +399,7 @@ public Optional getClassSource( * * @param warFilePath The path to war file to be extracted */ - protected void extractWarFile(Path warFilePath, final Path destDirectory) { + void extractWarFile(Path warFilePath, final Path destDirectory) { int extractedSize = 0; try { File dest = destDirectory.toFile(); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java index 3420131f0b1..f51cb1a084c 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java @@ -161,5 +161,4 @@ public void testVersions() { Assert.assertTrue(languageVersions.contains(9)); Assert.assertTrue(languageVersions.contains(10)); } - } From 5371e9e1ab322b1a62115343ccd90e6a24af236c Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Thu, 25 Jan 2024 16:23:05 +0100 Subject: [PATCH 49/57] fix providerMismatchException --- .../inputlocation/PathBasedAnalysisInputLocation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index 84b91026159..7cced89d18f 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -84,7 +84,7 @@ protected PathBasedAnalysisInputLocation( @Nonnull List bodyInterceptors, @Nonnull Collection ignoredPaths) { this.path = path; - this.ignoredPaths = ignoredPaths; + this.ignoredPaths = ignoredPaths.stream().map(Path::toAbsolutePath).collect(Collectors.toCollection(HashSet::new)); this.sourceType = srcType; this.bodyInterceptors = bodyInterceptors; @@ -155,7 +155,7 @@ Collection walkDirectory( try (final Stream walk = Files.walk(dirPath)) { return walk.filter( filePath -> - ignoredPaths.stream().noneMatch(filePath::startsWith) + ignoredPaths.stream().map(Path::toString).noneMatch(p -> filePath.toString().startsWith(p)) && PathUtils.hasExtension(filePath, handledFileType) && !filePath.toString().endsWith(moduleInfoFilename)) .flatMap( From 9f6a8c101e7fbd5540ddced79c324cffd4ff6d17 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 26 Jan 2024 17:11:54 +0100 Subject: [PATCH 50/57] never trust your inputs! --- .../java/de/upb/swt/multirelease/Main.java | 2 +- .../java/de/upb/swt/multirelease/Utility.java | 2 +- .../de/upb/swt/multirelease/Utility.java | 2 +- .../de/upb/swt/multirelease/Utility.java | 2 +- .../multi-release-jar/createMrJar.sh | 6 +- .../multi-release-jar/mrjar.jar | Bin 2856 -> 4100 bytes .../upb/{swt => sse}/multirelease/Main.java | 4 +- .../{swt => sse}/multirelease/Utility.java | 2 +- .../{swt => sse}/multirelease/Utility.java | 2 +- .../{swt => sse}/multirelease/Utility.java | 2 +- ...eMultiReleaseJarAnalysisInputLocation.java | 91 +++++++++--------- .../MultiReleaseJarAnalysisInputLocation.java | 5 +- .../PathBasedAnalysisInputLocation.java | 11 ++- ...tiReleaseJarAnalysisInputLocationTest.java | 71 +++++++------- .../java/core/views/JavaModuleView.java | 1 - 15 files changed, 102 insertions(+), 101 deletions(-) rename shared-test-resources/multi-release-jar/src/main/java/de/upb/{swt => sse}/multirelease/Main.java (83%) rename shared-test-resources/multi-release-jar/src/main/java/de/upb/{swt => sse}/multirelease/Utility.java (75%) rename shared-test-resources/multi-release-jar/src/main/java10/de/upb/{swt => sse}/multirelease/Utility.java (75%) rename shared-test-resources/multi-release-jar/src/main/java9/de/upb/{swt => sse}/multirelease/Utility.java (75%) diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Main.java b/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Main.java index 7f8e24f087f..ef3257fd72d 100644 --- a/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Main.java +++ b/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Main.java @@ -1,4 +1,4 @@ -package multirelease; +package de.upb.sse.multirelease; public class Main { diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Utility.java b/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Utility.java index 274c379a4d8..12a56285d53 100644 --- a/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Utility.java +++ b/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Utility.java @@ -1,4 +1,4 @@ -package multirelease; +package de.upb.sse.multirelease; public class Utility { diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java10/de/upb/swt/multirelease/Utility.java b/shared-test-resources/multi-release-jar-modular/src/main/java10/de/upb/swt/multirelease/Utility.java index eeafaa5baad..2f0dede051d 100644 --- a/shared-test-resources/multi-release-jar-modular/src/main/java10/de/upb/swt/multirelease/Utility.java +++ b/shared-test-resources/multi-release-jar-modular/src/main/java10/de/upb/swt/multirelease/Utility.java @@ -1,4 +1,4 @@ -package multirelease; +package de.upb.sse.multirelease; public class Utility { diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java9/de/upb/swt/multirelease/Utility.java b/shared-test-resources/multi-release-jar-modular/src/main/java9/de/upb/swt/multirelease/Utility.java index 14240b2411d..4331b21bb09 100644 --- a/shared-test-resources/multi-release-jar-modular/src/main/java9/de/upb/swt/multirelease/Utility.java +++ b/shared-test-resources/multi-release-jar-modular/src/main/java9/de/upb/swt/multirelease/Utility.java @@ -1,4 +1,4 @@ -package multirelease; +package de.upb.sse.multirelease; public class Utility { diff --git a/shared-test-resources/multi-release-jar/createMrJar.sh b/shared-test-resources/multi-release-jar/createMrJar.sh index a5ce52f4012..45ec9237b0c 100755 --- a/shared-test-resources/multi-release-jar/createMrJar.sh +++ b/shared-test-resources/multi-release-jar/createMrJar.sh @@ -1,9 +1,9 @@ # /bin/bash #More info: https://www.baeldung.com/java-multi-release-jar -javac --release 8 -d classes src/main/java/de/upb/swt/multirelease/*java -javac --release 9 -d classes-9 src/main/java9/de/upb/swt/multirelease/*java -javac --release 10 -d classes-10 src/main/java10/de/upb/swt/multirelease/*java +javac --release 8 -d classes src/main/java/de/upb/sse/multirelease/*java +javac --release 9 -d classes-9 src/main/java9/de/upb/sse/multirelease/*java +javac --release 10 -d classes-10 src/main/java10/de/upb/sse/multirelease/*java jar --create --file mrjar.jar --main-class de.upb.swt.multirelease.Main -C classes . --release 9 -C classes-9 . --release 10 -C classes-10 . diff --git a/shared-test-resources/multi-release-jar/mrjar.jar b/shared-test-resources/multi-release-jar/mrjar.jar index 19abe3ad6d2a2cacb6934c31c1502cc9b3c5db58..3ff8b98545b618683d688338c5a05148aefcc378 100644 GIT binary patch literal 4100 zcmb7H2~bm46b%Fkga~NDDuo&r8FqpwDj@q70)c=FL}d{L4HyVG#s!o}L}cGY3If$A zHK2*uqHJZ6VN<{*)mlVQtVJzUM?u-9|AXZx)O_&FWaiIs&z<+)J@?!TnTV9aA!KA^ z5Shsvw;_Zei;zN)oc-*L-Mw5)XF3rGB!Wyt$$$}(U&6>@$v7Zlo=md$a(8j2_?eJg zbUXQINplRMx4t)_z1*>7cu!mHXFH8P?KH)5|7^c^qkj)h95S@LRmH5iUT7W2MtYeW zbq-PQPkl#kmd)U8;?|*>`#AZ>Foy0#qHYx?iT`Uw$-1k%A+lOhReF3`U&K25(7w+zfla!WMfIQ?fOhM_(m}O-;Lp z&XD5p)q@<^Z|(E9W8?Fc_Zdw|%;>-P;b$_o$ot!#qD-iDC}77)9RpRLeQr6me0u1yL&x8okWM?{cGKw*drtz zq=1q&5Z`v2z!FfbeecR<&~W^a(xK8+v?Eg@si|OJmz@4y?j*MeKYsJU$RFjwg2qBt zoK54H+s${e1KoR?KZbgDxE)H&iN1Vsji9K>edU<*+MM8^kQ|R9l=jn%6Vi^;ze=5@ z`eM&j(REbOJJgc7kF}Ej%2%*{zk5n&=l-Xrud|y*lA_n*RD4;+#c#kczcTP&9&{TT0y9_G%S4L${v>2_<`G-`) zeEi`RGv%#b(s;wH{AYHp*h7^-AXWf9AYT5uFtzfJji5!uGUv(_N$&D!vBTLsxN%O; zB{1+!V1-;++#roAqqIJeTk5cO^5S=$xz-+p6%*TQ$n-(fC!gmeecQ(EeVfLM7(FK@ z-+dmFAHYnm+h=C=T3+2u?Mc;uxuQ>|XKSQYPUzjBo#jr$MCnko55{YQqaVv}8JNmC za)#Pf;1^*}w5bm9GZ-P{g?sNMB)gI-vUYWR=!v|+@4gq^+bZoiu4RKPIZMgS9BiD< zvwG29?glMK%pT(QtD+y{H$JwY#JVyodksFIw3%KerL|So*P^-|Kta$nT zcvwC+*MVkge4SsnMX8#)*_aW1Qgg?Zqn5n)Tl}iSHB79O(g!7(RWopC%sGd_e$Tfxu>tp_vGmVPtO5<;#*b3c@BofFd_~_F-$kW z^sNd|ta+~zV!%4WD)A(Em(YSI!aIl2;^ZZ|$%b#tv;@^wP~BS71`Ns-@7hM3BIssh zd!CHXH^EUqNyO(K!lo$DmB+hnUiC2s;*U1eBduB*($q2OH7sdQ_L$Kjj1x|W61}Q> zXq!cWih<8Wc9SaRm>g-F#xE=-tAwF`{3C*%e?YHqPo-*JO0B2vlLzN8&wa4_hqe-? z8LJ{I7_l0${HES%*Pg~#FLAoNt>_715s8;Cl=bjC=vG-j7M#NOaFWlsaXnoKrGxfd zx8Y@u(+0(E?0oJ@Cgpb7oe`E9{`OB($IiVp;3)n$IG$yfqVMG>WBR@A0JK1H%h z%=vcu{xyq=R_UwNFgJryEjUE}uUdctD_ad17QAl1UxW!ST;nCMm#Ey0-`>bE0DD;ub za%tD6_DDU)BkH#7D2+?l@pXkMSs}pV8whk+_q3#x3wc&F6p=pDKFut1a=22VL+N>t zdZ(|JdZ}~kEt#BPtRbc@M84Y#Fx*biaMc0BMV{U(z+Jw1q`cXzKlUqD1UGJDl3sAb3X8l$|5{D37O#a&f!9`IN^ST7rMlw;9D!h_`W(~mx_?)K- zEsbCXG(!C924#2ye9r1$JONzgAYg#I0faf}izk7r9RzcTG^cv;M6gRC1c(wB2wwD= zgcl8P^@ETJlLcA?7e2f2^aR%v2-d**`{fP5>xi66q<7%zAX>?4KoRqm6dI{;8Ne|N zVOUItMXC#qWeA$fzJ81)R2&@B5Vpc6T1*At*oKh1cruY1EUcvPNCC$)(g%%2nFAodO?ksNrSmSD{lkDvIa0!1ma(`vX`a+ literal 2856 zcmWIWW@Zs#;Nak3*b`{jl%JHg{Qvs7 zi@xl*E_)**>F9w~&8B}Ft0w&LI(A6BM(d8XYVFE29=}ya0v|)%7IyMpvgLQL;$YTo zJ0u$HEg;%C8+~L)5WTC?NaTs zIhQtlJ=yTG^zv@kz-}Go+4dF8)oSgDv+p_0I&;Wr_KN)%9#7%A5}yzGbVtXUl2(=3~QUFL?9H{=W30B#Af1Q#FgvCGfgW zY*v%uyMCB!kNu|tLvth5(6|dh_A4Z&{x*+FRWpg|D!Fq+>gUum2Um8RU9+^3+x5b* zMn*Dh`#13%y!=t)(T#)`OI?$uOzRXWetBPVs>bGo74c8LPg*Ft!Y58N zQ|Ig24q>M~r%WbQtt%=jJG|$DaOFy^yq$G1ZHWzbbC=hcZusO7VxDZ?diYX zu$i2_)0AY*H@elS78kr))LYuu*REH^bGQBr&!2^JCiU>NA6&2F{Gr6A%fd{eDs!U5 z(p06RF~7=zrK66-EAgLuQ!-e!CWpI9dDm(`Y7tm()VpNf>N#`n8t8v|5|vxm^3y zvhE_MvQ<;=0%MAuBVFU-UU`hTMh|*XtU+&RfE3y2T9j~UAu_i0iPDc2-QM1Z9R&Vu z%iQeSv+di%=nKskstl?=27Oej07iH5{cB5ePCA=OFSPgO=aT!w_)nuy2$;9|jjiuz zC)nBDzsEQy>9{MenEPF4W;5q%HMv&#?vhvW{m`7P1Bd6`ywl!4x#23kT1J*X_KU=>{}LX50{jZSI-4I{Hv-1CNsq-fi7HP) z>7}VUu6lp17bm4YV&ojgJc885dOl2Y91uMXp;xBqfoc#0SPKjj z6hlzb9I`*Km5>N?M1dg+4+*5w51$E&2<IaBHv&{-Ab<%jBk+0`Ie~+U5CkY8$~-jxvH~?RFmMB*5;FtC I2X+t-06q7a*#H0l diff --git a/shared-test-resources/multi-release-jar/src/main/java/de/upb/swt/multirelease/Main.java b/shared-test-resources/multi-release-jar/src/main/java/de/upb/sse/multirelease/Main.java similarity index 83% rename from shared-test-resources/multi-release-jar/src/main/java/de/upb/swt/multirelease/Main.java rename to shared-test-resources/multi-release-jar/src/main/java/de/upb/sse/multirelease/Main.java index 7f8e24f087f..19d0f513e64 100644 --- a/shared-test-resources/multi-release-jar/src/main/java/de/upb/swt/multirelease/Main.java +++ b/shared-test-resources/multi-release-jar/src/main/java/de/upb/sse/multirelease/Main.java @@ -1,4 +1,4 @@ -package multirelease; +package de.upb.sse.multirelease; public class Main { @@ -10,4 +10,4 @@ public static void main(String[] args) { System.out.println("End jar"); } -} \ No newline at end of file +} diff --git a/shared-test-resources/multi-release-jar/src/main/java/de/upb/swt/multirelease/Utility.java b/shared-test-resources/multi-release-jar/src/main/java/de/upb/sse/multirelease/Utility.java similarity index 75% rename from shared-test-resources/multi-release-jar/src/main/java/de/upb/swt/multirelease/Utility.java rename to shared-test-resources/multi-release-jar/src/main/java/de/upb/sse/multirelease/Utility.java index 274c379a4d8..12a56285d53 100644 --- a/shared-test-resources/multi-release-jar/src/main/java/de/upb/swt/multirelease/Utility.java +++ b/shared-test-resources/multi-release-jar/src/main/java/de/upb/sse/multirelease/Utility.java @@ -1,4 +1,4 @@ -package multirelease; +package de.upb.sse.multirelease; public class Utility { diff --git a/shared-test-resources/multi-release-jar/src/main/java10/de/upb/swt/multirelease/Utility.java b/shared-test-resources/multi-release-jar/src/main/java10/de/upb/sse/multirelease/Utility.java similarity index 75% rename from shared-test-resources/multi-release-jar/src/main/java10/de/upb/swt/multirelease/Utility.java rename to shared-test-resources/multi-release-jar/src/main/java10/de/upb/sse/multirelease/Utility.java index eeafaa5baad..2f0dede051d 100644 --- a/shared-test-resources/multi-release-jar/src/main/java10/de/upb/swt/multirelease/Utility.java +++ b/shared-test-resources/multi-release-jar/src/main/java10/de/upb/sse/multirelease/Utility.java @@ -1,4 +1,4 @@ -package multirelease; +package de.upb.sse.multirelease; public class Utility { diff --git a/shared-test-resources/multi-release-jar/src/main/java9/de/upb/swt/multirelease/Utility.java b/shared-test-resources/multi-release-jar/src/main/java9/de/upb/sse/multirelease/Utility.java similarity index 75% rename from shared-test-resources/multi-release-jar/src/main/java9/de/upb/swt/multirelease/Utility.java rename to shared-test-resources/multi-release-jar/src/main/java9/de/upb/sse/multirelease/Utility.java index 14240b2411d..4331b21bb09 100644 --- a/shared-test-resources/multi-release-jar/src/main/java9/de/upb/swt/multirelease/Utility.java +++ b/shared-test-resources/multi-release-jar/src/main/java9/de/upb/sse/multirelease/Utility.java @@ -1,4 +1,4 @@ -package multirelease; +package de.upb.sse.multirelease; public class Utility { diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java index bab58c04d90..30d01d601f0 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java @@ -22,6 +22,13 @@ * #L% */ +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import javax.annotation.Nonnull; import sootup.core.Language; import sootup.core.frontend.SootClassSource; import sootup.core.model.SourceType; @@ -31,61 +38,53 @@ import sootup.java.core.ModuleInfoAnalysisInputLocation; import sootup.java.core.signatures.ModuleSignature; -import javax.annotation.Nonnull; -import java.nio.file.Path; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ExecutionException; - /** * This AnalysisInputLocation models MultiRelease Jars or Directories if path points to a directory * that is not packed into a jar see https://openjdk.org/jeps/238#Modular_multi-release_JAR_files */ public class ModuleMultiReleaseJarAnalysisInputLocation extends MultiReleaseJarAnalysisInputLocation - implements ModuleInfoAnalysisInputLocation { - public ModuleMultiReleaseJarAnalysisInputLocation( - @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { - super(path, srcType, language); + implements ModuleInfoAnalysisInputLocation { + public ModuleMultiReleaseJarAnalysisInputLocation( + @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { + super(path, srcType, language); - throw new UnsupportedOperationException("not fully implemented, yet!"); - } + throw new UnsupportedOperationException("not fully implemented, yet!"); + } - @Override - protected ModuleInfoAnalysisInputLocation createAnalysisInputLocation( - @Nonnull Path path, SourceType sourceType, List bodyInterceptors) { - try { - return new JavaModulePathAnalysisInputLocation( - path, fileSystemCache.get(this.path), sourceType, bodyInterceptors); - } catch (ExecutionException e) { - throw new IllegalArgumentException("Could not open filesystemcache.", e); - } + @Override + protected ModuleInfoAnalysisInputLocation createAnalysisInputLocation( + @Nonnull Path path, SourceType sourceType, List bodyInterceptors) { + try { + return new JavaModulePathAnalysisInputLocation( + path, fileSystemCache.get(this.path), sourceType, bodyInterceptors); + } catch (ExecutionException e) { + throw new IllegalArgumentException("Could not open filesystemcache.", e); } + } - @Override - public Collection getModulesClassSources( - @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { - // TODO: check if we need to combine modules as well or if only versioned .class files are - return ((JavaModulePathAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) - .getModulesClassSources(moduleSignature, view); - } + @Override + public Collection getModulesClassSources( + @Nonnull ModuleSignature moduleSignature, @Nonnull View view) { + // TODO: check if we need to combine modules as well or if only versioned .class files are + return ((JavaModulePathAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) + .getModulesClassSources(moduleSignature, view); + } - @Nonnull - @Override - public Optional getModuleInfo(@Nonnull ModuleSignature sig, @Nonnull View view) { - // TODO: check if we need to combine modules as well or if only versioned .class files are - // allowed - return ((JavaModulePathAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) - .getModuleInfo(sig, view); - } + @Nonnull + @Override + public Optional getModuleInfo(@Nonnull ModuleSignature sig, @Nonnull View view) { + // TODO: check if we need to combine modules as well or if only versioned .class files are + // allowed + return ((JavaModulePathAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) + .getModuleInfo(sig, view); + } - @Nonnull - @Override - public Set getModules(@Nonnull View view) { - // TODO: check if we need to combine modules as well or if only versioned .class files are - // allowed - return ((JavaModulePathAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) - .getModules(view); - } + @Nonnull + @Override + public Set getModules(@Nonnull View view) { + // TODO: check if we need to combine modules as well or if only versioned .class files are + // allowed + return ((JavaModulePathAnalysisInputLocation) inputLocations.get(DEFAULT_VERSION)) + .getModules(view); + } } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index 5c4139095bb..0bb8232de9b 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -128,7 +128,7 @@ protected MultiReleaseJarAnalysisInputLocation( }) .map(Integer::new) .filter(version -> version <= language.getVersion()) - .sorted() + .sorted(Comparator.reverseOrder()) .forEach( version -> { final Path versionRoot = @@ -137,7 +137,8 @@ protected MultiReleaseJarAnalysisInputLocation( .getPath("/META-INF", "versions", version.toString()); inputLocations.put( version, - createAnalysisInputLocation(versionRoot, srcType, getBodyInterceptors())); + PathBasedAnalysisInputLocation.create( + versionRoot, sourceType, bodyInterceptors, Collections.emptyList())); }); inputLocations.put( diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index 7cced89d18f..eb3d769211b 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -84,7 +84,10 @@ protected PathBasedAnalysisInputLocation( @Nonnull List bodyInterceptors, @Nonnull Collection ignoredPaths) { this.path = path; - this.ignoredPaths = ignoredPaths.stream().map(Path::toAbsolutePath).collect(Collectors.toCollection(HashSet::new)); + this.ignoredPaths = + ignoredPaths.stream() + .map(Path::toAbsolutePath) + .collect(Collectors.toCollection(HashSet::new)); this.sourceType = srcType; this.bodyInterceptors = bodyInterceptors; @@ -155,7 +158,9 @@ Collection walkDirectory( try (final Stream walk = Files.walk(dirPath)) { return walk.filter( filePath -> - ignoredPaths.stream().map(Path::toString).noneMatch(p -> filePath.toString().startsWith(p)) + ignoredPaths.stream() + .map(Path::toString) + .noneMatch(p -> filePath.toString().startsWith(p)) && PathUtils.hasExtension(filePath, handledFileType) && !filePath.toString().endsWith(moduleInfoFilename)) .flatMap( @@ -296,6 +301,8 @@ public DirectoryBasedAnalysisInputLocation( @Override @Nonnull public Collection getClassSources(@Nonnull View view) { + // FIXME: 1) store the classprovider reference as a field; 2) and above too; and 3) move view + // which is only used in SootNode to be just there? return walkDirectory(path, view.getIdentifierFactory(), new AsmJavaClassProvider(view)); } diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java index f51cb1a084c..c1a2e762b98 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java @@ -30,7 +30,6 @@ import java.util.Collections; import java.util.List; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import sootup.core.model.SourceType; @@ -50,8 +49,8 @@ public class MultiReleaseJarAnalysisInputLocationTest extends AnalysisInputLocat ClassType classType; ClassType classType2; - @Before - public void setup() { + @Test + public void multiReleaseJar() { view_min = new JavaView( @@ -74,26 +73,21 @@ public void setup() { new MultiReleaseJarAnalysisInputLocation( mrj, SourceType.Application, new JavaLanguage(Integer.MAX_VALUE))); - classType = getIdentifierFactory().getClassType("de.upb.swt.multirelease.Utility"); - classType2 = getIdentifierFactory().getClassType("de.upb.swt.multirelease.Main"); - } - - @Test - public void multiReleaseJar() { + classType = getIdentifierFactory().getClassType("de.upb.sse.multirelease.Utility"); + classType2 = getIdentifierFactory().getClassType("de.upb.sse.multirelease.Main"); assertTrue(MultiReleaseJarAnalysisInputLocation.isMultiReleaseJar(mrj)); - // for java10 + // for java 8 Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_10.getClass(classType).get().getClassSource().getSourcePath().toString()); + "/de/upb/sse/multirelease/Utility.class", + view_8.getClass(classType).get().getClassSource().getSourcePath().toString()); Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_10.getClass(classType2).get().getClassSource().getSourcePath().toString()); - - // assert that method is correctly resolved + "/de/upb/sse/multirelease/Main.class", + view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); + // assert that method is correctly resolved to base Assert.assertTrue( - view_10 + view_8 .getClass(classType) .get() .getMethod( @@ -105,26 +99,27 @@ public void multiReleaseJar() { .get() .getBody() .toString() - .contains("java 9")); + .contains("java 8")); // for java 9 Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", + "/META-INF/versions/9/de/upb/sse/multirelease/Utility.class", view_9.getClass(classType).get().getClassSource().getSourcePath().toString()); Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", + "/de/upb/sse/multirelease/Main.class", view_9.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // for java 8 + // for java10 Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", - view_8.getClass(classType).get().getClassSource().getSourcePath().toString()); + "/META-INF/versions/10/de/upb/sse/multirelease/Utility.class", + view_10.getClass(classType).get().getClassSource().getSourcePath().toString()); Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // assert that method is correctly resolved to base + "/de/upb/sse/multirelease/Main.class", + view_10.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // assert that method is correctly resolved Assert.assertTrue( - view_8 + view_10 .getClass(classType) .get() .getMethod( @@ -136,23 +131,23 @@ public void multiReleaseJar() { .get() .getBody() .toString() - .contains("java 8")); - - // for max int - Assert.assertEquals( - "/META-INF/versions/9/de/upb/swt/multirelease/Utility.class", - view_max.getClass(classType).get().getClassSource().getSourcePath().toString()); - Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", - view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); + .contains("java 10")); // for min int Assert.assertEquals( - "/de/upb/swt/multirelease/Utility.class", + "/de/upb/sse/multirelease/Utility.class", view_min.getClass(classType).get().getClassSource().getSourcePath().toString()); Assert.assertEquals( - "/de/upb/swt/multirelease/Main.class", + "/de/upb/sse/multirelease/Main.class", view_min.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + // for max int + Assert.assertEquals( + "/META-INF/versions/10/de/upb/sse/multirelease/Utility.class", + view_max.getClass(classType).get().getClassSource().getSourcePath().toString()); + Assert.assertEquals( + "/de/upb/sse/multirelease/Main.class", + view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); } @Test 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 3026b91d2d7..6fca0f044b1 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 @@ -27,7 +27,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nonnull; -import sootup.core.cache.FullCache; import sootup.core.cache.provider.ClassCacheProvider; import sootup.core.cache.provider.FullCacheProvider; import sootup.core.inputlocation.AnalysisInputLocation; From 5f77222a322610073a024754dc9b7db94a221215 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 26 Jan 2024 17:15:01 +0100 Subject: [PATCH 51/57] never trust your inputs - modular. --- .../multi-release-jar-modular/createModMrJar.sh | 6 +++--- .../main/java/de/upb/{swt => sse}/multirelease/Main.java | 0 .../main/java/de/upb/{swt => sse}/multirelease/Utility.java | 0 .../java10/de/upb/{swt => sse}/multirelease/Utility.java | 0 .../src/main/java10/module-info.java | 2 +- .../java9/de/upb/{swt => sse}/multirelease/Utility.java | 0 .../src/main/java9/module-info.java | 2 +- 7 files changed, 5 insertions(+), 5 deletions(-) rename shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/{swt => sse}/multirelease/Main.java (100%) rename shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/{swt => sse}/multirelease/Utility.java (100%) rename shared-test-resources/multi-release-jar-modular/src/main/java10/de/upb/{swt => sse}/multirelease/Utility.java (100%) rename shared-test-resources/multi-release-jar-modular/src/main/java9/de/upb/{swt => sse}/multirelease/Utility.java (100%) diff --git a/shared-test-resources/multi-release-jar-modular/createModMrJar.sh b/shared-test-resources/multi-release-jar-modular/createModMrJar.sh index a006c783cdc..62ee8e435e6 100755 --- a/shared-test-resources/multi-release-jar-modular/createModMrJar.sh +++ b/shared-test-resources/multi-release-jar-modular/createModMrJar.sh @@ -2,9 +2,9 @@ # To build the jar: -javac --release 8 -d classes src/main/java/de/upb/swt/multirelease/*java -javac --release 9 -d classes-9 src/main/java9/de/upb/swt/multirelease/*java src/main/java9/module-info.java -javac --release 10 -d classes-10 src/main/java10/de/upb/swt/multirelease/*java src/main/java10/module-info.java +javac --release 8 -d classes src/main/java/de/upb/sse/multirelease/*java +javac --release 9 -d classes-9 src/main/java9/de/upb/sse/multirelease/*java src/main/java9/module-info.java +javac --release 10 -d classes-10 src/main/java10/de/upb/sse/multirelease/*java src/main/java10/module-info.java jar --create --file mrjar.jar --main-class multirelease.Main -C classes . --release 9 -C classes-9 . --release 10 -C classes-10 . diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Main.java b/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/sse/multirelease/Main.java similarity index 100% rename from shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Main.java rename to shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/sse/multirelease/Main.java diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Utility.java b/shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/sse/multirelease/Utility.java similarity index 100% rename from shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/swt/multirelease/Utility.java rename to shared-test-resources/multi-release-jar-modular/src/main/java/de/upb/sse/multirelease/Utility.java diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java10/de/upb/swt/multirelease/Utility.java b/shared-test-resources/multi-release-jar-modular/src/main/java10/de/upb/sse/multirelease/Utility.java similarity index 100% rename from shared-test-resources/multi-release-jar-modular/src/main/java10/de/upb/swt/multirelease/Utility.java rename to shared-test-resources/multi-release-jar-modular/src/main/java10/de/upb/sse/multirelease/Utility.java diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java10/module-info.java b/shared-test-resources/multi-release-jar-modular/src/main/java10/module-info.java index 84c3dc2c06d..e329256178f 100644 --- a/shared-test-resources/multi-release-jar-modular/src/main/java10/module-info.java +++ b/shared-test-resources/multi-release-jar-modular/src/main/java10/module-info.java @@ -1,3 +1,3 @@ module multirelease { -exports multirelease; + exports de.upb.sse.multirelease; } \ No newline at end of file diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java9/de/upb/swt/multirelease/Utility.java b/shared-test-resources/multi-release-jar-modular/src/main/java9/de/upb/sse/multirelease/Utility.java similarity index 100% rename from shared-test-resources/multi-release-jar-modular/src/main/java9/de/upb/swt/multirelease/Utility.java rename to shared-test-resources/multi-release-jar-modular/src/main/java9/de/upb/sse/multirelease/Utility.java diff --git a/shared-test-resources/multi-release-jar-modular/src/main/java9/module-info.java b/shared-test-resources/multi-release-jar-modular/src/main/java9/module-info.java index 84c3dc2c06d..e329256178f 100644 --- a/shared-test-resources/multi-release-jar-modular/src/main/java9/module-info.java +++ b/shared-test-resources/multi-release-jar-modular/src/main/java9/module-info.java @@ -1,3 +1,3 @@ module multirelease { -exports multirelease; + exports de.upb.sse.multirelease; } \ No newline at end of file From f79d1435c0bcacfa4beead74207a657126d74785 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 26 Jan 2024 23:18:20 +0100 Subject: [PATCH 52/57] copy de-incorporated comment to wip feature --- ...eMultiReleaseJarAnalysisInputLocation.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java index 30d01d601f0..f16f6866c01 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java @@ -48,6 +48,54 @@ public ModuleMultiReleaseJarAnalysisInputLocation( @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { super(path, srcType, language); + + /* + + + + // only versions >= 9 support java modules + if (availableVersions[i] > 8) { + moduleInfoMap.put(availableVersions[i], new HashMap<>()); + try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { + for (Path entry : stream) { + + Path mi = path.resolve(moduleInfoFilename); + + if (Files.exists(mi)) { + JavaModuleInfo moduleInfo = new AsmModuleSource(mi); + ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); + JavaModulePathAnalysisInputLocation inputLocation = + new JavaModulePathAnalysisInputLocation( + versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); + + inputLocations.get(availableVersions[i]).add(inputLocation); + moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); + } + + if (Files.isDirectory(entry)) { + mi = versionRoot.resolve(moduleInfoFilename); + + if (Files.exists(mi)) { + JavaModuleInfo moduleInfo = new AsmModuleSource(mi); + ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); + JavaModulePathAnalysisInputLocation inputLocation = + new JavaModulePathAnalysisInputLocation( + versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); + + inputLocations.get(availableVersions[i]).add(inputLocation); + moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); + } + // else TODO [bh] can we have automatic modules here? + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + + */ + throw new UnsupportedOperationException("not fully implemented, yet!"); } From eb38068dc858ec1f398a5c9856008943f74b51ad Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 29 Jan 2024 21:21:40 +0100 Subject: [PATCH 53/57] fix #763 --- .../JavaModulePathAnalysisInputLocation.java | 2 +- .../bytecode/inputlocation/ModuleFinder.java | 17 +++-- ...eMultiReleaseJarAnalysisInputLocation.java | 69 +++++++++---------- 3 files changed, 48 insertions(+), 40 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java index 4bbc266f17a..90068e1cd75 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java @@ -92,7 +92,7 @@ public JavaModulePathAnalysisInputLocation( @Nonnull List bodyInterceptors) { this.sourcetype = sourcetype; this.bodyInterceptors = bodyInterceptors; - moduleFinder = new ModuleFinder(modulePath, fileSystem, sourcetype); + moduleFinder = new ModuleFinder(modulePath, fileSystem, sourcetype, bodyInterceptors); } @Nonnull diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java index 9e897dbd272..d4e207e32c0 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java @@ -37,6 +37,7 @@ import sootup.core.frontend.ResolveException; import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.model.SourceType; +import sootup.core.transform.BodyInterceptor; import sootup.core.util.PathUtils; import sootup.java.bytecode.frontend.AsmModuleSource; import sootup.java.core.JavaModuleIdentifierFactory; @@ -64,6 +65,7 @@ public class ModuleFinder { @Nonnull private final List modulePathEntries; private final SourceType sourceType; + @Nonnull private final List bodyInterceptors; public boolean hasMoreToResolve() { return next < modulePathEntries.size(); @@ -76,8 +78,12 @@ public boolean hasMoreToResolve() { * @param sourceType */ public ModuleFinder( - @Nonnull Path modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourceType) { + @Nonnull Path modulePath, + @Nonnull FileSystem fileSystem, + @Nonnull SourceType sourceType, + @Nonnull List bodyInterceptors) { this.sourceType = sourceType; + this.bodyInterceptors = bodyInterceptors; this.modulePathEntries = JavaClassPathAnalysisInputLocation.explode(modulePath.toString(), fileSystem) .collect(Collectors.toList()); @@ -93,12 +99,15 @@ public ModuleFinder( } } - public ModuleFinder(@Nonnull Path modulePath, @Nonnull SourceType sourceType) { - this(modulePath, FileSystems.getDefault(), sourceType); + public ModuleFinder( + @Nonnull Path modulePath, + @Nonnull SourceType sourceType, + @Nonnull List bodyInterceptors) { + this(modulePath, FileSystems.getDefault(), sourceType, bodyInterceptors); } public ModuleFinder(@Nonnull Path modulePath) { - this(modulePath, FileSystems.getDefault(), SourceType.Application); + this(modulePath, FileSystems.getDefault(), SourceType.Application, Collections.emptyList()); } @Nonnull diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java index f16f6866c01..a9bd05c345a 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleMultiReleaseJarAnalysisInputLocation.java @@ -48,53 +48,52 @@ public ModuleMultiReleaseJarAnalysisInputLocation( @Nonnull Path path, @Nonnull SourceType srcType, @Nonnull Language language) { super(path, srcType, language); - /* - // only versions >= 9 support java modules - if (availableVersions[i] > 8) { - moduleInfoMap.put(availableVersions[i], new HashMap<>()); - try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { - for (Path entry : stream) { + // only versions >= 9 support java modules + if (availableVersions[i] > 8) { + moduleInfoMap.put(availableVersions[i], new HashMap<>()); + try (DirectoryStream stream = Files.newDirectoryStream(versionRoot)) { + for (Path entry : stream) { - Path mi = path.resolve(moduleInfoFilename); + Path mi = path.resolve(moduleInfoFilename); - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); + if (Files.exists(mi)) { + JavaModuleInfo moduleInfo = new AsmModuleSource(mi); + ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); + JavaModulePathAnalysisInputLocation inputLocation = + new JavaModulePathAnalysisInputLocation( + versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - inputLocations.get(availableVersions[i]).add(inputLocation); - moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); - } + inputLocations.get(availableVersions[i]).add(inputLocation); + moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); + } - if (Files.isDirectory(entry)) { - mi = versionRoot.resolve(moduleInfoFilename); + if (Files.isDirectory(entry)) { + mi = versionRoot.resolve(moduleInfoFilename); - if (Files.exists(mi)) { - JavaModuleInfo moduleInfo = new AsmModuleSource(mi); - ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); - JavaModulePathAnalysisInputLocation inputLocation = - new JavaModulePathAnalysisInputLocation( - versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); + if (Files.exists(mi)) { + JavaModuleInfo moduleInfo = new AsmModuleSource(mi); + ModuleSignature moduleSignature = moduleInfo.getModuleSignature(); + JavaModulePathAnalysisInputLocation inputLocation = + new JavaModulePathAnalysisInputLocation( + versionRoot.toString(), versionRoot.getFileSystem(), getSourceType()); - inputLocations.get(availableVersions[i]).add(inputLocation); - moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); - } - // else TODO [bh] can we have automatic modules here? - } - } - } catch (IOException e) { - e.printStackTrace(); - } - } + inputLocations.get(availableVersions[i]).add(inputLocation); + moduleInfoMap.get(availableVersions[i]).put(moduleSignature, moduleInfo); + } + // else TODO [bh] can we have automatic modules here? + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } - */ + */ throw new UnsupportedOperationException("not fully implemented, yet!"); } From 5922decef2b1e8a3f2fd0e80b562235b01ea7c82 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 29 Jan 2024 21:24:07 +0100 Subject: [PATCH 54/57] and pass interceptors further down --- .../sootup/java/bytecode/inputlocation/ModuleFinder.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java index d4e207e32c0..ed8b0634d3d 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/ModuleFinder.java @@ -216,9 +216,8 @@ private void discoverModulesIn(@Nonnull Path path) { private void buildModuleForExplodedModule(@Nonnull Path dir) throws ResolveException { // create the input location for this module dir - // TODO: propagte corresponding BodyInterceptors to newly cerated InputLocations PathBasedAnalysisInputLocation inputLocation = - PathBasedAnalysisInputLocation.create(dir, sourceType); + PathBasedAnalysisInputLocation.create(dir, sourceType, bodyInterceptors); Path moduleInfoFile = dir.resolve(JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"); if (!Files.exists(moduleInfoFile) && !Files.isRegularFile(moduleInfoFile)) { @@ -241,7 +240,7 @@ private void buildModuleForExplodedModule(@Nonnull Path dir) throws ResolveExcep */ private void buildModuleForJar(@Nonnull Path jar) { PathBasedAnalysisInputLocation inputLocation = - PathBasedAnalysisInputLocation.create(jar, sourceType); + PathBasedAnalysisInputLocation.create(jar, sourceType, bodyInterceptors); Path mi; try (FileSystem zipFileSystem = FileSystems.newFileSystem(jar, (ClassLoader) null)) { final Path archiveRoot = zipFileSystem.getPath("/"); From 564bba0458af42f02c0311177d3be8dcd09a931c Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 30 Jan 2024 12:17:10 +0100 Subject: [PATCH 55/57] test getClasses; fix typo in ignored Path --- .../bytecode/frontend/AsmClassSource.java | 2 +- .../JavaModulePathAnalysisInputLocation.java | 1 - .../MultiReleaseJarAnalysisInputLocation.java | 9 +++-- .../PathBasedAnalysisInputLocation.java | 15 +++++---- ...tiReleaseJarAnalysisInputLocationTest.java | 33 +++++++++++++------ 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmClassSource.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmClassSource.java index 8af776d8d2a..d6fb7063715 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmClassSource.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmClassSource.java @@ -168,7 +168,7 @@ public Optional resolveSuperclass() { if (classNode.superName == null) { return Optional.empty(); } - return Optional.ofNullable(AsmUtil.toJimpleClassType(classNode.superName)); + return Optional.of(AsmUtil.toJimpleClassType(classNode.superName)); } @Nonnull diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java index 90068e1cd75..a5751f671db 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaModulePathAnalysisInputLocation.java @@ -116,7 +116,6 @@ public Collection getClassSources(@Nonnull View view) { Collection allModules = moduleFinder.getAllModules(); return allModules.stream() .flatMap(sig -> getClassSourcesInternal(sig, view)) - .map(src -> (JavaSootClassSource) src) .collect(Collectors.toList()); } diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java index 0bb8232de9b..765a9e360d7 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocation.java @@ -76,7 +76,7 @@ public static AnalysisInputLocation create( } return PathBasedAnalysisInputLocation.create( - path, srcType, bodyInterceptors, Collections.singletonList(Paths.get("/META_INF"))); + path, srcType, bodyInterceptors, Collections.singletonList(Paths.get("/META-INF"))); } public MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nonnull Language language) { @@ -155,7 +155,7 @@ protected AnalysisInputLocation createAnalysisInputLocation( archiveRoot, sourceType, bodyInterceptors, - Collections.singletonList(Paths.get("/META_INF"))); + Collections.singletonList(Paths.get("/META-INF"))); } @Override @@ -179,8 +179,7 @@ public Collection getClassSources(@Nonnull View view) { Collection classSources = new ArrayList<>(); inputLocations.values().stream() - .map(location -> location.getClassSources(view)) - .flatMap(Collection::stream) + .flatMap(location -> location.getClassSources(view).stream()) .map(src -> (JavaSootClassSource) src) .forEach( cs -> { @@ -235,7 +234,7 @@ public List getBodyInterceptors() { } /** - * lists all versions from the version directories inside the META_INF/ directory - excluding the + * lists all versions from the version directories inside the META-INF/ directory - excluding the * default implemention version */ protected static List getLanguageVersions(@Nonnull Path path) { diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index eb3d769211b..ee36143a737 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -128,6 +128,11 @@ public static PathBasedAnalysisInputLocation create( @Nonnull SourceType srcType, @Nonnull List bodyInterceptors, @Nonnull Collection ignoredPaths) { + + if(ignoredPaths.stream().anyMatch( ignoPath -> path.toString().startsWith(ignoPath.toString()) )){ + throw new IllegalArgumentException("The Path for the AnalysisInputLocation is in the ignored paths."); + } + if (Files.isDirectory(path)) { return new DirectoryBasedAnalysisInputLocation(path, srcType, bodyInterceptors, ignoredPaths); } else if (PathUtils.isArchive(path)) { @@ -157,12 +162,10 @@ Collection walkDirectory( final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; try (final Stream walk = Files.walk(dirPath)) { return walk.filter( - filePath -> - ignoredPaths.stream() - .map(Path::toString) - .noneMatch(p -> filePath.toString().startsWith(p)) - && PathUtils.hasExtension(filePath, handledFileType) - && !filePath.toString().endsWith(moduleInfoFilename)) + filePath -> PathUtils.hasExtension(filePath, handledFileType) + && !filePath.toString().endsWith(moduleInfoFilename) + && ignoredPaths.stream().noneMatch(p -> filePath.toString().startsWith(p.toString())) + ) .flatMap( p -> { final String fullyQualifiedName = fromPath(dirPath, p); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java index c1a2e762b98..d64ff97d256 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java @@ -22,6 +22,7 @@ * #L% */ +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import categories.Java8Test; @@ -29,10 +30,14 @@ import java.nio.file.Paths; import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import sootup.core.model.SourceType; +import sootup.core.signatures.MethodSubSignature; import sootup.core.types.ClassType; import sootup.java.core.language.JavaLanguage; import sootup.java.core.views.JavaView; @@ -86,16 +91,17 @@ public void multiReleaseJar() { "/de/upb/sse/multirelease/Main.class", view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); // assert that method is correctly resolved to base + MethodSubSignature printBodyMethodSubSig = getIdentifierFactory() + .getMethodSubSignature( + "printVersion", + getIdentifierFactory().getType("void"), + Collections.emptyList()); Assert.assertTrue( view_8 .getClass(classType) .get() .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) + printBodyMethodSubSig) .get() .getBody() .toString() @@ -123,11 +129,7 @@ public void multiReleaseJar() { .getClass(classType) .get() .getMethod( - getIdentifierFactory() - .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList())) + printBodyMethodSubSig) .get() .getBody() .toString() @@ -148,6 +150,17 @@ public void multiReleaseJar() { Assert.assertEquals( "/de/upb/sse/multirelease/Main.class", view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); + + + // getClasses + List collectedClassesWPrintBody9 = view_9.getClasses().stream().map(c -> c.getMethod(printBodyMethodSubSig)).filter(Optional::isPresent).map(m -> m.get().getBody().toString()).collect(Collectors.toList()); + assertEquals(1, collectedClassesWPrintBody9.size()); + assertTrue(collectedClassesWPrintBody9.get(0).contains("java 9")); + + List collectedClassesWPrintBody10 = view_10.getClasses().stream().map(c -> c.getMethod(printBodyMethodSubSig)).filter(Optional::isPresent).map(m -> m.get().getBody().toString()).collect(Collectors.toList()); + assertEquals(1, collectedClassesWPrintBody10.size()); + assertTrue(collectedClassesWPrintBody10.get(0).contains("java 10")); + } @Test From 66a0cc8d18a30044d7c5df3a91f1c78e8a69617d Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 30 Jan 2024 12:42:32 +0100 Subject: [PATCH 56/57] its not easy beeing green /style --- .../PathBasedAnalysisInputLocation.java | 13 ++++---- ...tiReleaseJarAnalysisInputLocationTest.java | 30 +++++++++++-------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java index ee36143a737..e247066692b 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/PathBasedAnalysisInputLocation.java @@ -129,8 +129,10 @@ public static PathBasedAnalysisInputLocation create( @Nonnull List bodyInterceptors, @Nonnull Collection ignoredPaths) { - if(ignoredPaths.stream().anyMatch( ignoPath -> path.toString().startsWith(ignoPath.toString()) )){ - throw new IllegalArgumentException("The Path for the AnalysisInputLocation is in the ignored paths."); + if (ignoredPaths.stream() + .anyMatch(ignoPath -> path.toString().startsWith(ignoPath.toString()))) { + throw new IllegalArgumentException( + "The Path for the AnalysisInputLocation is in the ignored paths."); } if (Files.isDirectory(path)) { @@ -162,10 +164,11 @@ Collection walkDirectory( final String moduleInfoFilename = JavaModuleIdentifierFactory.MODULE_INFO_FILE + ".class"; try (final Stream walk = Files.walk(dirPath)) { return walk.filter( - filePath -> PathUtils.hasExtension(filePath, handledFileType) + filePath -> + PathUtils.hasExtension(filePath, handledFileType) && !filePath.toString().endsWith(moduleInfoFilename) - && ignoredPaths.stream().noneMatch(p -> filePath.toString().startsWith(p.toString())) - ) + && ignoredPaths.stream() + .noneMatch(p -> filePath.toString().startsWith(p.toString()))) .flatMap( p -> { final String fullyQualifiedName = fromPath(dirPath, p); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java index d64ff97d256..909e0fb5ed3 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/MultiReleaseJarAnalysisInputLocationTest.java @@ -32,7 +32,6 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; - import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -91,17 +90,15 @@ public void multiReleaseJar() { "/de/upb/sse/multirelease/Main.class", view_8.getClass(classType2).get().getClassSource().getSourcePath().toString()); // assert that method is correctly resolved to base - MethodSubSignature printBodyMethodSubSig = getIdentifierFactory() + MethodSubSignature printBodyMethodSubSig = + getIdentifierFactory() .getMethodSubSignature( - "printVersion", - getIdentifierFactory().getType("void"), - Collections.emptyList()); + "printVersion", getIdentifierFactory().getType("void"), Collections.emptyList()); Assert.assertTrue( view_8 .getClass(classType) .get() - .getMethod( - printBodyMethodSubSig) + .getMethod(printBodyMethodSubSig) .get() .getBody() .toString() @@ -128,8 +125,7 @@ public void multiReleaseJar() { view_10 .getClass(classType) .get() - .getMethod( - printBodyMethodSubSig) + .getMethod(printBodyMethodSubSig) .get() .getBody() .toString() @@ -151,16 +147,24 @@ public void multiReleaseJar() { "/de/upb/sse/multirelease/Main.class", view_max.getClass(classType2).get().getClassSource().getSourcePath().toString()); - // getClasses - List collectedClassesWPrintBody9 = view_9.getClasses().stream().map(c -> c.getMethod(printBodyMethodSubSig)).filter(Optional::isPresent).map(m -> m.get().getBody().toString()).collect(Collectors.toList()); + List collectedClassesWPrintBody9 = + view_9.getClasses().stream() + .map(c -> c.getMethod(printBodyMethodSubSig)) + .filter(Optional::isPresent) + .map(m -> m.get().getBody().toString()) + .collect(Collectors.toList()); assertEquals(1, collectedClassesWPrintBody9.size()); assertTrue(collectedClassesWPrintBody9.get(0).contains("java 9")); - List collectedClassesWPrintBody10 = view_10.getClasses().stream().map(c -> c.getMethod(printBodyMethodSubSig)).filter(Optional::isPresent).map(m -> m.get().getBody().toString()).collect(Collectors.toList()); + List collectedClassesWPrintBody10 = + view_10.getClasses().stream() + .map(c -> c.getMethod(printBodyMethodSubSig)) + .filter(Optional::isPresent) + .map(m -> m.get().getBody().toString()) + .collect(Collectors.toList()); assertEquals(1, collectedClassesWPrintBody10.size()); assertTrue(collectedClassesWPrintBody10.get(0).contains("java 10")); - } @Test From f139b8e2c134b86ac3bacfaf6578039709edd430 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Wed, 31 Jan 2024 17:21:49 +0100 Subject: [PATCH 57/57] incorporate PR feedback --- .../java/sootup/core/IdentifierFactory.java | 4 +++- .../bytecode/frontend/AsmMethodSourceTest.java | 3 ++- .../sootup/java/core/JavaIdentifierFactory.java | 17 ++++++++++------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/IdentifierFactory.java b/sootup.core/src/main/java/sootup/core/IdentifierFactory.java index eb3447d4b7d..ceb8c1256c9 100644 --- a/sootup.core/src/main/java/sootup/core/IdentifierFactory.java +++ b/sootup.core/src/main/java/sootup/core/IdentifierFactory.java @@ -246,7 +246,9 @@ FieldSignature getFieldSignature( boolean isStaticInitializerSubSignature(@Nonnull MethodSubSignature methodSubSignature); - boolean isConstructorSubSignature(@Nonnull MethodSignature methodSignature); + boolean isConstructorSignature(@Nonnull MethodSignature methodSignature); + + boolean isConstructorSubSignature(@Nonnull MethodSubSignature methodSubSignature); boolean isMainSubSignature(@Nonnull MethodSubSignature methodSubSignature); } diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/AsmMethodSourceTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/AsmMethodSourceTest.java index 54104c0e189..9bc9c6e1ec8 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/AsmMethodSourceTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/frontend/AsmMethodSourceTest.java @@ -39,7 +39,8 @@ public void testFix_StackUnderrun_convertPutFieldInsn_init() { Arrays.asList( "java.util.concurrent.Executor", "javax.management.MBeanNotificationInfo[]")); - assertTrue(idf.isConstructorSubSignature(mainMethodSignature)); + assertTrue(idf.isConstructorSignature(mainMethodSignature)); + assertTrue(idf.isConstructorSubSignature(mainMethodSignature.getSubSignature())); final SootClass abstractClass = view.getClass(mainClassSignature).get(); diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java index c3286ed3135..f5bd6c16012 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java +++ b/sootup.java.core/src/main/java/sootup/java/core/JavaIdentifierFactory.java @@ -55,20 +55,23 @@ public class JavaIdentifierFactory implements IdentifierFactory { @Nonnull private static final JavaIdentifierFactory INSTANCE = new JavaIdentifierFactory(); @Nonnull - public final MethodSubSignature STATIC_INITIALIZER = + public static final MethodSubSignature STATIC_INITIALIZER = new MethodSubSignature("", Collections.emptyList(), VoidType.getInstance()); @Override public boolean isStaticInitializerSubSignature(@Nonnull MethodSubSignature methodSubSignature) { - return methodSubSignature.getName().equals("") - && methodSubSignature.getParameterTypes().isEmpty() - && methodSubSignature.getType() == VoidType.getInstance(); + return methodSubSignature.equals(STATIC_INITIALIZER); } @Override - public boolean isConstructorSubSignature(@Nonnull MethodSignature methodSignature) { - return methodSignature.getName().equals("") - && methodSignature.getType() == VoidType.getInstance(); + public boolean isConstructorSignature(@Nonnull MethodSignature methodSignature) { + return isConstructorSubSignature(methodSignature.getSubSignature()); + } + + @Override + public boolean isConstructorSubSignature(@Nonnull MethodSubSignature methodSubSignature) { + return methodSubSignature.getName().equals("") + && methodSubSignature.getType() == VoidType.getInstance(); } @Override