Hi,
PMD is throwing a RuntimeException
when it is parsing a class with multiple lambdas of the same type and with the same variable identifiers.
In the PMD source I've reproduced the issue that we encountered we have with sonar. The following test
package net.sourceforge.pmd.lang.java.bugs;
import org.junit.Test;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.lang.java.symboltable.STBBaseTst;
public class Java8MultipleLambdasTest extends STBBaseTst {
private static final String MULTIPLE_JAVA_8_LAMBDAS =
"public class MultipleLambdas {" + PMD.EOL +
" Observer a = (o, arg) -> System.out.println("a:" + arg);" + PMD.EOL +
" Observer b = (o, arg) -> System.out.println("b:" + arg);" + PMD.EOL +
"}";
@Test
public void should_not_fail() {
parseCode(MULTIPLE_JAVA_8_LAMBDAS);
}
}
fails with the following stacktrace
java.lang.RuntimeException: Variable: image = 'o', line = 3 is already in the symbol table
at net.sourceforge.pmd.lang.java.symboltable.AbstractJavaScope.checkForDuplicatedNameDeclaration(AbstractJavaScope.java:27)
at net.sourceforge.pmd.lang.java.symboltable.AbstractJavaScope.addDeclaration(AbstractJavaScope.java:21)
at net.sourceforge.pmd.lang.java.symboltable.ScopeAndDeclarationFinder.visit(ScopeAndDeclarationFinder.java:294)
at net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId.jjtAccept(ASTVariableDeclaratorId.java:30)
at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.childrenAccept(AbstractJavaNode.java:55)
at net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter.visit(JavaParserVisitorAdapter.java:9)
at net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter.visit(JavaParserVisitorAdapter.java:455)
at net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression.jjtAccept(ASTLambdaExpression.java:21)
at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.childrenAccept(AbstractJavaNode.java:55)
at net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter.visit(JavaParserVisitorAdapter.java:9)
at net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter.visit(JavaParserVisitorAdapter.java:312)
at net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix.jjtAccept(ASTPrimaryPrefix.java:40)
at net.sourceforge.pmd.lang.java.ast.AbstractJavaNode.childrenAccept(AbstractJavaNode.java:55)
at net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter.visit(JavaParserVisitorAdapter.java:9)
at net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter.visit(JavaParserVisitorAdapter.java:308)
at net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression.jjtAccept(ASTPrimaryExpression.java:22)
truncated for the issue
I'm not able to propose a fix, but from what I've seen while debugging is that while the visitor visit the lambda it has the scope of the class (in this case MultipleLambdas
). So at failure point the declarations
map contains :
Variable: image = 'a', line = 2=[]
Variable: image = 'o', line = 2=[]
Variable: image = 'arg', line = 2=[]
Variable: image = 'b', line = 3=[]
Not sure what are the implications of having a new LambdaScope, but it somehow makes sense.
Maybe the
equals
/hashcode
methods ofVariableNameDeclaration
can be changed... But that feels like a dirty quickfix hides the real issue.Will be fixed with the next version.
I've created for LamdaExpressions a new LocalScope - so that two LamdaExpressions don't interfere.
OK cool, thanks