diff --git a/scope4j/src/main/jastadd/ProgramToScopeTree.jrag b/scope4j/src/main/jastadd/ProgramToScopeTree.jrag index 26f0fba4b17bef875c774f95a7cc4e201d703da3..b1dc8e2586d5d76cbcfe93de04f5ecc821a2fe47 100644 --- a/scope4j/src/main/jastadd/ProgramToScopeTree.jrag +++ b/scope4j/src/main/jastadd/ProgramToScopeTree.jrag @@ -35,6 +35,12 @@ aspect ProgramToScopeTree { addInheritedScope(superDecl.asProtectedScope()); } } + for (InterfaceDecl interfaceDecl : classDecl.implementedInterfaces()) { + System.out.println(classDecl.implementedInterfaces()); + if (interfaceDecl.compilationUnit().fromSource()) { + addInheritedScope(interfaceDecl.asPackageScope()); + } + } } super.updateInheritance(); } @@ -53,11 +59,11 @@ aspect ProgramToScopeTree { EnhancedForStmt contributes scope() when !(getStmt() instanceof Block) to ASTNode.scope() for containingScope(); // collect all elements - Declarator contributes asDeclaration() when /* is NOT in interface || */ !isField() || isPrivate() to ASTNode.scope() for containingScope(); + Declarator contributes asDeclaration() when !inInterface() && (!isField() || isPrivate()) to ASTNode.scope() for containingScope(); // field which is neither private, protected, nor public -> package-private scope Declarator contributes asDeclaration() when isField() && !isPrivate() && !(isProtected() || isPublic()) to TypeDecl.packageScope() for containingScope(); // field which is either protected or public -> protected scope - Declarator contributes asDeclaration() when /* is in interface && */ isField() && !isPrivate() && (isProtected() || isPublic()) to TypeDecl.protectedScope() for containingScope(); + Declarator contributes asDeclaration() when isField() && !isPrivate() && (isProtected() || isPublic() || inInterface()) to TypeDecl.protectedScope() for containingScope(); ParameterDeclaration contributes asDeclaration() to ASTNode.scope() for containingScope(); } @@ -156,4 +162,8 @@ aspect ScopeGenerationAttributes { // allow host package to be called from all AST nodes inh String ASTNode.hostPackage(); eq Program.getCompilationUnit(int i).hostPackage() = getCompilationUnit(i).getPackageDecl(); + + inh boolean Declarator.inInterface(); + eq TypeDecl.getChild().inInterface() = false; + eq InterfaceDecl.getChild().inInterface() = true; } diff --git a/scope4j/src/test/java/org/extendj/InterfaceTest.java b/scope4j/src/test/java/org/extendj/InterfaceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..070ac2e23dfc1e73ed4236a0a00894702fdd7f14 --- /dev/null +++ b/scope4j/src/test/java/org/extendj/InterfaceTest.java @@ -0,0 +1,30 @@ +package org.extendj; + +import org.extendj.ast.AbstractFinding; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Set; + +public class InterfaceTest extends ScopeAnalysisTest { + + @Test + void test() { + + + final String classA = "src/test/resources/interface/ClassA.java"; + final String interfaceA = "src/test/resources/interface/InterfaceA.java"; + final String interfaceB = "src/test/resources/interface/InterfaceB.java"; + final String interfaceAorB = "src/test/resources/interface/Interface"; + + ScopeAnalysis scopeAnalysis = new ScopeAnalysis(); + Set<AbstractFinding> findings = scopeAnalysis.analyze("src/test/resources/interface", true, true); + + assertShadow(findings, "fieldA", classA, 2, interfaceA, 2); + assertShadow(findings, "fieldB", classA, 3, interfaceB, 3); + assertShadow(findings, "fieldC", classA, 4, interfaceAorB, 4); + + Assertions.assertEquals(3, findings.size()); + } + +} diff --git a/scope4j/src/test/resources/interface/ClassA.java b/scope4j/src/test/resources/interface/ClassA.java new file mode 100644 index 0000000000000000000000000000000000000000..0a91b8a4f8beb6d3e8ce466ea23260434ed5d69a --- /dev/null +++ b/scope4j/src/test/resources/interface/ClassA.java @@ -0,0 +1,5 @@ +public class ClassA implements InterfaceA { + int fieldA = 1; + int fieldB = 1; + int fieldC = 1; +} diff --git a/scope4j/src/test/resources/interface/InterfaceA.java b/scope4j/src/test/resources/interface/InterfaceA.java new file mode 100644 index 0000000000000000000000000000000000000000..481e0e6b1a1c5748284d0bbf5b18831c02dd4deb --- /dev/null +++ b/scope4j/src/test/resources/interface/InterfaceA.java @@ -0,0 +1,5 @@ +public interface InterfaceA extends InterfaceB { + int fieldA = 1; + + int fieldC = 1; +} diff --git a/scope4j/src/test/resources/interface/InterfaceB.java b/scope4j/src/test/resources/interface/InterfaceB.java new file mode 100644 index 0000000000000000000000000000000000000000..ca9fb459c40eba519ccb651a087d80cdf64d64dc --- /dev/null +++ b/scope4j/src/test/resources/interface/InterfaceB.java @@ -0,0 +1,5 @@ +public interface InterfaceB { + + int fieldB = 2; + int fieldC = 2; +}