diff --git a/simplecfg/build.gradle b/simplecfg/build.gradle index 45deaad9613999f038146ab8300b717967db3d1b..d5b56af3e0f58494b310e09edfc6ededc7cd4f05 100644 --- a/simplecfg/build.gradle +++ b/simplecfg/build.gradle @@ -32,6 +32,7 @@ sourceSets.main { srcDirs "src/gen/java" srcDirs '../extendj/src/frontend' + srcDirs '../extendj/src/frontend-main' } resources { srcDir '../extendj/src/res' diff --git a/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerFrontend.java b/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerFrontend.java index fb9ad9d1fbae37eb5cc851e2b5f80028bf53fa0e..6e3871b77180191e9bdcf72e3ee42c2bfd106ec9 100644 --- a/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerFrontend.java +++ b/simplecfg/src/main/java/com/google/simplecfg/ExtendJAnalyzerFrontend.java @@ -16,6 +16,7 @@ package com.google.simplecfg; import org.extendj.ast.*; +import org.extendj.ExtendJVersion; import java.io.FileNotFoundException; import java.io.IOException; @@ -29,29 +30,14 @@ import java.util.Iterator; */ public class ExtendJAnalyzerFrontend extends Frontend { - private final JavaParser javaParser; - private final BytecodeReader bytecodeReader; - private final Collection<ExtendJFinding> findings = new ArrayList<ExtendJFinding>(); - - /** Create new analyzer instance. */ public ExtendJAnalyzerFrontend() { - super("ExtendJ Analyzer", "v1.0"); - javaParser = new JavaParser() { - @Override - public CompilationUnit parse(InputStream is, String fileName) - throws IOException, beaver.Parser.Exception { - return new org.extendj.parser.JavaParser().parse(is, fileName); - } - }; - bytecodeReader = new BytecodeReader() { - @Override - public CompilationUnit read(InputStream is, String fullName, Program p) - throws FileNotFoundException, IOException { - return new BytecodeParser(is, fullName).parse(null, null, p); - } - }; + super("Simple CFG Checker", ExtendJVersion.getVersion()); } + private final Collection<ExtendJFinding> findings = new ArrayList<>(); + + + /** * Analyze a single file for findings and return the findings in a collection. */ @@ -78,78 +64,16 @@ public class ExtendJAnalyzerFrontend extends Frontend { * @param args command-line arguments * @return 0 on success, 1 on error, 2 on configuration error, 3 on system */ - public int run(String args[]) { - return run(args, bytecodeReader, javaParser); + public int run(String[] args) { + return run(args, Program.defaultBytecodeReader(), Program.defaultJavaParser()); } @Override protected int processCompilationUnit(CompilationUnit unit) { + super.processCompilationUnit(unit); if (unit.fromSource()) { findings.addAll(unit.findings()); } return EXIT_SUCCESS; } - - @Override - public int run(String[] args, BytecodeReader reader, JavaParser parser) { - program.resetStatistics(); - program.setTypeLookupFilter(Program.ANALYZER_TYPE_FILTER); - program.initBytecodeReader(bytecodeReader); - program.initJavaParser(javaParser); - - initOptions(); - int argResult = processArgs(args); - if (argResult != 0) { - return argResult; - } - - if (program.options().hasOption("-version")) { - printVersion(); - return EXIT_SUCCESS; - } - - Collection<String> files = program.options().files(); - if (program.options().hasOption("-help") || files.isEmpty()) { - printUsage(); - return EXIT_SUCCESS; - } - - return run(files); - } - - private int run(Collection<String> files) { - try { - for (String file : files) { - // Calling addSourceFile will parse the file and add it to the program AST. - program.addSourceFile(file); - } - - // Process source compilation units. - int compileResult = EXIT_SUCCESS; - - Iterator<CompilationUnit> iter = program.compilationUnitIterator(); - while (iter.hasNext()) { - CompilationUnit unit = iter.next(); - int result = processCompilationUnit(unit); - if (result != EXIT_SUCCESS) { - compileResult = result; - if (compileResult == EXIT_UNHANDLED_ERROR) { - // Stop immediately when an unhandled error is encountered. - return compileResult; - } - } - } - - if (compileResult != EXIT_SUCCESS) { - return compileResult; - } - } catch (IOException e) { - throw new Error(e); - } finally { - if (program.options().hasOption("-profile")) { - program.printStatistics(System.out); - } - } - return EXIT_SUCCESS; - } } diff --git a/simplecfg/src/test/java/com/google/simplecfg/AlreadyClosedTest.java b/simplecfg/src/test/java/com/google/simplecfg/AlreadyClosedTest.java index 687f228b68c4c4335c15c8c051b8c1b9ccac326d..b2db5b2dda0a72955e5472f99619582b697d7e18 100644 --- a/simplecfg/src/test/java/com/google/simplecfg/AlreadyClosedTest.java +++ b/simplecfg/src/test/java/com/google/simplecfg/AlreadyClosedTest.java @@ -30,7 +30,7 @@ import java.util.Collection; public class AlreadyClosedTest { @Test public void test01() { - Collection<String> findings = StmtCfgTest.findings("Close01", Program.NO_TYPE_FILTER); + Collection<String> findings = StmtCfgTest.findings("Close01", Program.ANALYZER_TYPE_FILTER); assertThat(findings).containsExactly( "testdata/Close01.javax:23:5: close() may have already been called on writer at this point"); } @@ -44,7 +44,7 @@ public class AlreadyClosedTest { */ @Test public void writer01() { Collection<String> findings = StmtCfgTest.findings("AlreadyClosedWriter01", - Program.NO_TYPE_FILTER); + Program.ANALYZER_TYPE_FILTER); assertThat(findings).hasSize(1); assertThat(findings).containsExactly( "testdata/AlreadyClosedWriter01.javax:27:5: close() may have already been called on writer at this point"); @@ -58,7 +58,7 @@ public class AlreadyClosedTest { @Test public void negativeFindings01() { Collection<String> findings = StmtCfgTest.findings("AlreadyClosedNegativeFindings01", - Program.NO_TYPE_FILTER); + Program.ANALYZER_TYPE_FILTER); assertThat(findings).isEmpty(); } } diff --git a/simplecfg/src/test/java/com/google/simplecfg/StmtCfgTest.java b/simplecfg/src/test/java/com/google/simplecfg/StmtCfgTest.java index 974b17485fea1dffefea174725b1c4ea6303a9e4..dddb8f8f825f696e69da9e848c505f320ce2cd26 100644 --- a/simplecfg/src/test/java/com/google/simplecfg/StmtCfgTest.java +++ b/simplecfg/src/test/java/com/google/simplecfg/StmtCfgTest.java @@ -15,34 +15,15 @@ */ package com.google.simplecfg; -import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; - -import org.extendj.ast.BytecodeParser; -import org.extendj.ast.BytecodeReader; -import org.extendj.ast.CfgNode; -import org.extendj.ast.CompilationUnit; -import org.extendj.ast.ExtendJFinding; -import org.extendj.ast.FileClassSource; -import org.extendj.ast.JavaParser; -import org.extendj.ast.Program; -import org.extendj.ast.SourceFolderPath; -import org.extendj.ast.TypeLookupFilter; - +import org.extendj.ast.*; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; +import java.util.*; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; /** Tests for simplified Control Flow Graphs built for methods/constructors/initializers. */ @RunWith(JUnit4.class) @@ -52,32 +33,24 @@ public class StmtCfgTest { protected static CompilationUnit parseFile(String filename, TypeLookupFilter typeFilter) { String path = "testdata/" + filename + ".javax"; try { - JavaParser javaParser = new JavaParser() { - @Override - public CompilationUnit parse(java.io.InputStream is, String fileName) - throws IOException, beaver.Parser.Exception { - return new org.extendj.parser.JavaParser().parse(is, fileName); - } - }; - BytecodeReader bytecodeReader = new BytecodeReader() { - @Override - public CompilationUnit read(InputStream is, String fullName, Program p) - throws FileNotFoundException, IOException { - return new BytecodeParser(is, fullName).parse(null, null, p); - } - }; Program program = new Program(); - program.initBytecodeReader(bytecodeReader); - program.initJavaParser(javaParser); + program.initBytecodeReader(Program.defaultBytecodeReader()); + program.initJavaParser(Program.defaultJavaParser()); program.setTypeLookupFilter(typeFilter); - CompilationUnit unit = javaParser.parse(new FileInputStream(path), path); - // Attach the parsed unit to a program node so we have a healthy AST. - program.addCompilationUnit(unit); - // Ensure compilation unit is set to final. This is important to get - // caching to work right in the AST. - unit = program.getCompilationUnit(0); - unit.setClassSource(new FileClassSource(new SourceFolderPath("testdata"), path)); - unit.setFromSource(true); + + CompilationUnit unit = program.addSourceFile(path); + + TypeDecl object = program.lookupType("java.lang", "Object"); + if (object.isUnknown()) { + // If we try to continue without java.lang.Object, we'll just get a stack overflow + // in member lookups because the unknown (Object) type would be treated as circular. + System.err.println("Error: java.lang.Object is missing." + + " The Java standard library was not found."); + throw new RuntimeException("exiting with unhandled error!"); + } else { + System.out.println("Success: java.lang.Object and thus the Java standard library was found."); + } + return unit; } catch (Exception e) { e.printStackTrace();