Skip to content

Commit d49c2be

Browse files
committed
SONARJAVA-1296 Workaround for constructors references in SonarSymbolTableVisitor
1 parent bf1c9a7 commit d49c2be

3 files changed

Lines changed: 50 additions & 16 deletions

File tree

java-squid/src/main/java/org/sonar/java/ast/visitors/SonarSymbolTableVisitor.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
*/
2020
package org.sonar.java.ast.visitors;
2121

22+
import com.google.common.base.Predicate;
23+
import com.google.common.collect.Iterables;
2224
import com.google.common.collect.Lists;
2325
import org.sonar.api.source.Symbol;
2426
import org.sonar.api.source.Symbolizable;
@@ -38,6 +40,7 @@
3840
import org.sonar.plugins.java.api.tree.TypeParameterTree;
3941
import org.sonar.plugins.java.api.tree.VariableTree;
4042

43+
import java.util.ArrayList;
4144
import java.util.List;
4245

4346
public class SonarSymbolTableVisitor extends BaseTreeVisitor {
@@ -91,11 +94,20 @@ public void visitEnumConstant(EnumConstantTree tree) {
9194

9295
@Override
9396
public void visitMethod(MethodTree tree) {
94-
//as long as SONAR-5894 is not fixed, do not provide references to enum constructors
95-
if(tree.symbol().returnType() == null && tree.symbol().owner().isEnum()) {
96-
createSymbol(tree.simpleName(), Lists.<IdentifierTree>newArrayList());
97+
List<IdentifierTree> usages = tree.symbol().usages();
98+
if (tree.symbol().returnType() == null) {
99+
if (tree.symbol().owner().isEnum()) {
100+
// as long as SONAR-5894 is not fixed, do not provide references to enum constructors
101+
createSymbol(tree.simpleName(), Lists.<IdentifierTree>newArrayList());
102+
} else {
103+
// as long as SONAR-5894 is not fixed, only provides references to constructors using direct call (with same name), and consequently
104+
// discard usages of this()/super()
105+
String constructorName = tree.simpleName().name();
106+
ArrayList<IdentifierTree> filteredUsages = Lists.newArrayList(Iterables.filter(usages, new SameNameFilter(constructorName)));
107+
createSymbol(tree.simpleName(), filteredUsages);
108+
}
97109
} else {
98-
createSymbol(tree.simpleName(), tree.symbol().usages());
110+
createSymbol(tree.simpleName(), usages);
99111
}
100112
super.visitMethod(tree);
101113
}
@@ -144,4 +156,19 @@ private static int endOffsetFor(IdentifierTree tree) {
144156
return ((InternalSyntaxToken) tree.identifierToken()).fromIndex() + tree.identifierToken().text().length();
145157
}
146158

159+
private static class SameNameFilter implements Predicate<IdentifierTree> {
160+
161+
private final String constructorName;
162+
163+
public SameNameFilter(String constructorName) {
164+
this.constructorName = constructorName;
165+
}
166+
167+
@Override
168+
public boolean apply(IdentifierTree input) {
169+
return constructorName.equals(input.name());
170+
}
171+
172+
}
173+
147174
}

java-squid/src/test/files/highlighter/SonarSymTable.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
class Example<T> {
55
List<String> list;
6+
Example() {
7+
this(null);
8+
}
69
Example(List<String> list) {
710
this.list = list;
811
}

java-squid/src/test/java/org/sonar/java/ast/visitors/SonarSymbolTableVisitorTest.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
import org.junit.Test;
2727
import org.sonar.api.source.Symbol;
2828
import org.sonar.api.source.Symbolizable;
29-
import org.sonar.java.ast.JavaAstScanner;
3029
import org.sonar.java.SonarComponents;
30+
import org.sonar.java.ast.JavaAstScanner;
3131
import org.sonar.java.model.VisitorsBridge;
3232

3333
import java.io.File;
@@ -64,28 +64,32 @@ public void sonar_symbol_table() throws Exception {
6464
// import List
6565
verify(symboltableBuilder).newSymbol(offset(1, 18), offset(1, 22));
6666
verify(symboltableBuilder).newReference(any(Symbol.class), eq(offset(5, 3)));
67-
verify(symboltableBuilder).newReference(any(Symbol.class), eq(offset(6, 11)));
67+
verify(symboltableBuilder).newReference(any(Symbol.class), eq(offset(9, 11)));
6868
// Example class declaration
6969
verify(symboltableBuilder).newSymbol(offset(4, 7), offset(4, 14));
7070
verify(symboltableBuilder).newSymbol(offset(4, 15), offset(4, 16));
7171
// list field
7272
verify(symboltableBuilder).newSymbol(offset(5, 16), offset(5, 20));
73-
verify(symboltableBuilder).newReference(any(Symbol.class), eq(offset(7, 10)));
74-
// Example constructor
73+
verify(symboltableBuilder).newReference(any(Symbol.class), eq(offset(10, 10)));
74+
// Example empty constructor
7575
verify(symboltableBuilder).newSymbol(offset(6, 3), offset(6, 10));
76+
// Do not reference constructor of class using this() and super() as long as SONAR-5894 is not fixed
77+
//verify(symboltableBuilder).newReference(any(Symbol.class), eq(offset(7, 5)));
78+
// Example list constructor
79+
verify(symboltableBuilder).newSymbol(offset(9, 3), offset(9, 10));
7680
// list local var
77-
verify(symboltableBuilder).newSymbol(offset(6, 24), offset(6, 28));
78-
verify(symboltableBuilder).newReference(any(Symbol.class), eq(offset(7, 17)));
81+
verify(symboltableBuilder).newSymbol(offset(9, 24), offset(9, 28));
82+
verify(symboltableBuilder).newReference(any(Symbol.class), eq(offset(10, 17)));
7983
// method
80-
verify(symboltableBuilder).newSymbol(offset(9, 7), offset(9, 13));
84+
verify(symboltableBuilder).newSymbol(offset(12, 7), offset(12, 13));
8185
//label
82-
verify(symboltableBuilder).newSymbol(offset(10, 5), offset(10, 10));
86+
verify(symboltableBuilder).newSymbol(offset(13, 5), offset(13, 10));
8387
//Enum
84-
verify(symboltableBuilder).newSymbol(offset(13, 8), offset(13, 26));
85-
verify(symboltableBuilder).newSymbol(offset(14, 5), offset(14, 12));
86-
//Do not reference constructor of enum as it can leads to failure in analysis as long as SONAR-5894 is not fixed
88+
verify(symboltableBuilder).newSymbol(offset(16, 8), offset(16, 26));
89+
verify(symboltableBuilder).newSymbol(offset(17, 5), offset(17, 12));
90+
// Do not reference constructor of enum as it can leads to failure in analysis as long as SONAR-5894 is not fixed
8791
//verify(symboltableBuilder).newReference(any(Symbol.class), eq(offset(14, 5)));
88-
verify(symboltableBuilder).newSymbol(offset(15, 5), offset(15, 23));
92+
verify(symboltableBuilder).newSymbol(offset(18, 5), offset(18, 23));
8993
verify(symboltableBuilder).build();
9094
verifyNoMoreInteractions(symboltableBuilder);
9195
}

0 commit comments

Comments
 (0)