diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index d29995cdcda..501160c33d5 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -12,6 +12,7 @@ on: - 'mkdocs.yml' - 'sootup.examples/**' - 'docs/**' + - '.github/workflows/gh-pages.yml' release: types: [ created, published ] @@ -26,6 +27,7 @@ on: - 'mkdocs.yml' - 'sootup.examples/**' - 'docs/**' + - '.github/workflows/gh-pages.yml' concurrency: pages @@ -63,6 +65,9 @@ jobs: git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" + # sanitive head_ref name + - run: echo "DOC_VERSION_NAME=$(echo ${{ github.head_ref }} | sed "s/[^[:alnum:]-]/_/g" )" >> $GITHUB_ENV + # on push to develop branch - keep a doc around for develop to show the current state - name: deploy doc in subdirectory if: github.event_name == 'push' @@ -71,27 +76,36 @@ jobs: # on PR events.. - name: deploy doc in subdirectory if: github.event_name == 'pull_request' - run: mike deploy ${{ github.head_ref }}_preview --push - # TODO: set to true when the release is capable of the documentation ;) && mike props ${{ github.head_ref }}_preview --set-string hidden=true --push + run: mike deploy ${{ env.DOC_VERSION_NAME }}_preview -t "PR Preview ${{ env.DOC_VERSION_NAME }}" && mike props ${{ env.DOC_VERSION_NAME }}_preview --set-string hidden=true --push - name: comment link to preview if: github.event_name == 'pull_request' && github.event.action != 'closed' uses: marocchino/sticky-pull-request-comment@v2 with: message: | - You updated the documentation - [Doc Preview](https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}_preview/${{ github.head_ref }}/). + You updated the documentation - [Doc Preview](https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ env.DOC_VERSION_NAME }}_preview/). # on PR close - delete preview - name: delete the deployed preview if: github.event_name == 'pull_request' && github.event.action == 'closed' - run: mike delete ${{ github.head_ref }}_preview --push + run: mike delete ${{ env.DOC_VERSION_NAME }}_preview --push # on release events.. + # sanitive head_ref name + - name: sanitize tag name + if: github.event_name == 'release' + run: echo "DOC_VERSION_NAME=$(echo ${{ github.ref_name }} | sed "s/[^[:alnum:]-]/_/g" )" >> $GITHUB_ENV + + - name: deploy doc in subdirectory + if: github.event_name == 'release' + run: mike deploy ${{ env.DOC_VERSION_NAME }} --push + + - name: deploy doc in subdirectory if: github.event_name == 'release' - run: mike deploy ${{ github.ref_name }} --push + run: mike deploy ${{ env.DOC_VERSION_NAME }} --push - name: set the new release doc as default (release published) if: github.event_name == 'release' && github.event.action == 'published' - run: mike deploy --push --update-aliases ${{ github.ref_name }} latest + run: mike deploy --push --update-aliases ${{ env.DOC_VERSION_NAME }} latest diff --git a/docs/call-graph-construction.md b/docs/call-graph-construction.md index 60bc3d93b40..ebf1462cdba 100644 --- a/docs/call-graph-construction.md +++ b/docs/call-graph-construction.md @@ -19,9 +19,7 @@ Below, we show how to create a type hierarchy: JavaProject project = JavaProject.builder(language) .addInputLocation(inputLocation) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .build(); JavaView view = project.createView(); diff --git a/sootup.analysis/src/test/java/sootup/analysis/interprocedural/icfg/ICFGDotExporterTest.java b/sootup.analysis/src/test/java/sootup/analysis/interprocedural/icfg/ICFGDotExporterTest.java index 25bddb3617e..7f80c33f221 100644 --- a/sootup.analysis/src/test/java/sootup/analysis/interprocedural/icfg/ICFGDotExporterTest.java +++ b/sootup.analysis/src/test/java/sootup/analysis/interprocedural/icfg/ICFGDotExporterTest.java @@ -16,6 +16,7 @@ import sootup.core.model.SootClass; import sootup.core.model.SootMethod; import sootup.core.signatures.MethodSignature; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; @@ -41,9 +42,7 @@ public CallGraph loadCallGraph(JavaView view) { public void ICFGDotExportTest() { JavaProject javaProject = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .addInputLocation( new JavaClassPathAnalysisInputLocation("src/test/resources/icfg/binary")) .build(); @@ -81,9 +80,7 @@ public void ICFGDotExportTest() { public void ICFGDotExportTest2() { JavaProject javaProject = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .addInputLocation( new JavaClassPathAnalysisInputLocation("src/test/resources/icfg/binary")) .build(); @@ -121,9 +118,7 @@ public void ICFGDotExportTest2() { public void ICFGArrayListDotExport() { JavaProject javaProject = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .addInputLocation( new JavaClassPathAnalysisInputLocation("src/test/resources/icfg/binary")) .build(); @@ -153,9 +148,7 @@ public void ICFGArrayListDotExport() { public void ICFGInterfaceDotExport() { JavaProject javaProject = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .addInputLocation( new JavaClassPathAnalysisInputLocation("src/test/resources/icfg/binary")) .build(); diff --git a/sootup.analysis/src/test/java/sootup/analysis/interprocedural/ifds/CGEdgeUtilTest.java b/sootup.analysis/src/test/java/sootup/analysis/interprocedural/ifds/CGEdgeUtilTest.java index 286a465ff8f..e76296062a4 100644 --- a/sootup.analysis/src/test/java/sootup/analysis/interprocedural/ifds/CGEdgeUtilTest.java +++ b/sootup.analysis/src/test/java/sootup/analysis/interprocedural/ifds/CGEdgeUtilTest.java @@ -41,7 +41,7 @@ import sootup.core.types.PrimitiveType; import sootup.core.types.Type; import sootup.core.util.printer.StmtPrinter; -import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; import sootup.java.core.language.JavaLanguage; @@ -137,9 +137,7 @@ public void testGetCallEdges() { JavaView view = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .addInputLocation( new JavaSourcePathAnalysisInputLocation("src/test/resources/callgraph/")) .build() diff --git a/sootup.analysis/src/test/java/sootup/analysis/interprocedural/ifds/IFDSTaintTestSetUp.java b/sootup.analysis/src/test/java/sootup/analysis/interprocedural/ifds/IFDSTaintTestSetUp.java index 57e091d2445..0ad5a5b31e4 100644 --- a/sootup.analysis/src/test/java/sootup/analysis/interprocedural/ifds/IFDSTaintTestSetUp.java +++ b/sootup.analysis/src/test/java/sootup/analysis/interprocedural/ifds/IFDSTaintTestSetUp.java @@ -30,6 +30,7 @@ import sootup.core.model.SootClass; import sootup.core.model.SootMethod; import sootup.core.signatures.MethodSignature; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; @@ -73,9 +74,7 @@ private void runAnalysis() { private void setupSoot(String targetTestClassName) { JavaProject javaProject = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .addInputLocation( new JavaClassPathAnalysisInputLocation("src/test/resources/taint/binary")) .build(); diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphTestBase.java b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphTestBase.java index 26c41ee37b8..e853b94fd40 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphTestBase.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphTestBase.java @@ -9,6 +9,7 @@ import sootup.core.model.SootMethod; import sootup.core.model.SourceType; import sootup.core.signatures.MethodSignature; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; @@ -35,9 +36,7 @@ private JavaView createViewForClassPath(String classPath) { private JavaView createViewForClassPath(String classPath, boolean useSourceCodeFrontend) { JavaProject.JavaProjectBuilder javaProjectBuilder = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar", SourceType.Library)); + .addInputLocation(new DefaultRTJarAnalysisInputLocation()); if (useSourceCodeFrontend) { javaProjectBuilder.addInputLocation(new JavaSourcePathAnalysisInputLocation(classPath)); } else { @@ -725,9 +724,7 @@ public void testStopAtLibraryClass() { String classPath = "src/test/resources/callgraph/Library/binary/"; JavaProject.JavaProjectBuilder javaProjectBuilder = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar", SourceType.Library)) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .addInputLocation( new JavaClassPathAnalysisInputLocation( classPath + "application/", SourceType.Application)) diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/ConcreteDispatchTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/ConcreteDispatchTest.java index d8d8ce95836..a69d9ef20d7 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/ConcreteDispatchTest.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/ConcreteDispatchTest.java @@ -14,6 +14,7 @@ import sootup.core.IdentifierFactory; import sootup.core.signatures.MethodSignature; import sootup.core.types.ClassType; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; import sootup.java.core.JavaProject; import sootup.java.core.language.JavaLanguage; @@ -35,9 +36,7 @@ public static void setUp() { .addInputLocation( new JavaClassPathAnalysisInputLocation( "src/test/resources/callgraph/ConcreteDispatch/binary")) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .build(); view = project.createView(); } diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/InstantiateClassValueVisitorTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/InstantiateClassValueVisitorTest.java index 2313bfaea48..3ae875e2878 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/InstantiateClassValueVisitorTest.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/InstantiateClassValueVisitorTest.java @@ -64,7 +64,7 @@ import sootup.core.types.ClassType; import sootup.core.types.PrimitiveType; import sootup.core.views.View; -import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.core.JavaProject; import sootup.java.core.JavaSootClass; import sootup.java.core.language.JavaJimple; @@ -77,9 +77,7 @@ public void testVisitor() { JavaProject javaProject = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .build(); View view = javaProject.createView(); IdentifierFactory identifierFactory = view.getIdentifierFactory(); diff --git a/sootup.core/src/main/java/sootup/core/IdentifierFactory.java b/sootup.core/src/main/java/sootup/core/IdentifierFactory.java index cd747f44586..6814d56e6cd 100644 --- a/sootup.core/src/main/java/sootup/core/IdentifierFactory.java +++ b/sootup.core/src/main/java/sootup/core/IdentifierFactory.java @@ -253,4 +253,10 @@ FieldSignature getFieldSignature( * @return the class type */ ClassType fromPath(Path rootDirectory, Path file); + + boolean isStaticInitializerSubSignature(@Nonnull MethodSubSignature methodSubSignature); + + boolean isConstructorSubSignature(@Nonnull MethodSubSignature methodSubSignature); + + boolean isMainSubSignature(@Nonnull MethodSubSignature methodSubSignature); } 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 8c66380901f..b4de840f5ce 100644 --- a/sootup.core/src/main/java/sootup/core/inputlocation/AnalysisInputLocation.java +++ b/sootup.core/src/main/java/sootup/core/inputlocation/AnalysisInputLocation.java @@ -46,7 +46,7 @@ * @author Ben Hermann * @author Linghui Luo */ -public interface AnalysisInputLocation { +public interface AnalysisInputLocation> { /** * Create or find a class source for a given type. * 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 ad2ecc7184c..809a7adba6e 100644 --- a/sootup.core/src/main/java/sootup/core/model/SootMethod.java +++ b/sootup.core/src/main/java/sootup/core/model/SootMethod.java @@ -35,6 +35,7 @@ import java.util.function.Supplier; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import sootup.core.IdentifierFactory; import sootup.core.frontend.BodySource; import sootup.core.frontend.OverridingBodySource; import sootup.core.frontend.ResolveException; @@ -208,10 +209,8 @@ public boolean isSynchronized() { } /** @return yes if this is the main method */ - public boolean isMain() { - return isPublic() - && isStatic() - && getSignature().getSubSignature().toString().equals("void main(java.lang.String[])"); + public boolean isMain(@Nonnull IdentifierFactory idf) { + return isPublic() && isStatic() && idf.isMainSubSignature(getSignature().getSubSignature()); } /** We rely on the JDK class recognition to decide if a method is JDK method. */ @@ -228,7 +227,7 @@ public void toString(@Nonnull StmtPrinter printer) { // print modifiers final Set modifiers = getModifiers(); printer.modifier(MethodModifier.toString(modifiers)); - if (modifiers.size() != 0) { + if (!modifiers.isEmpty()) { printer.literal(" "); } diff --git a/sootup.examples/src/test/java/sootup/examples/callgraph/CallgraphExample.java b/sootup.examples/src/test/java/sootup/examples/callgraph/CallgraphExample.java index 1c551b0a44d..bbdf3e08430 100644 --- a/sootup.examples/src/test/java/sootup/examples/callgraph/CallgraphExample.java +++ b/sootup.examples/src/test/java/sootup/examples/callgraph/CallgraphExample.java @@ -10,6 +10,7 @@ import sootup.core.typehierarchy.ViewTypeHierarchy; import sootup.core.types.ClassType; import sootup.core.types.VoidType; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; @@ -34,9 +35,7 @@ public void test() { JavaProject project = JavaProject.builder(language) .addInputLocation(inputLocation) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) // add rt.jar + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) // add rt.jar .build(); JavaView view = project.createView(); diff --git a/sootup.examples/src/test/java/sootup/examples/classhierarchy/ClassHierarchy.java b/sootup.examples/src/test/java/sootup/examples/classhierarchy/ClassHierarchy.java index 408ab93736f..70baf917263 100644 --- a/sootup.examples/src/test/java/sootup/examples/classhierarchy/ClassHierarchy.java +++ b/sootup.examples/src/test/java/sootup/examples/classhierarchy/ClassHierarchy.java @@ -8,6 +8,7 @@ import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.typehierarchy.ViewTypeHierarchy; import sootup.core.types.ClassType; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; @@ -44,9 +45,7 @@ public void test() { JavaProject project = JavaProject.builder(language) .addInputLocation(inputLocation) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) // add rt.jar + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) // add rt.jar .build(); JavaView view = project.createView(); diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/DefaultRTJarAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/DefaultRTJarAnalysisInputLocation.java new file mode 100644 index 00000000000..971f55e321b --- /dev/null +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/DefaultRTJarAnalysisInputLocation.java @@ -0,0 +1,43 @@ +package sootup.java.bytecode.inputlocation; +/*- + * #%L + * Soot - a J*va Optimization Framework + * %% + * Copyright (C) 2023 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 java.nio.file.Paths; +import javax.annotation.Nonnull; +import sootup.core.model.SourceType; + +/** + * Refers to the rt.jar from <=Java8 as an AnalysisInputLocation requires: JAVA_HOME to be set and + * expects the jar in the "lib/" subdirectory. If you need to include the rt.jar from a custom + * Location please make use of JavaClassPathAnalysisInputLocation. + */ +public class DefaultRTJarAnalysisInputLocation + extends PathBasedAnalysisInputLocation.ArchiveBasedAnalysisInputLocation { + + public DefaultRTJarAnalysisInputLocation() { + this(SourceType.Library); + } + + public DefaultRTJarAnalysisInputLocation(@Nonnull SourceType srcType) { + super(Paths.get(System.getProperty("java.home") + "/lib/rt.jar"), srcType); + } +} diff --git a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaClassPathAnalysisInputLocation.java b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaClassPathAnalysisInputLocation.java index f84ca90d9e7..b129a360a32 100644 --- a/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaClassPathAnalysisInputLocation.java +++ b/sootup.java.bytecode/src/main/java/sootup/java/bytecode/inputlocation/JavaClassPathAnalysisInputLocation.java @@ -80,12 +80,12 @@ public JavaClassPathAnalysisInputLocation( @Nonnull String classPath, @Nonnull SourceType srcType) { this.srcType = srcType; if (classPath.length() <= 0) { - throw new IllegalStateException("Empty class path given"); + throw new IllegalArgumentException("Empty class path given"); } cpEntries = explodeClassPath(classPath); if (cpEntries.isEmpty()) { - throw new IllegalStateException("Empty class path is given."); + throw new IllegalArgumentException("Empty class path is given."); } } @@ -133,9 +133,8 @@ public SourceType getSourceType() { @Nonnull String entry, FileSystem fileSystem) { if (entry.endsWith(WILDCARD_CHAR)) { Path baseDir = fileSystem.getPath(entry.substring(0, entry.indexOf(WILDCARD_CHAR))); - try { - return StreamUtils.iteratorToStream( - Files.newDirectoryStream(baseDir, "*.{jar,JAR}").iterator()); + try (final DirectoryStream paths = Files.newDirectoryStream(baseDir, "*.{jar,JAR}"); ) { + return StreamUtils.iteratorToStream(paths.iterator()); } catch (PatternSyntaxException | NotDirectoryException e) { throw new IllegalStateException("Malformed wildcard entry", e); } catch (IOException e) { @@ -213,14 +212,9 @@ private List> explodeClassPath(@Nonnull Str */ private List> explodeClassPath( @Nonnull String jarPath, @Nonnull FileSystem fileSystem) { - try { - return explode(jarPath, fileSystem) - .flatMap(cp -> StreamUtils.optionalToStream(inputLocationForPath(cp))) - .collect(Collectors.toList()); - - } catch (IllegalArgumentException e) { - throw new IllegalStateException("Malformed class path given: " + jarPath, e); - } + return explode(jarPath, fileSystem) + .flatMap(cp -> StreamUtils.optionalToStream(inputLocationForPath(cp))) + .collect(Collectors.toList()); } @Override 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 fe55c72d6f5..2c1a672ef84 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 @@ -87,7 +87,7 @@ public JavaModulePathAnalysisInputLocation( public JavaModulePathAnalysisInputLocation( @Nonnull String modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourcetype) { this.sourcetype = sourcetype; - moduleFinder = new ModuleFinder(modulePath, fileSystem); + moduleFinder = new ModuleFinder(modulePath, fileSystem, sourcetype); } @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 ce7eadecae0..dcb11c46a35 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 @@ -65,7 +65,7 @@ public class ModuleFinder { private int next = 0; @Nonnull private final List modulePathEntries; - private SourceType sourceType = null; // FIXME ! + private final SourceType sourceType; public boolean hasMoreToResolve() { return next < modulePathEntries.size(); @@ -75,8 +75,11 @@ public boolean hasMoreToResolve() { * Helper Class to discover modules in a given module path. * * @param modulePath the module path + * @param sourceType */ - public ModuleFinder(@Nonnull String modulePath, @Nonnull FileSystem fileSystem) { + public ModuleFinder( + @Nonnull String modulePath, @Nonnull FileSystem fileSystem, @Nonnull SourceType sourceType) { + this.sourceType = sourceType; this.modulePathEntries = JavaClassPathAnalysisInputLocation.explode(modulePath, fileSystem) .collect(Collectors.toList()); @@ -92,8 +95,12 @@ public ModuleFinder(@Nonnull String modulePath, @Nonnull FileSystem fileSystem) } } + public ModuleFinder(@Nonnull String modulePath, @Nonnull SourceType sourceType) { + this(modulePath, FileSystems.getDefault(), sourceType); + } + public ModuleFinder(@Nonnull String modulePath) { - this(modulePath, FileSystems.getDefault()); + this(modulePath, FileSystems.getDefault(), SourceType.Application); } @Nonnull 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..56e59839e19 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 @@ -78,9 +78,13 @@ public abstract class PathBasedAnalysisInputLocation private final SourceType sourceType; protected Path path; - protected PathBasedAnalysisInputLocation(Path path, SourceType srcType) { + protected PathBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { this.path = path; this.sourceType = srcType; + + if (!Files.exists(path)) { + throw new IllegalArgumentException("The provided path '" + path + "' does not exist."); + } } @Nullable @@ -96,14 +100,25 @@ public static PathBasedAnalysisInputLocation create( if (Files.isDirectory(path)) { inputLocation = new DirectoryBasedAnalysisInputLocation(path, srcType); } else if (PathUtils.isArchive(path)) { - if (PathUtils.hasExtension(path, FileType.WAR)) { - inputLocation = new WarArchiveAnalysisInputLocation(path, srcType); - } else if (isMultiReleaseJar(path)) { // check if mainfest contains multi release flag - inputLocation = new MultiReleaseJarAnalysisInputLocation(path, srcType); + if (PathUtils.hasExtension(path, FileType.JAR)) { + if (isMultiReleaseJar(path)) { + inputLocation = new MultiReleaseJarAnalysisInputLocation(path, srcType); + } else { + inputLocation = new ArchiveBasedAnalysisInputLocation(path, srcType); + } } else if (PathUtils.hasExtension(path, FileType.APK)) { inputLocation = new ApkAnalysisInputLocation(path, srcType); + } else if (PathUtils.hasExtension(path, FileType.WAR)) { + try { + inputLocation = new WarArchiveAnalysisInputLocation(path, srcType); + } catch (IOException e) { + throw new RuntimeException(e); + } } else { - inputLocation = new ArchiveBasedAnalysisInputLocation(path, srcType); + 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); @@ -199,11 +214,8 @@ protected Optional> getSingleClass( private static class ClassFileBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { public ClassFileBasedAnalysisInputLocation( - @Nonnull Path classPath, @Nonnull SourceType srcType) { - super(classPath, srcType); - if (!Files.exists(classPath)) { - throw new IllegalArgumentException("The provided .class file does not exist."); - } + @Nonnull Path classFilePath, @Nonnull SourceType srcType) { + super(classFilePath, srcType); } @Override @@ -228,7 +240,7 @@ public Collection> getClassSources( private static class DirectoryBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { - private DirectoryBasedAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { + private DirectoryBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { super(path, srcType); } @@ -265,7 +277,7 @@ public static class MultiReleaseJarAnalysisInputLocation extends ArchiveBasedAna boolean isResolved = false; - private MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { + private MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { super(path, srcType); int[] tmp; @@ -288,7 +300,7 @@ private MultiReleaseJarAnalysisInputLocation(@Nonnull Path path, @Nullable Sourc } /** Discovers all input locations for different java versions in this multi release jar */ - private void discoverInputLocations(@Nullable SourceType srcType) { + private void discoverInputLocations(@Nonnull SourceType srcType) { FileSystem fs = null; try { fs = fileSystemCache.get(path); @@ -523,7 +535,7 @@ public int hashCode() { private static class ApkAnalysisInputLocation extends ArchiveBasedAnalysisInputLocation { - private ApkAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { + private ApkAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { super(path, srcType); String jarPath = dex2jar(path); this.path = Paths.get(jarPath); @@ -540,7 +552,7 @@ private String dex2jar(Path path) { } } - private static class ArchiveBasedAnalysisInputLocation extends PathBasedAnalysisInputLocation { + 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 @@ -568,7 +580,7 @@ private static class ArchiveBasedAnalysisInputLocation extends PathBasedAnalysis } })); - private ArchiveBasedAnalysisInputLocation(@Nonnull Path path, @Nullable SourceType srcType) { + ArchiveBasedAnalysisInputLocation(@Nonnull Path path, @Nonnull SourceType srcType) { super(path, srcType); } @@ -608,16 +620,11 @@ private static final class WarArchiveAnalysisInputLocation public static int maxAllowedBytesToExtract = 1024 * 1024 * 500; // limit of extracted file size to protect against archive bombs - private WarArchiveAnalysisInputLocation(@Nonnull Path warPath, @Nullable SourceType srcType) { + private WarArchiveAnalysisInputLocation(@Nonnull Path warPath, @Nonnull SourceType srcType) + throws IOException { super( - Paths.get( - System.getProperty("java.io.tmpdir") - + File.separator - + "sootOutput" - + "-war" - + warPath.hashCode() - + "/"), - srcType); + Files.createTempDirectory("sootUp-war-" + warPath.hashCode()).toAbsolutePath(), srcType); + extractWarFile(warPath, path); Path webInfPath = path.resolve("WEB-INF"); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/RuntimeJarConversionTests.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/RuntimeJarConversionTests.java index 241d631c33a..38b704145fa 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/RuntimeJarConversionTests.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/RuntimeJarConversionTests.java @@ -1,12 +1,11 @@ package sootup.java.bytecode; -import java.nio.file.Paths; import org.junit.Test; import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.model.SootMethod; import sootup.core.signatures.MethodSignature; import sootup.java.bytecode.inputlocation.BytecodeClassLoadingOptions; -import sootup.java.bytecode.inputlocation.PathBasedAnalysisInputLocation; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; import sootup.java.core.JavaSootClass; @@ -16,9 +15,7 @@ public class RuntimeJarConversionTests { private static void execute(String methodSignature1) { - AnalysisInputLocation inputLocation = - PathBasedAnalysisInputLocation.create( - Paths.get(System.getProperty("java.home") + "/lib/rt.jar"), null); + AnalysisInputLocation inputLocation = new DefaultRTJarAnalysisInputLocation(); JavaProject project = JavaProject.builder(new JavaLanguage(8)).addInputLocation(inputLocation).build(); 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 c16724ab7e1..d5f54b0bacb 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 @@ -1,16 +1,16 @@ package sootup.java.bytecode.frontend; +import static junit.framework.Assert.assertTrue; import static junit.framework.TestCase.fail; import categories.Java8Test; import java.util.Arrays; -import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import sootup.core.model.SootClass; import sootup.core.model.SootMethod; import sootup.core.signatures.MethodSignature; -import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; import sootup.java.core.language.JavaLanguage; @@ -21,7 +21,6 @@ public class AsmMethodSourceTest { @Test - @Ignore("FIXME") public void testFix_StackUnderrun_convertPutFieldInsn_init() { double version = Double.parseDouble(System.getProperty("java.specification.version")); @@ -31,24 +30,23 @@ public void testFix_StackUnderrun_convertPutFieldInsn_init() { JavaProject javaProject = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .build(); JavaView view = javaProject.createView(); + final JavaIdentifierFactory idf = JavaIdentifierFactory.getInstance(); JavaClassType mainClassSignature = - JavaIdentifierFactory.getInstance() - .getClassType("javax.management.NotificationBroadcasterSupport"); + idf.getClassType("javax.management.NotificationBroadcasterSupport"); MethodSignature mainMethodSignature = - JavaIdentifierFactory.getInstance() - .getMethodSignature( - mainClassSignature, - "", - "void", - Arrays.asList( - "java.util.concurrent.Executor", "javax.management.MBeanNotificationInfo[]")); + idf.getMethodSignature( + mainClassSignature, + "", + "void", + Arrays.asList( + "java.util.concurrent.Executor", "javax.management.MBeanNotificationInfo[]")); + + assertTrue(idf.isConstructorSubSignature(mainMethodSignature.getSubSignature())); final SootClass abstractClass = view.getClass(mainClassSignature).get(); diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocationTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocationTest.java index e6344ced91e..5c96cabc826 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocationTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/inputlocation/JrtFileSystemAnalysisInputLocationTest.java @@ -56,11 +56,17 @@ public void getClassSources() { final ClassType sig2 = JavaModuleIdentifierFactory.getInstance().getClassType("System", "java.lang", "java.base"); + final JavaView view = project.createView(); final Collection> classSources = - inputLocation.getClassSources(project.createView()); - assertTrue(classSources.size() > 26000); + inputLocation.getClassSources(view); + assertTrue( + classSources.size() + > 20000); // not precise as this amount can differ depending on the included runtime + // library assertTrue(classSources.stream().anyMatch(cs -> cs.getClassType().equals(sig1))); + assertTrue(view.getClass(sig1).isPresent()); assertTrue(classSources.stream().anyMatch(cs -> cs.getClassType().equals(sig2))); + assertTrue(view.getClass(sig2).isPresent()); } @Test 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 f2a845a03ee..9e93e56379a 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,22 @@ public class ModuleFinderTest extends AnalysisInputLocationTest { @Test - public void discoverModuleByName() { + public void discoverJarModuleByName() { + ModuleFinder moduleFinder = new ModuleFinder(jar.toString()); + AnalysisInputLocation inputLocation = + moduleFinder.getModule(JavaModuleIdentifierFactory.getModuleSignature("MiniApp")); + assertTrue(inputLocation instanceof PathBasedAnalysisInputLocation); + } + + @Test + public void discoverJarModuleInAllModules() { + ModuleFinder moduleFinder = new ModuleFinder(jar.toString()); + Collection modules = moduleFinder.getAllModules(); + assertTrue(modules.contains(JavaModuleIdentifierFactory.getModuleSignature("MiniApp"))); + } + + @Test + public void discoverWarModuleByName() { ModuleFinder moduleFinder = new ModuleFinder(war.toString()); AnalysisInputLocation inputLocation = moduleFinder.getModule(JavaModuleIdentifierFactory.getModuleSignature("dummyWarApp")); @@ -25,7 +40,7 @@ public void discoverModuleByName() { } @Test - public void discoverModuleInAllModules() { + public void discoverWarModuleInAllModules() { ModuleFinder moduleFinder = new ModuleFinder(war.toString()); Collection modules = moduleFinder.getAllModules(); assertTrue(modules.contains(JavaModuleIdentifierFactory.getModuleSignature("dummyWarApp"))); 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..701d0143a22 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 @@ -421,9 +421,7 @@ void runtimeContains(View view, String classname, String packageName) { @Test public void testRuntimeJar() { - PathBasedAnalysisInputLocation pathBasedNamespace = - PathBasedAnalysisInputLocation.create( - Paths.get(System.getProperty("java.home") + "/lib/rt.jar"), null); + PathBasedAnalysisInputLocation pathBasedNamespace = new DefaultRTJarAnalysisInputLocation(); JavaView v = JavaProject.builder(new JavaLanguage(8)) @@ -450,9 +448,7 @@ public void testInputLocationLibraryMode() { JavaProject javaProject = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar", SourceType.Library)) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .build(); JavaView view = javaProject.createView(); 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 baee876f4e3..54e2b956ecb 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 @@ -560,8 +560,6 @@ private Body.BodyBuilder createTrapBody() { graph.setStartingStmt(startingStmt); - System.out.println(graph); - return builder; } diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/typeresolving/TypeAssignerTestSuite.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/typeresolving/TypeAssignerTestSuite.java index f837968b729..89e8df57694 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/typeresolving/TypeAssignerTestSuite.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/interceptors/typeresolving/TypeAssignerTestSuite.java @@ -4,11 +4,13 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.jimple.basic.Local; import sootup.core.model.Body; import sootup.core.signatures.MethodSignature; import sootup.core.types.ClassType; import sootup.core.types.Type; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; @@ -28,8 +30,7 @@ public void buildView(String baseDir, String className) { JavaClassPathAnalysisInputLocation analysisInputLocation = new JavaClassPathAnalysisInputLocation(baseDir); - JavaClassPathAnalysisInputLocation rtJar = - new JavaClassPathAnalysisInputLocation(System.getProperty("java.home") + "/lib/rt.jar"); + AnalysisInputLocation rtJar = new DefaultRTJarAnalysisInputLocation(); JavaProject project = JavaProject.builder(new JavaLanguage(8)) .addInputLocation(analysisInputLocation) diff --git a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java6/DeclareEnumWithConstructorTest.java b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java6/DeclareEnumWithConstructorTest.java index ac43bb021b2..eafcd52e7a7 100644 --- a/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java6/DeclareEnumWithConstructorTest.java +++ b/sootup.java.bytecode/src/test/java/sootup/java/bytecode/minimaltestsuite/java6/DeclareEnumWithConstructorTest.java @@ -61,9 +61,14 @@ public void test() { assertJimpleStmts(sootMethod, expectedBodyStmts()); sootMethod = loadMethod(getMainMethodSignature()); + assertTrue(sootMethod.isMain(identifierFactory)); + assertTrue(identifierFactory.isMainSubSignature(sootMethod.getSignature().getSubSignature())); assertJimpleStmts(sootMethod, expectedMainBodyStmts()); sootMethod = loadMethod(getEnumConstructorSignature()); + assertTrue( + identifierFactory.isStaticInitializerSubSignature( + sootMethod.getSignature().getSubSignature())); assertJimpleStmts(sootMethod, expectedEnumConstructorStmts()); sootMethod = loadMethod(getEnumGetValueSignature()); 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..19732777fd7 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 @@ -56,6 +56,27 @@ public class JavaIdentifierFactory implements IdentifierFactory { @Nonnull private static final JavaIdentifierFactory INSTANCE = new JavaIdentifierFactory(); + @Override + public boolean isStaticInitializerSubSignature(@Nonnull MethodSubSignature methodSubSignature) { + return methodSubSignature.getName().equals(""); + } + + @Override + public boolean isConstructorSubSignature(@Nonnull MethodSubSignature methodSubSignature) { + return methodSubSignature.getName().equals(""); + } + + @Override + public boolean isMainSubSignature(@Nonnull MethodSubSignature methodSubSignature) { + if (methodSubSignature.getName().equals("main")) { + final List parameterTypes = methodSubSignature.getParameterTypes(); + if (parameterTypes.size() == 1) { + return parameterTypes.get(0).toString().equals("java.lang.String[]"); + } + } + return false; + } + /** Caches the created PackageNames for packages. */ @Nonnull protected final Cache packageCache = diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaModuleIdentifierFactory.java b/sootup.java.core/src/main/java/sootup/java/core/JavaModuleIdentifierFactory.java index 0a24d88ac3f..bf5c49ad4fc 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/JavaModuleIdentifierFactory.java +++ b/sootup.java.core/src/main/java/sootup/java/core/JavaModuleIdentifierFactory.java @@ -28,6 +28,8 @@ import javax.annotation.Nonnull; import org.apache.commons.lang3.ClassUtils; import sootup.core.signatures.MethodSignature; +import sootup.core.signatures.MethodSubSignature; +import sootup.core.types.Type; import sootup.java.core.signatures.ModulePackageName; import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.ModuleJavaClassType; @@ -69,6 +71,17 @@ public static JavaModuleIdentifierFactory getInstance(@Nonnull ModuleSignature m modules.put(ModuleSignature.UNNAMED_MODULE.getModuleName(), ModuleSignature.UNNAMED_MODULE); } + @Override + public boolean isMainSubSignature(@Nonnull MethodSubSignature methodSubSignature) { + if (methodSubSignature.getName().equals("main")) { + final List parameterTypes = methodSubSignature.getParameterTypes(); + if (parameterTypes.size() == 1) { + return parameterTypes.get(0).toString().equals("java.base/java.lang.String[]"); + } + } + return false; + } + @Override public ModuleJavaClassType getClassType(final String className, final String packageName) { return getClassType(className, packageName, ModuleSignature.UNNAMED_MODULE.getModuleName()); diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaModuleInfo.java b/sootup.java.core/src/main/java/sootup/java/core/JavaModuleInfo.java index 5fb889990ef..11340609077 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/JavaModuleInfo.java +++ b/sootup.java.core/src/main/java/sootup/java/core/JavaModuleInfo.java @@ -24,7 +24,6 @@ import java.util.*; import javax.annotation.Nonnull; -import sootup.core.frontend.ResolveException; import sootup.java.core.signatures.ModulePackageName; import sootup.java.core.signatures.ModuleSignature; import sootup.java.core.types.JavaClassType; @@ -87,33 +86,33 @@ public ModuleSignature getModuleSignature() { @Override public Collection requires() { // can read all other modules and the unnamed module (modules on the classpath) - throw new ResolveException( + throw new UnsupportedOperationException( "All modules can be required from the automatic module. Handle it separately."); } @Override public Collection exports() { // all Packages are exported - throw new ResolveException( + throw new UnsupportedOperationException( "All Packages are exported in the automatic module. Handle it separately."); } @Override public Collection opens() { // all Packages are open - throw new ResolveException( + throw new UnsupportedOperationException( "All Packages are open in the automatic module. Handle it separately."); } @Override public Collection provides() { - throw new ResolveException( + throw new UnsupportedOperationException( "All Packages are open in the automatic module. Handle it separately."); } @Override public Collection uses() { - throw new ResolveException( + throw new UnsupportedOperationException( "All Packages are open in the automatic module. Handle it separately."); } diff --git a/sootup.java.core/src/main/java/sootup/java/core/JavaSootMethod.java b/sootup.java.core/src/main/java/sootup/java/core/JavaSootMethod.java index b9e84dc6b71..d7271cbe0b9 100644 --- a/sootup.java.core/src/main/java/sootup/java/core/JavaSootMethod.java +++ b/sootup.java.core/src/main/java/sootup/java/core/JavaSootMethod.java @@ -38,8 +38,6 @@ import sootup.java.core.views.JavaView; public class JavaSootMethod extends SootMethod { - @Nonnull protected static final String CONSTRUCTOR_NAME = ""; - @Nonnull protected static final String STATIC_INITIALIZER_NAME = ""; @Nonnull private final Iterable annotations; public JavaSootMethod( @@ -53,19 +51,6 @@ public JavaSootMethod( this.annotations = annotations; } - /** - * @return yes, if this function is a constructor. Please not that <clinit> methods are not - * treated as constructors in this methodRef. - */ - public boolean isConstructor() { - return this.getSignature().getName().equals(CONSTRUCTOR_NAME); - } - - /** @return yes, if this function is a static initializer. */ - public boolean isStaticInitializer() { - return this.getSignature().getName().equals(STATIC_INITIALIZER_NAME); - } - @Nonnull public Iterable getAnnotations(@Nonnull Optional view) { resolveDefaultsForAnnotationTypes(view, annotations); 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 c434e537f57..95e70adc76d 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 @@ -31,7 +31,6 @@ import sootup.core.cache.FullCache; import sootup.core.cache.provider.FullCacheProvider; import sootup.core.frontend.AbstractClassSource; -import sootup.core.frontend.ResolveException; import sootup.core.inputlocation.AnalysisInputLocation; import sootup.core.inputlocation.ClassLoadingOptions; import sootup.core.inputlocation.EmptyClassLoadingOptions; @@ -118,7 +117,7 @@ private boolean isPackageVisibleToModule( Optional moduleInfoOpt = getModuleInfo(packageName.getModuleSignature()); if (!moduleInfoOpt.isPresent()) { - throw new ResolveException("ModuleDescriptor not available."); + throw new IllegalStateException("ModuleDescriptor not available."); } JavaModuleInfo moduleInfo = moduleInfoOpt.get(); 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 7fd91ca9cfd..9d6bc837b90 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 @@ -21,6 +21,7 @@ * #L% */ +import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; import javax.annotation.Nonnull; @@ -84,6 +85,13 @@ public JavaSourcePathAnalysisInputLocation( this.sourcePaths = sourcePaths; this.exclusionFilePath = exclusionFilePath; this.classProvider = new WalaJavaClassProvider(sourcePaths, exclusionFilePath); + + final Optional any = + sourcePaths.stream().filter(path -> !Files.exists(Paths.get(path))).findAny(); + any.ifPresent( + s -> { + throw new IllegalArgumentException("The provided path " + any.get() + " does not exist."); + }); } /** diff --git a/sootup.tests/src/test/java/sootup/tests/CallGraphTest.java b/sootup.tests/src/test/java/sootup/tests/CallGraphTest.java index 440ac9bb96c..49d7385a66c 100644 --- a/sootup.tests/src/test/java/sootup/tests/CallGraphTest.java +++ b/sootup.tests/src/test/java/sootup/tests/CallGraphTest.java @@ -13,7 +13,7 @@ import sootup.core.model.SootClass; import sootup.core.model.SootMethod; import sootup.core.signatures.MethodSignature; -import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.core.JavaIdentifierFactory; import sootup.java.core.JavaProject; import sootup.java.core.language.JavaLanguage; @@ -40,9 +40,7 @@ protected AbstractCallGraphAlgorithm createAlgorithm(JavaView view) { private JavaView createViewForClassPath(String classPath) { JavaProject javaProject = JavaProject.builder(new JavaLanguage(8)) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .addInputLocation(new JavaSourcePathAnalysisInputLocation(classPath)) .build(); return javaProject.createView(); @@ -247,8 +245,7 @@ public void checkCallGraphDotExporter() { + "\t\"()>\" -> \"()>\";\n" + "\t\"()>\" -> \"()>\";\n" + "\t\"()>\" -> \"()>\";\n" - + "\t\"()>\" -> \"()>\";\n" - + "\t\"()>\" -> \"\";\n}"; - assertEquals(actualContent, expectedContent); + + "}"; + assertEquals(expectedContent, actualContent); } } diff --git a/sootup.tests/src/test/java/sootup/tests/typehierarchy/HierarchyComparatorTest.java b/sootup.tests/src/test/java/sootup/tests/typehierarchy/HierarchyComparatorTest.java index e431486ae2d..e73369d7ae2 100644 --- a/sootup.tests/src/test/java/sootup/tests/typehierarchy/HierarchyComparatorTest.java +++ b/sootup.tests/src/test/java/sootup/tests/typehierarchy/HierarchyComparatorTest.java @@ -14,7 +14,7 @@ import sootup.core.typehierarchy.HierarchyComparator; import sootup.core.types.ClassType; import sootup.core.views.View; -import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; +import sootup.java.bytecode.inputlocation.DefaultRTJarAnalysisInputLocation; import sootup.java.core.JavaProject; import sootup.java.core.language.JavaLanguage; import sootup.java.sourcecode.inputlocation.JavaSourcePathAnalysisInputLocation; @@ -31,9 +31,7 @@ public static void setUp() { .addInputLocation( new JavaSourcePathAnalysisInputLocation( Collections.singleton("src/test/resources/javatypehierarchy/Comparator"))) - .addInputLocation( - new JavaClassPathAnalysisInputLocation( - System.getProperty("java.home") + "/lib/rt.jar")) + .addInputLocation(new DefaultRTJarAnalysisInputLocation()) .build(); view = project.createView(); }