From c74b43baf22b17fc3f248d665ad85bf5f8c6045b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 7 Mar 2015 21:12:04 +0100 Subject: [PATCH] #1317 RuntimeException when parsing class with multiple lambdas Removing Java8MultipleLambdasTest from java8 integration, as it can be tested with java < 8 in pmd-java --- .../pmd/lang/java/symboltable/LocalScope.java | 9 +--- .../ScopeAndDeclarationFinder.java | 8 +++ .../pmd/lang/java/symboltable/STBBaseTst.java | 4 +- .../ScopeAndDeclarationFinderTest.java | 44 ++++++++++++++++ .../java/bugs/Java8MultipleLambdasTest.java | 51 ------------------- src/site/markdown/overview/changelog.md | 1 + 6 files changed, 56 insertions(+), 61 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinderTest.java delete mode 100644 pmd-java8/src/test/java/net/sourceforge/pmd/lang/java/bugs/Java8MultipleLambdasTest.java diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/LocalScope.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/LocalScope.java index 656d18ffa8..42155ef146 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/LocalScope.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/LocalScope.java @@ -40,14 +40,7 @@ public class LocalScope extends AbstractJavaScope { throw new IllegalArgumentException("A LocalScope can contain only VariableNameDeclarations or ClassNameDeclarations. " + "Tried to add " + nameDecl.getClass() + "(" + nameDecl + ")"); } - if (nameDecl.getNode().jjtGetParent() instanceof ASTLambdaExpression - || nameDecl.getNode().jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTLambdaExpression) { - // don't add the variable declaration, but verify, that there is no other local variable declaration - // with the same name - this would be a compiler error - checkForDuplicatedNameDeclaration(nameDecl); - } else { - super.addDeclaration(nameDecl); - } + super.addDeclaration(nameDecl); } public NameDeclaration findVariableHere(JavaNameOccurrence occurrence) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinder.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinder.java index f57fe1212e..f9989e448b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinder.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinder.java @@ -20,6 +20,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTForStatement; import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator; import net.sourceforge.pmd.lang.java.ast.ASTPackageDeclaration; @@ -266,6 +267,13 @@ public class ScopeAndDeclarationFinder extends JavaParserVisitorAdapter { return data; } + @Override + public Object visit(ASTLambdaExpression node, Object data) { + createLocalScope(node); + cont(node); + return data; + } + @Override public Object visit(ASTTryStatement node, Object data) { createLocalScope(node); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/STBBaseTst.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/STBBaseTst.java index 8e2d348e6a..9b93c23138 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/STBBaseTst.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/STBBaseTst.java @@ -15,7 +15,7 @@ public abstract class STBBaseTst { protected SymbolFacade stb; protected void parseCode(String code) { - parseCode(code, LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.4")); + parseCode(code, LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getDefaultVersion()); } protected void parseCode15(String code) { @@ -23,7 +23,7 @@ public abstract class STBBaseTst { } protected void parseCode(String code, LanguageVersion languageVersion) { - LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getDefaultVersion().getLanguageVersionHandler(); + LanguageVersionHandler languageVersionHandler = languageVersion.getLanguageVersionHandler(); acu = (ASTCompilationUnit)languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new StringReader(code)); stb = new SymbolFacade(); stb.initializeWith(acu); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinderTest.java new file mode 100644 index 0000000000..b2ef5ac61b --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symboltable/ScopeAndDeclarationFinderTest.java @@ -0,0 +1,44 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package net.sourceforge.pmd.lang.java.symboltable; + +import java.util.List; + +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.java.JavaLanguageModule; +import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; +import net.sourceforge.pmd.lang.symboltable.NameDeclaration; + +import org.junit.Assert; +import org.junit.Test; + +public class ScopeAndDeclarationFinderTest extends STBBaseTst { + + /** + * Unit test for https://sourceforge.net/p/pmd/bugs/1317/ + */ + @Test + public void testJava8LambdaScoping() { + String source = "public class MultipleLambdas {\n" + + " Observer a = (o, arg) -> System.out.println(\"a:\" + arg);\n" + + " Observer b = (o, arg) -> System.out.println(\"b:\" + arg);\n" + + "}"; + parseCode(source, LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.8")); + + List lambdas = acu.findDescendantsOfType(ASTLambdaExpression.class); + Assert.assertEquals(2, lambdas.size()); + LocalScope scope1 = (LocalScope)lambdas.get(0).getScope(); + LocalScope scope2 = (LocalScope)lambdas.get(1).getScope(); + Assert.assertNotSame(scope1, scope2); + + for (ASTLambdaExpression l : lambdas) { + LocalScope scope = (LocalScope)l.getScope(); + Assert.assertEquals(2, scope.getVariableDeclarations().size()); + Assert.assertTrue(scope.contains(new JavaNameOccurrence(null, "o"))); + Assert.assertTrue(scope.contains(new JavaNameOccurrence(null, "arg"))); + NameDeclaration decl = scope.findVariableHere(new JavaNameOccurrence(null, "arg")); + Assert.assertEquals(1, scope.getVariableDeclarations().get(decl).size()); + } + } +} diff --git a/pmd-java8/src/test/java/net/sourceforge/pmd/lang/java/bugs/Java8MultipleLambdasTest.java b/pmd-java8/src/test/java/net/sourceforge/pmd/lang/java/bugs/Java8MultipleLambdasTest.java deleted file mode 100644 index 1d2eaf9ef7..0000000000 --- a/pmd-java8/src/test/java/net/sourceforge/pmd/lang/java/bugs/Java8MultipleLambdasTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ -package net.sourceforge.pmd.lang.java.bugs; - -import java.io.StringReader; -import org.junit.Ignore; -import org.junit.Test; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersionHandler; -import net.sourceforge.pmd.lang.java.JavaLanguageModule; -import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; -import net.sourceforge.pmd.lang.java.symboltable.SymbolFacade; - -@Ignore -public class Java8MultipleLambdasTest { - - 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); - } - - private void parseCode(String code) { - LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getDefaultVersion().getLanguageVersionHandler(); - ASTCompilationUnit acu = (ASTCompilationUnit) languageVersionHandler.getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new StringReader(code)); - SymbolFacade stb = new SymbolFacade(); - stb.initializeWith(acu); - } - - - // Was failing with : - // java.lang.RuntimeException: Variable: image = 'i', line = 3 is already in the symbol table - // at net.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.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) -} diff --git a/src/site/markdown/overview/changelog.md b/src/site/markdown/overview/changelog.md index e7174201f6..ad45e607fe 100644 --- a/src/site/markdown/overview/changelog.md +++ b/src/site/markdown/overview/changelog.md @@ -47,6 +47,7 @@ * [#1312](https://sourceforge.net/p/pmd/bugs/1312/): Rule reference must not override rule name of referenced rule * [#1313](https://sourceforge.net/p/pmd/bugs/1313/): Missing assertion message in assertEquals with delta not detected * [#1316](https://sourceforge.net/p/pmd/bugs/1316/): Multi Rule Properties with delimiter not possible +* [#1317](https://sourceforge.net/p/pmd/bugs/1317/): RuntimeException when parsing class with multiple lambdas **API Changes:**