Fix #4912 - grammar for TWR allows this expression

This commit is contained in:
Clément Fournier
2024-04-05 10:19:58 +02:00
parent f2a586c6f2
commit 03b8d1acef
4 changed files with 19 additions and 17 deletions

View File

@ -2867,8 +2867,8 @@ void Resource() :
PrimaryExpression()
{
Node top = jjtree.peekNode();
if (!(top instanceof ASTVariableAccess || top instanceof ASTFieldAccess))
throwParseException("Expected a variable access, but was a " + top.getXPathNodeName());
if (!(top instanceof ASTVariableAccess || top instanceof ASTFieldAccess || top instanceof ASTThisExpression))
throwParseException("Expected a variable or field access, but was a " + top.getXPathNodeName());
}
{}
}

View File

@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.ast;
import org.checkerframework.checker.nullness.qual.Nullable;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil;
/**
* A resource of a {@linkplain ASTTryStatement try-with-resources}. This contains another
@ -48,24 +49,16 @@ public final class ASTResource extends AbstractJavaNode {
* then returns the sequence of names that identifies the expression.
* If this has a local variable declaration, then returns the name
* of the variable.
*
* <p>Note that this might be null if the expression is too complex.
*
* @deprecated Since 7.1.0. This method is not very useful because the expression
* might be complex and not have a real "name".
*/
@Deprecated
public String getStableName() {
if (isConciseResource()) {
ASTExpression expr = getInitializer();
StringBuilder builder = new StringBuilder();
while (expr instanceof ASTFieldAccess) {
ASTFieldAccess fa = (ASTFieldAccess) expr;
builder.insert(0, "." + fa.getName());
expr = fa.getQualifier();
}
// the last one may be ambiguous, or a variable reference
// the only common interface we have to get their name is
// unfortunately Node::getImage
if (expr != null) {
builder.insert(0, expr.getImage());
}
return builder.toString();
return PrettyPrintingUtil.prettyPrint(getInitializer()).toString();
} else {
return asLocalVariableDeclaration().iterator().next().getName();
}

View File

@ -241,6 +241,7 @@ public final class PrettyPrintingUtil {
}
/** Pretty print an expression or any other kind of node. */
public static CharSequence prettyPrint(JavaNode node) {
StringBuilder sb = new StringBuilder();
node.acceptVisitor(new ExprPrinter(), sb);

View File

@ -132,8 +132,16 @@ class ASTTryStatementTest : ParserTestSpec({
}
}
// the expr must be a field access or var access
"try ( a.foo() ){}" shouldNot parse()
"try (new Foo()){}" shouldNot parse()
"try(arr[0]) {}" shouldNot parse()
"try ( a.foo().b ){}" should parse()
"try (new Foo().x){}" should parse()
// this is also allowed by javac
"try(this) {}" should parse()
"try(Foo.this) {}" should parse()
}
}