diff --git a/scope4j/src/main/jastadd/ProgramToScopeTree.jrag b/scope4j/src/main/jastadd/ProgramToScopeTree.jrag index 20955beb656d2e069117ebe68a13a1522aa5c377..6bd575cb2424d020b5ad12ce170e64eca288d3f6 100644 --- a/scope4j/src/main/jastadd/ProgramToScopeTree.jrag +++ b/scope4j/src/main/jastadd/ProgramToScopeTree.jrag @@ -83,8 +83,8 @@ aspect ScopeTreeConstructors { return scope; } - syn lazy JavaDeclaration Declarator.asDeclaration() { - JavaDeclaration decl = new JavaDeclaration(getID()); + syn lazy SimpleJavaDeclaration Declarator.asDeclaration() { + SimpleJavaDeclaration decl = new SimpleJavaDeclaration(getID()); decl.setDeclarator(this); return decl; } diff --git a/scope4j/src/main/jastadd/ProgramToScopeTree.relast b/scope4j/src/main/jastadd/ProgramToScopeTree.relast index a1d84e0153fe227e592e61c3a456e9553462c79e..ef201525f26bee91ac385a13f75ff7e9ff1abe56 100644 --- a/scope4j/src/main/jastadd/ProgramToScopeTree.relast +++ b/scope4j/src/main/jastadd/ProgramToScopeTree.relast @@ -1,23 +1,25 @@ // glue relation for the Java-based variable shadowing analysis rel ScopeTree.Program -> Program; -TypeDeclScope : Scope; +abstract JavaScope : Scope; +TypeDeclScope : JavaScope; rel TypeDeclScope.typeDecl -> TypeDecl; -BlockScope : Scope; +BlockScope : JavaScope; rel BlockScope.block -> Block; -ForStmtScope : Scope; +ForStmtScope : JavaScope; rel ForStmtScope.forStmt -> ForStmt; -EnhancedForStmtScope : Scope; +EnhancedForStmtScope : JavaScope; rel EnhancedForStmtScope.enhancedForStmt -> EnhancedForStmt; -JavaDeclaration : Declaration; -rel JavaDeclaration.declarator -> Declarator; +abstract JavaDeclaration : Declaration ; +SimpleJavaDeclaration : JavaDeclaration; +rel SimpleJavaDeclaration.declarator -> Declarator; -JavaParameterDeclaration : Declaration; +JavaParameterDeclaration : JavaDeclaration; rel JavaParameterDeclaration.parameterDeclaration -> ParameterDeclaration; -JavaInferredLambdaParameterDeclaration : Declaration; +JavaInferredLambdaParameterDeclaration : JavaDeclaration; rel JavaInferredLambdaParameterDeclaration.inferredParameterDeclaration -> InferredParameterDeclaration; diff --git a/scope4j/src/main/jastadd/Shadow.jadd b/scope4j/src/main/jastadd/Shadow.jadd index 644a178f4dba9057f6ab1617f8360e82b6f8f493..0caf2f5f46964f4fa319576dbe5c50e2ca074fe3 100644 --- a/scope4j/src/main/jastadd/Shadow.jadd +++ b/scope4j/src/main/jastadd/Shadow.jadd @@ -1,55 +1,37 @@ aspect Shadow{ + // --- toString --- eq TypeDeclScope.toString() = getTypeDecl().getClass().getSimpleName() + "-Scope"; eq BlockScope.toString() = getBlock().getClass().getSimpleName() + "-Scope"; eq ForStmtScope.toString() = getForStmt().getClass().getSimpleName() + "-Scope"; eq EnhancedForStmtScope.toString() = getEnhancedForStmt().getClass().getSimpleName() + "-Scope"; - eq JavaDeclaration.toString() = getDeclarator().getClass().getSimpleName() + ":" + super.toString(); + eq SimpleJavaDeclaration.toString() = getDeclarator().getClass().getSimpleName() + ":" + super.toString(); eq JavaParameterDeclaration.toString() = getParameterDeclaration().getClass().getSimpleName() + ":" + super.toString(); eq JavaInferredLambdaParameterDeclaration.toString() = getInferredParameterDeclaration().getClass().getSimpleName() + ":" + super.toString(); - public int TypeDeclScope.lineNumber(){ - return getTypeDecl().lineNumber(); - } - public int BlockScope.lineNumber(){ - return getBlock().lineNumber(); - } - public int ForStmtScope.lineNumber(){ - return getForStmt().lineNumber(); - } - public int EnhancedForStmtScope.lineNumber(){ - return getEnhancedForStmt().lineNumber(); - } - public int JavaDeclaration.lineNumber() { - return getDeclarator().lineNumber(); - } - public int JavaParameterDeclaration.lineNumber() { - return getParameterDeclaration().lineNumber(); - } - public int JavaInferredLambdaParameterDeclaration.lineNumber() { - return getInferredParameterDeclaration().lineNumber(); - } + // --- lineNumber --- + syn int JavaScope.lineNumber(); + eq TypeDeclScope.lineNumber() = getTypeDecl().lineNumber(); + eq BlockScope.lineNumber() = getBlock().lineNumber(); + eq ForStmtScope.lineNumber() = getForStmt().lineNumber(); + eq EnhancedForStmtScope.lineNumber() = getEnhancedForStmt().lineNumber(); + syn int JavaDeclaration.lineNumber(); + eq SimpleJavaDeclaration.lineNumber() = getDeclarator().lineNumber(); + eq JavaParameterDeclaration.lineNumber() = getParameterDeclaration().lineNumber(); + eq JavaInferredLambdaParameterDeclaration.lineNumber() = getInferredParameterDeclaration().lineNumber(); - public String TypeDeclScope.sourceFile() { - return getTypeDecl().sourceFile(); - } - public String BlockScope.sourceFile() { - return getBlock().sourceFile(); - } - public String ForStmtScope.sourceFile() { - return getForStmt().sourceFile(); - } - public String EnhancedForStmtScope.sourceFile() { - return getEnhancedForStmt().sourceFile(); - } - public String JavaDeclaration.sourceFile() { - return getDeclarator().sourceFile(); - } - public String JavaParameterDeclaration.sourceFile() { - return getParameterDeclaration().sourceFile(); - } - public String JavaInferredLambdaParameterDeclaration.sourceFile() { - return getInferredParameterDeclaration().sourceFile(); - } + // --- sourceFile --- + syn String JavaScope.sourceFile(); + eq TypeDeclScope.sourceFile() = getTypeDecl().sourceFile(); + eq BlockScope.sourceFile() = getBlock().sourceFile(); + eq ForStmtScope.sourceFile() = getForStmt().sourceFile(); + eq EnhancedForStmtScope.sourceFile() = getEnhancedForStmt().sourceFile(); + syn String JavaDeclaration.sourceFile(); + eq SimpleJavaDeclaration.sourceFile() = getDeclarator().sourceFile(); + eq JavaParameterDeclaration.sourceFile() = getParameterDeclaration().sourceFile(); + eq JavaInferredLambdaParameterDeclaration.sourceFile() = getInferredParameterDeclaration().sourceFile(); + // --- asJavaDeclaration --- + syn JavaDeclaration Declaration.asJavaDeclaration() = null; + eq JavaDeclaration.asJavaDeclaration() = this; } diff --git a/scope4j/src/test/java/org/extendj/ScopeAnalysisTest.java b/scope4j/src/test/java/org/extendj/ScopeAnalysisTest.java index 95d479ce7b90b3d7deb7684ea36c07c3dba1777a..32936e35476af347224087c70d4ec66e07ca0090 100644 --- a/scope4j/src/test/java/org/extendj/ScopeAnalysisTest.java +++ b/scope4j/src/test/java/org/extendj/ScopeAnalysisTest.java @@ -1,25 +1,46 @@ package org.extendj; -import org.extendj.ast.AbstractFinding; -import org.extendj.ast.Declaration; -import org.extendj.ast.MultipleDeclarationFinding; -import org.extendj.ast.VariableShadowFinding; +import org.extendj.ast.*; import org.junit.jupiter.api.Assertions; import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Supplier; public abstract class ScopeAnalysisTest { - static void assertShadow(Set<AbstractFinding> findings, String name, int shadowerLine, int shadowedLine) { + private static void assertShadow(Set<AbstractFinding> findings, + BiFunction<JavaDeclaration, JavaDeclaration, Boolean> test, + Supplier<String> failMessage) { for (AbstractFinding finding : findings) { if (finding instanceof VariableShadowFinding) { - Declaration shadower = ((VariableShadowFinding)finding).getShadower(); - Declaration shadowed = ((VariableShadowFinding)finding).getShadowed(); - if (shadowed.getName().equals(name) && shadowed.lineNumber() == shadowedLine && shadower.lineNumber() == shadowerLine) { + JavaDeclaration shadower = ((VariableShadowFinding)finding).getShadower().asJavaDeclaration(); + JavaDeclaration shadowed = ((VariableShadowFinding)finding).getShadowed().asJavaDeclaration(); + if (test.apply(shadower, shadowed)) { return; } } } - Assertions.fail("No shadow finding found for name '" + name + "' in lines " + shadowerLine + " > " + shadowedLine); + Assertions.fail(failMessage.get()); + } + + static void assertShadow(Set<AbstractFinding> findings, String name, int shadowerLine, int shadowedLine) { + assertShadow(findings, + (shadower, shadowed) -> + shadowed.getName().equals(name) && + shadowed.lineNumber() == shadowedLine && + shadower.lineNumber() == shadowerLine, + () -> "No shadow finding found for name '" + name + "' in lines " + shadowerLine + " > " + shadowedLine); + } + + static void assertShadow(Set<AbstractFinding> findings, String name, String shadowerSourceFile, int shadowerLine, String shadowedSourceFile, int shadowedLine) { + assertShadow(findings, + (shadower, shadowed) -> + shadowed.getName().equals(name) && + shadowed.sourceFile().equals(shadowedSourceFile) && + shadowed.lineNumber() == shadowedLine && + shadower.sourceFile().equals(shadowerSourceFile) && + shadower.lineNumber() == shadowerLine, + () -> "No shadow finding found for name '" + name + "' in " +shadowerSourceFile + ":" + shadowerLine + " > " + shadowedSourceFile + ":" + shadowedLine); } static void assertRedefinition(Set<AbstractFinding> findings, String name, int declLine) { @@ -33,4 +54,22 @@ public abstract class ScopeAnalysisTest { } Assertions.fail("No multi-decl finding found for name '" + name + "' in line " + declLine); } + + static void assertNotShadow(Set<AbstractFinding> findings, String name, int shadowerLine, int shadowedLine) { + try { + assertShadow(findings, name, shadowerLine, shadowedLine); + } catch (AssertionError e) { + return; + } + Assertions.fail("There should not be a shadow finding for name '" + name + "' in lines " + shadowerLine + " > " + shadowedLine); + } + + static void assertNotShadow(Set<AbstractFinding> findings, String name, String shadowerSourceFile, int shadowerLine, String shadowedSourceFile, int shadowedLine) { + try { + assertShadow(findings, name, shadowerLine, shadowedLine); + } catch (AssertionError e) { + return; + } + Assertions.fail("There should not be a shadow finding for name '" + name + "' in " + shadowerSourceFile + ":" + shadowerLine + " > " + shadowedSourceFile + ":" + shadowedLine); + } }