diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8bc1061c44147b7e5a6eea5807d20fa1c4e19314..899deca0620bff12dc5d17ca10932a52693ab965 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,7 +15,7 @@ build: - dockered stage: build script: - - ./gradlew --console=plain --build-cache assemble + - ./gradlew --console=plain --build-cache assemble -x ":drast:assemble" cache: key: "$CI_COMMIT_REF_NAME" policy: push @@ -29,7 +29,7 @@ test: - dockered stage: test script: - - ./gradlew --continue --console=plain check + - ./gradlew --continue --console=plain check -x ":drast:check" cache: key: "$CI_COMMIT_REF_NAME" policy: pull diff --git a/drast/.gitignore b/drast/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a745ae2e144d6fe0fb7242c63535a75e2276a08a --- /dev/null +++ b/drast/.gitignore @@ -0,0 +1 @@ +DrAST.cfg diff --git a/drast/build.gradle b/drast/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..a13fa3a0d05306a9e8a56d2f7c6152267f84b0d4 --- /dev/null +++ b/drast/build.gradle @@ -0,0 +1,22 @@ +plugins { + id 'java' + id 'application' +} + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + implementation project(':scope4j') + implementation files('../tools/DrAST-1.2.2.jar') + implementation fileTree(dir: "${System.properties['java.home']}", include: '**/jfxrt.jar') +} + +run { + mainClassName = 'de.tudresden.inf.st.scope4j.DrAstRunner' + doFirst { environment 'JAVA_TOOL_OPTIONS', '-Dlog4j2.disableJmx=true' } +} +run.dependsOn ':scope4j:jar' diff --git a/drast/src/main/java/de/tudresden/inf/st/scope4j/DrAstRunner.java b/drast/src/main/java/de/tudresden/inf/st/scope4j/DrAstRunner.java new file mode 100644 index 0000000000000000000000000000000000000000..d17eb838e06ecb65703931571463086fcf165101 --- /dev/null +++ b/drast/src/main/java/de/tudresden/inf/st/scope4j/DrAstRunner.java @@ -0,0 +1,83 @@ +package de.tudresden.inf.st.scope4j; + +import drast.Log; +import drast.model.DrAST; +import drast.model.DrASTSettings; +import drast.model.TreeFilter; +import drast.views.gui.DrASTGUI; +import drast.views.gui.GUIData; +import drast.views.gui.controllers.Controller; +import drast.views.gui.graph.GraphView; +import javafx.application.Platform; +import javafx.fxml.FXMLLoader; +import javafx.geometry.Rectangle2D; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.ScrollPane; +import javafx.stage.Screen; +import javafx.stage.Stage; + +/** + * Extended runner for DrAST + * + * @author jmey - Initial contribution + */ +public class DrAstRunner extends DrASTGUI { + + public static void main(String[] args) { + + openView(); + System.exit(0); + + } + + private static final GUIData mon = new GUIData(); + private static Controller con; + private static boolean guiHasBeenCreated = false; + + private static void openView() { + guiHasBeenCreated = true; + DrASTSettings.put(DrASTSettings.PREV_JAR, "../scope4j/scope4j.jar"); + DrASTSettings.put(DrASTSettings.PREV_TAIL_ARGS, "--drast"); + launch(); + con.onApplicationClose(); + } + + public void setRoot(Object root) { + long timeStart = System.currentTimeMillis(); + DrAST newAst = new DrAST(root, TreeFilter.readFilter(con.getFilter())); + Log.info("Filter update: done after %d ms", System.currentTimeMillis() - timeStart); + Platform.runLater(() -> { + mon.reset(newAst); + if (guiHasBeenCreated) { + con.onSetRoot(); + } else { + openView(); + } + + }); + } + + public void start(Stage stage) throws Exception { + FXMLLoader loader = new FXMLLoader(); + Parent rootView = loader.load(this.getClass().getResource("/main.fxml").openStream()); + con = loader.getController(); + mon.setParentStage(stage); + mon.setController(con); + mon.setDrASTUI(this); + mon.setStage(stage); + GraphView graphview = new GraphView(mon); + graphview.setOnMouseClicked((event) -> graphview.getParent().requestFocus()); + mon.setGraphView(graphview); + con.init(mon); + Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds(); + stage.setTitle("Scope4J DrAST 1.2.2"); + stage.setScene(new Scene(rootView, primaryScreenBounds.getWidth(), primaryScreenBounds.getHeight() - 100.0D)); + stage.show(); + ScrollPane center = (ScrollPane)rootView.lookup("#graphViewScrollPane"); + center.setContent(graphview); + Platform.runLater(() -> graphview.setPreferredSize((int)center.getWidth(), (int)center.getHeight())); + con.loadPreviousFilter(); + } + +} diff --git a/scope/src/main/jastadd/Shadowing.jrag b/scope/src/main/jastadd/Shadowing.jrag index 8bd777b431711d498044c13495e64978e5029b21..5c37ee81a752b76949c42dc1184f4c896509bad7 100644 --- a/scope/src/main/jastadd/Shadowing.jrag +++ b/scope/src/main/jastadd/Shadowing.jrag @@ -4,7 +4,7 @@ aspect Shadowing { Declaration contributes new VariableShadowFinding(shadowed(), this) when isShadowing() to ScopeTree.variableShadowings(); Declaration contributes new MultipleDeclarationFinding(this) when isShadowingInSameScope() to ScopeTree.variableShadowings(); - syn Declaration Declaration.shadowed()= shadowed(asDeclaration()); + syn Declaration Declaration.shadowed() = shadowed(asDeclaration()); inh Declaration Element.shadowed(Declaration shadower); eq Scope.getElement().shadowed(Declaration shadower) = shadowedLocally(shadower); @@ -16,7 +16,7 @@ aspect Shadowing { return declaration; } } - // the look in the inherited scopes + // then look in the inherited scopes for (Scope inherited : getInheritedScopeList()) { Declaration shadowed = inherited.shadowedLocally(shadower); if (shadowed != null) { diff --git a/scope4j/build.gradle b/scope4j/build.gradle index cf6e3a0f0aec486203016ec437c1894f108d2572..dc2f6007ba8f036ff07eafe6c2a6d3a9f922075e 100644 --- a/scope4j/build.gradle +++ b/scope4j/build.gradle @@ -40,11 +40,17 @@ sourceSets.main { } } +configurations { + ragdoc +} + dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2' testCompile 'org.junit.platform:junit-platform-runner:1.4.2' testImplementation 'org.junit.jupiter:junit-jupiter-params:5.4.2' + + ragdoc files('../tools/rd-builder.jar') } jastadd { @@ -133,10 +139,7 @@ jastadd { } run { - mainClassName = 'org.extendj.SccChecker' - if (project.hasProperty("appArgs")) { - args Eval.me(appArgs) - } + mainClassName = 'org.extendj.ScopeAnalysis' } task preprocess(type: JavaExec) { @@ -216,7 +219,7 @@ generateAst.dependsOn preprocess mainClassName = 'org.extendj.ScopeAnalysis' jar.manifest.attributes 'Main-Class': mainClassName -jar.destinationDir = projectDir +jar.destinationDirectory = projectDir sourceCompatibility = '1.8' targetCompatibility = '1.8' diff --git a/scope4j/src/main/jastadd/ASTPrinting.jadd b/scope4j/src/main/jastadd/ASTPrinting.jadd index 08641440a1247fff135e07dae2318c441a445636..b12a7fd0466d822f8ec8695b51de5681198194db 100644 --- a/scope4j/src/main/jastadd/ASTPrinting.jadd +++ b/scope4j/src/main/jastadd/ASTPrinting.jadd @@ -2,7 +2,7 @@ aspect Debugging { public String ASTNode.getASTString() { - String result = this.getClass().getSimpleName() + "\n"; + String result = this.getClass().getSimpleName() + " (@" + this.hashCode() + ")\n"; for (java.lang.reflect.Method method : this.getClass().getMethods()) { ASTNodeAnnotation.Token annotation = method.getAnnotation(ASTNodeAnnotation.Token.class); @@ -14,7 +14,8 @@ aspect Debugging { } else { name += ":= "; } - result += "|--" + name + method.invoke(this); + Object methodResult = method.invoke(this); + result += "|--" + name + methodResult + (methodResult == null ? "" : " (@" + methodResult.hashCode() + ")"); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (java.lang.reflect.InvocationTargetException e) { diff --git a/scope4j/src/main/jastadd/ProgramToScopeTree.jrag b/scope4j/src/main/jastadd/ProgramToScopeTree.jrag index 05b0ea10e0ac4f9eecbb2eff28c7c26ad21cbbb4..1cb2b14fde8f4f4be10541edeb188021c704fd32 100644 --- a/scope4j/src/main/jastadd/ProgramToScopeTree.jrag +++ b/scope4j/src/main/jastadd/ProgramToScopeTree.jrag @@ -27,8 +27,13 @@ aspect ProgramToScopeTree { public void ProtectedClassDeclScope.updateInheritance() { if (getTypeDecl().isClassDecl()) { ClassDecl classDecl = (ClassDecl)getTypeDecl(); - if(classDecl.superclass().isClassDecl() && classDecl.superclass().compilationUnit().fromSource()) { - addInheritedScope(((ClassDecl)classDecl.superclass()).asPackageScope()); + if (classDecl.superclass().isClassDecl() && classDecl.superclass().compilationUnit().fromSource()) { + ClassDecl superDecl = (ClassDecl)classDecl.superclass(); + if (classDecl.hostPackage().equals(superDecl.hostPackage())) { + addInheritedScope(superDecl.asPackageScope()); + } else { + addInheritedScope(superDecl.asProtectedScope()); + } } } super.updateInheritance(); diff --git a/scope4j/src/main/java/org/extendj/ScopeAnalysis.java b/scope4j/src/main/java/org/extendj/ScopeAnalysis.java index c6802fa0af437d36c7e77341d28f5ed219fa67c6..603bb69259676a78383c9746395d35aa55d239cf 100644 --- a/scope4j/src/main/java/org/extendj/ScopeAnalysis.java +++ b/scope4j/src/main/java/org/extendj/ScopeAnalysis.java @@ -17,6 +17,8 @@ public class ScopeAnalysis extends Frontend { super("Java Scope Anaysis", ExtendJVersion.getVersion()); } + @SuppressWarnings("WeakerAccess") + public static Object DrAST_root_node; public Program getProgram() { return program; @@ -24,6 +26,8 @@ public class ScopeAnalysis extends Frontend { private Program program; + private static boolean isDrAst = false; + /** * Entry point for the Java checker. * @@ -36,9 +40,11 @@ public class ScopeAnalysis extends Frontend { boolean debug = arguments.isEmpty() || arguments.remove("--debug"); boolean tree = arguments.remove("--tree"); boolean warnings = arguments.remove("--warnings"); + isDrAst = arguments.remove("--drast"); if (arguments.size() > 1) { System.out.println("usage: ScopeAnalysis [--debug] [--tree] [--warnings] <directory with java files>"); + System.out.println(arguments); System.exit(-1); } String path = arguments.isEmpty() ? "../testprograms/simpleScope" : arguments.get(arguments.size() - 1); @@ -52,6 +58,11 @@ public class ScopeAnalysis extends Frontend { } public void analyzeTimed(String path) { + if (isDrAst) { + // quick-fix for DrAst, use directory of given file + path = Paths.get(path).getParent().toFile().getPath(); + } + try { List<String> files = Files.walk(Paths.get(path)) .filter(Files::isRegularFile) @@ -66,6 +77,7 @@ public class ScopeAnalysis extends Frontend { long startGenerationTime = System.nanoTime(); ScopeTree scopeTree = program.scopeTree(); + DrAST_root_node = scopeTree; long startAnalysisTime = System.nanoTime(); diff --git a/settings.gradle b/settings.gradle index 5dc7447e44465492250bf58c555fdde33b16d6a3..3b6fb9063340d94a7336c03aaea5d4a90cba2297 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,3 +23,5 @@ include 'extendj:java5' include 'extendj:java6' include 'extendj:java7' include 'extendj:java8' +include 'drast' + diff --git a/tools/DrAST-1.2.2.jar b/tools/DrAST-1.2.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..399bbeb6c19fd40e3b411d1527a8f5e98d4ed1be Binary files /dev/null and b/tools/DrAST-1.2.2.jar differ