Skip to content
Snippets Groups Projects
Commit 5c9d40c3 authored by René Schöne's avatar René Schöne
Browse files

Added test and analysis for protected.

- reintroduce some parts of 24a4d16b
- this currently fails for package-private members, which are treated as if protected, thus reporting too much shadowings
parent f82bbf76
Branches
Tags
No related merge requests found
...@@ -9,6 +9,7 @@ aspect ProgramToScopeTree { ...@@ -9,6 +9,7 @@ aspect ProgramToScopeTree {
/** a relational nta collection attribute to compute a special scope containing visible fields and subtypes */ /** a relational nta collection attribute to compute a special scope containing visible fields and subtypes */
coll TypeDeclScope ClassDecl.protectedScope() [asProtectedScope()] with addElement root Program; coll TypeDeclScope ClassDecl.protectedScope() [asProtectedScope()] with addElement root Program;
coll TypeDeclScope ClassDecl.packageScope() [asPackageScope()] with addElement root Program;
// collect all scopes // collect all scopes
TypeDecl contributes scope() when !isClassDecl() to ASTNode.scope() for containingScope(); TypeDecl contributes scope() when !isClassDecl() to ASTNode.scope() for containingScope();
...@@ -17,16 +18,23 @@ aspect ProgramToScopeTree { ...@@ -17,16 +18,23 @@ aspect ProgramToScopeTree {
to ASTNode.scope() to ASTNode.scope()
for containingScope(); for containingScope();
ClassDecl contributes protectedScope() ClassDecl contributes protectedScope()
when !isInnerClass() && superclass().isClassDecl() && superclass().compilationUnit().fromSource() when !isInnerClass() && superclass().isClassDecl() && superclass().compilationUnit().fromSource() && !accessibleFromPackage(superclass().hostPackage())
to ClassDecl.protectedScope() to ClassDecl.protectedScope()
for superclass(); for superclass();
ClassDecl contributes protectedScope()
when !isInnerClass() && superclass().isClassDecl() && superclass().compilationUnit().fromSource() && accessibleFromPackage(superclass().hostPackage())
to ClassDecl.packageScope()
for superclass();
Block contributes scope() to ASTNode.scope() for containingScope(); Block contributes scope() to ASTNode.scope() for containingScope();
ForStmt contributes scope() when !(getStmt() instanceof Block) to ASTNode.scope() for containingScope(); ForStmt contributes scope() when !(getStmt() instanceof Block) to ASTNode.scope() for containingScope();
EnhancedForStmt contributes scope() when !(getStmt() instanceof Block) to ASTNode.scope() for containingScope(); EnhancedForStmt contributes scope() when !(getStmt() instanceof Block) to ASTNode.scope() for containingScope();
// collect all elements // collect all elements
Declarator contributes asDeclaration() when !isField() || isPrivate() to ASTNode.scope() for containingScope(); Declarator contributes asDeclaration() when !isField() || isPrivate() to ASTNode.scope() for containingScope();
Declarator contributes asDeclaration() when isField() && !isPrivate() to ClassDecl.protectedScope() for containingScope(); // field which is neither private, protected, nor public -> package-private scope
Declarator contributes asDeclaration() when isField() && !isPrivate() && !(isProtected() || isPublic()) to ClassDecl.packageScope() for containingScope();
// field which is either protected or public -> protected scope
Declarator contributes asDeclaration() when isField() && !isPrivate() && (isProtected() || isPublic()) to ClassDecl.protectedScope() for containingScope();
ParameterDeclaration contributes asDeclaration() to ASTNode.scope() for containingScope(); ParameterDeclaration contributes asDeclaration() to ASTNode.scope() for containingScope();
} }
...@@ -57,7 +65,7 @@ aspect ScopeTreeConstructors { ...@@ -57,7 +65,7 @@ aspect ScopeTreeConstructors {
syn lazy TypeDeclScope ClassDecl.asProtectedScope() { syn lazy TypeDeclScope ClassDecl.asProtectedScope() {
TypeDeclScope scope = new TypeDeclScope(); TypeDeclScope scope = new TypeDeclScope();
scope.setTypeDecl(this); scope.setTypeDecl(this);
scope.addElement(scope()); // this irregular statement is necessary because of either a bug or a limitation in JastAdd collections scope.addElement(packageScope()); // this irregular statement is necessary because of either a bug or a limitation in JastAdd collections
return scope; return scope;
} }
// the following commented statement unfortunately does not work, because during the contribution phase, the information // the following commented statement unfortunately does not work, because during the contribution phase, the information
...@@ -65,6 +73,13 @@ aspect ScopeTreeConstructors { ...@@ -65,6 +73,13 @@ aspect ScopeTreeConstructors {
// and JastAdd always wants to also add the contribution made in line 17ff to this target as well. // and JastAdd always wants to also add the contribution made in line 17ff to this target as well.
// ClassDecl contributes scope() to ClassDecl.protectedScope() for this; // ClassDecl contributes scope() to ClassDecl.protectedScope() for this;
syn lazy TypeDeclScope ClassDecl.asPackageScope() {
TypeDeclScope scope = new TypeDeclScope();
scope.setTypeDecl(this);
scope.addElement(scope());
return scope;
}
syn lazy BlockScope Block.asScope() { syn lazy BlockScope Block.asScope() {
BlockScope scope = new BlockScope(); BlockScope scope = new BlockScope();
scope.setBlock(this); scope.setBlock(this);
......
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 ProtectedTest extends ScopeAnalysisTest {
@Test
void test() {
ScopeAnalysis scopeAnalysis = new ScopeAnalysis();
Set<AbstractFinding> findings = scopeAnalysis.analyze("src/test/resources/protected_", true, true);
System.out.println(findings);
final String classA = "src/test/resources/protected_/one/ClassA.java";
final String classB = "src/test/resources/protected_/one/ClassB.java";
final String classC = "src/test/resources/protected_/one/ClassC.java";
final String classD = "src/test/resources/protected_/two/ClassD.java";
final String classE = "src/test/resources/protected_/two/ClassE.java";
// within class A
// A.A()
assertShadow(findings, "fPrivate", classA, 19, classA, 9);
assertShadow(findings, "fPackage", classA, 20, classA, 10);
assertShadow(findings, "fProtected", classA, 21, classA, 11);
assertShadow(findings, "fPublic", classA, 22, classA, 12);
// A.foo()
assertShadow(findings, "fPrivate", classA, 26, classA, 9);
assertShadow(findings, "fPackage", classA, 27, classA, 10);
assertShadow(findings, "fProtected", classA, 28, classA, 11);
assertShadow(findings, "fPublic", classA, 29, classA, 12);
// A.bar()
assertShadow(findings, "fPrivate", classA, 32, classA, 9);
assertShadow(findings, "fPackage", classA, 33, classA, 10);
assertShadow(findings, "fProtected", classA, 34, classA, 11);
assertShadow(findings, "fPublic", classA, 35, classA, 12);
// within class B
assertShadow(findings, "fPackage", classB, 14, classA, 10);
assertShadow(findings, "fProtected", classB, 15, classA, 11);
assertShadow(findings, "fPublic", classB, 16, classA, 12);
// B.B()
assertShadow(findings, "fPrivate", classB, 19, classB, 13);
assertShadow(findings, "fPackage", classB, 20, classB, 14);
assertShadow(findings, "fProtected", classB, 21, classB, 15);
assertShadow(findings, "fPublic", classB, 22, classB, 16);
// B.foo()
assertShadow(findings, "fPrivate", classB, 26, classB, 13);
assertShadow(findings, "fPackage", classB, 27, classB, 14);
assertShadow(findings, "fProtected", classB, 28, classB, 15);
assertShadow(findings, "fPublic", classB, 29, classB, 16);
// B.bar()
assertShadow(findings, "fPrivate", classB, 32, classB, 13);
assertShadow(findings, "fPackage", classB, 33, classB, 14);
assertShadow(findings, "fProtected", classB, 34, classB, 15);
assertShadow(findings, "fPublic", classB, 35, classB, 16);
// within class C
// C.C()
assertShadow(findings, "fPackage", classC, 20, classA, 10);
assertShadow(findings, "fProtected", classC, 21, classA, 11);
assertShadow(findings, "fPublic", classC, 22, classA, 12);
// C.foo()
assertShadow(findings, "fPackage", classC, 27, classA, 10);
assertShadow(findings, "fProtected", classC, 28, classA, 11);
assertShadow(findings, "fPublic", classC, 29, classA, 12);
// C.bar()
assertShadow(findings, "fPackage", classC, 33, classA, 10);
assertShadow(findings, "fProtected", classC, 34, classA, 11);
assertShadow(findings, "fPublic", classC, 35, classA, 12);
// within class D
assertNotShadow(findings, "fPackage", classD, 20, classA, 10);
assertShadow(findings, "fProtected", classD, 15, classA, 11);
assertShadow(findings, "fPublic", classD, 16, classA, 12);
// D.D()
assertShadow(findings, "fPrivate", classD, 19, classA, 13);
assertShadow(findings, "fPackage", classD, 20, classA, 14);
assertShadow(findings, "fProtected", classD, 21, classA, 15);
assertShadow(findings, "fPublic", classD, 22, classA, 16);
// D.foo()
assertShadow(findings, "fPrivate", classD, 26, classA, 13);
assertShadow(findings, "fPackage", classD, 27, classA, 14);
assertShadow(findings, "fProtected", classD, 28, classA, 15);
assertShadow(findings, "fPublic", classD, 29, classA, 16);
// D.bar()
assertShadow(findings, "fPrivate", classD, 32, classA, 13);
assertShadow(findings, "fPackage", classD, 33, classA, 14);
assertShadow(findings, "fProtected", classD, 34, classA, 15);
assertShadow(findings, "fPublic", classD, 35, classA, 16);
// within class E
// E.E()
assertNotShadow(findings, "fPackage", classE, 20, classA, 10);
assertShadow(findings, "fProtected", classE, 21, classA, 11);
assertShadow(findings, "fPublic", classE, 22, classA, 12);
// E.foo()
assertNotShadow(findings, "fPackage", classE, 27, classA, 10);
assertShadow(findings, "fProtected", classE, 28, classA, 11);
assertShadow(findings, "fPublic", classE, 29, classA, 12);
// E.bar()
assertNotShadow(findings, "fPackage", classE, 33, classA, 14);
assertShadow(findings, "fProtected", classE, 34, classA, 11);
assertShadow(findings, "fPublic", classE, 35, classA, 12);
Assertions.assertEquals(56, findings.size());
}
}
/*
As of https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html, an underscore shall be added to
avoid conflicts with Java keywords.
*/
package protected_.one;
public class ClassA {
private int fPrivate = 0;
int fPackage = 0;
protected int fProtected = 0;
public int fPublic = 0;
protected ClassA() {
int fPrivate = 1;
int fPackage = 1;
int fProtected = 1;
int fPublic = 1;
}
void foo() {
int fPrivate = 2;
int fPackage = 2;
int fProtected = 2;
int fPublic = 2;
}
void bar(int fPrivate,
int fPackage,
int fProtected,
int fPublic) {
// empty
}
}
/*
As of https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html, an underscore shall be added to
avoid conflicts with Java keywords.
*/
package protected_.one;
class ClassB extends ClassA {
private int fPrivate = 0;
int fPackage = 0;
protected int fProtected = 0;
public int fPublic = 0;
ClassB() {
int fPrivate = 1;
int fPackage = 1;
int fProtected = 1;
int fPublic = 1;
}
void foo() {
int fPrivate = 2;
int fPackage = 2;
int fProtected = 2;
int fPublic = 2;
}
void bar(int fPrivate,
int fPackage,
int fProtected,
int fPublic) {
// empty
}
}
/*
As of https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html, an underscore shall be added to
avoid conflicts with Java keywords.
*/
package protected_.one;
class ClassC extends ClassA {
ClassC() {
int fPrivate = 1;
int fPackage = 1;
int fProtected = 1;
int fPublic = 1;
}
void foo() {
int fPrivate = 2;
int fPackage = 2;
int fProtected = 2;
int fPublic = 2;
}
void bar(int fPrivate,
int fPackage,
int fProtected,
int fPublic) {
// empty
}
}
/*
As of https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html, an underscore shall be added to
avoid conflicts with Java keywords.
*/
package protected_.two;
import protected_.one.ClassA;
class ClassD extends ClassA {
int fPrivate = 0;
int fPackage = 0;
int fProtected = 0;
int fPublic = 0;
ClassD() {
int fPrivate = 1;
int fPackage = 1;
int fProtected = 1;
int fPublic = 1;
}
void foo() {
int fPrivate = 2;
int fPackage = 2;
int fProtected = 2;
int fPublic = 2;
}
void bar(int fPrivate,
int fPackage,
int fProtected,
int fPublic) {
// empty
}
}
/*
As of https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html, an underscore shall be added to
avoid conflicts with Java keywords.
*/
package protected_.two;
class ClassE extends protected_.one.ClassA {
ClassE() {
int fPrivate = 1;
int fPackage = 1;
int fProtected = 1;
int fPublic = 1;
}
void foo() {
int fPrivate = 2;
int fPackage = 2;
int fProtected = 2;
int fPublic = 2;
}
void bar(int fPrivate,
int fPackage,
int fProtected,
int fPublic) {
// empty
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment