Turn Statement into an interface

Remove BlockStatement
Introduce LocalClassDeclStatement
Introduce EmptyDeclaration (in preparation for PR about declarations)
Replace StatementExpression with ExpressionStatement

Make YieldStatement, ExplicitConstructorInvocation implement ASTStatement

Extract ForeachStatement from ForStatement

Rename
(ASTWhileStmt,
 ASTDoStmt,
 ASTForStmt,
 ASTIfStmt,
 ASTAssertStmt)#getGuardExpressionNode() -> getCondition()

Rename ASTCatchStatement -> ASTCatchClause
Rename ASTFinallyStatement -> ASTFinallyClause
Rename ASTTryStatement#getCatchStatements() -> getCatchClauses()

Make ASTYieldStatement not a TypeNode

Remove ASTTryStatement#hasFinally()

Add (ASTThrowStatement,  ASTYieldStatement, ASTReturnStatement)#getExpression()
Add ASTTryStatement#getBody()
This commit is contained in:
Clément Fournier
2019-12-14 03:32:17 +01:00
parent 5960740d18
commit b03e233647
67 changed files with 1044 additions and 438 deletions

View File

@ -1548,13 +1548,13 @@ TOKEN :
ASTCompilationUnit CompilationUnit() :
{}
{
[ LOOKAHEAD( ( Annotation() )* "package" ) PackageDeclaration() ( EmptyStatement() )* ]
( ImportDeclaration() ( EmptyStatement() )* )*
[ LOOKAHEAD( ( Annotation() )* "package" ) PackageDeclaration() ( EmptyDeclaration() )* ]
( ImportDeclaration() ( EmptyDeclaration() )* )*
// the module decl lookahead needs to be before the type declaration branch,
// looking for annotations + "open" | "module" will fail faster if it's *not*
// a module (most common case)
[ LOOKAHEAD(ModuleDeclLahead()) ModuleDeclaration() ( EmptyStatement() )* ]
( TypeDeclaration() ( EmptyStatement() )* )*
[ LOOKAHEAD(ModuleDeclLahead()) ModuleDeclaration() ( EmptyDeclaration() )* ]
( TypeDeclaration() ( EmptyDeclaration() )* )*
( < "\u001a" > )?
( < "~[]" > )? // what's this for? Do you mean ( < ~[] > )*, i.e. "any character"?
<EOF>
@ -2654,7 +2654,7 @@ void ArrayDimExpr() #void:
* Statement syntax follows.
*/
void Statement() :
void Statement() #void:
{}
{
Block()
@ -2675,7 +2675,7 @@ void Statement() :
// because they start with a different token
| LOOKAHEAD( { isNextTokenAnAssert() } ) AssertStatement()
| LOOKAHEAD(2) LabeledStatement()
| StatementExpression() ";"
| ( StatementExpression() ";" ) #ExpressionStatement
}
void LabeledStatement() :
@ -2692,14 +2692,14 @@ void Block() :
( BlockStatement() )* t = "}" { if (isPrecededByComment(t)) { jjtThis.setContainsComment(); } }
}
void BlockStatement():
void BlockStatement() #void:
{}
{
LOOKAHEAD( { isNextTokenAnAssert() } ) AssertStatement()
| LOOKAHEAD({ jdkVersion >= 13 && isKeyword("yield") }) YieldStatement()
|
LOOKAHEAD(( "final" | Annotation() )* Type() <IDENTIFIER>)
LocalVariableDeclaration() ";"
LocalVariableDeclaration() ";" { ((AbstractJavaNode) jjtree.peekNode()).shiftTokens(0, 1); }
|
// we need to lookahead until the "class" token,
// because a method ref may be annotated
@ -2709,7 +2709,7 @@ void BlockStatement():
Statement()
}
void LocalClassDecl() #void:
void LocalClassDecl() #LocalClassStatement:
{int mods = 0;}
{
// this preserves the modifiers of the local class.
@ -2757,7 +2757,13 @@ void EmptyStatement() :
";"
}
void StatementExpression() :
void EmptyDeclaration() :
{}
{
";"
}
void StatementExpression() #void:
{AssignmentOp op = null;}
{
PrefixIncrementExpression()
@ -2859,19 +2865,21 @@ void DoStatement() :
"do" Statement() "while" "(" Expression() ")" ";"
}
void ForStatement() :
{}
void ForStatement() #void:
{Token t;}
{
"for" "("
t="for" "("
(
LOOKAHEAD(LocalVariableDeclaration() ":")
LocalVariableDeclaration() ":" Expression()
|
(LocalVariableDeclaration() ":" Expression() ")" Statement() { jjtThis.jjtSetFirstToken(t); }) #ForeachStatement
| (
[ ForInit() ] ";"
[ Expression() ] ";"
[ ForUpdate() ]
)
")" Statement()
{ jjtThis.jjtSetFirstToken(t); }
) #ForStatement
)
}
void ForInit() :
@ -2932,9 +2940,10 @@ void TryStatement() :
*/
{}
{
"try" (ResourceList())? Block()
( CatchStatement() )*
[ FinallyStatement() ]
"try" (ResourceList())?
Block()
( CatchClause() )*
[ FinallyClause() ]
}
void ResourceList():
@ -2964,7 +2973,7 @@ void Resource() :
{}
}
void CatchStatement() :
void CatchClause() :
{}
{
"catch"
@ -2972,7 +2981,7 @@ void CatchStatement() :
Block()
}
void FinallyStatement() :
void FinallyClause() :
{}
{
"finally" Block()

View File

@ -13,7 +13,7 @@ package net.sourceforge.pmd.lang.java.ast;
*
* </pre>
*/
public final class ASTAssertStatement extends AbstractJavaNode {
public final class ASTAssertStatement extends AbstractStatement {
ASTAssertStatement(int id) {
super(id);
@ -38,7 +38,7 @@ public final class ASTAssertStatement extends AbstractJavaNode {
/**
* Returns the expression tested by this assert statement.
*/
public ASTExpression getGuardExpressionNode() {
public ASTExpression getCondition() {
return (ASTExpression) jjtGetChild(0);
}

View File

@ -4,7 +4,19 @@
package net.sourceforge.pmd.lang.java.ast;
public final class ASTBlock extends AbstractJavaNode {
import java.util.Iterator;
/**
* A block of code. This is a {@linkplain ASTStatement statement} that
* contains other statements.
*
* <pre class="grammar">
*
* Block ::= "{" {@link ASTStatement Statement}* "}"
*
* </pre>
*/
public final class ASTBlock extends AbstractStatement implements Iterable<ASTStatement> {
private boolean containsComment;
@ -36,4 +48,14 @@ public final class ASTBlock extends AbstractJavaNode {
this.containsComment = true;
}
@Override
public Iterator<ASTStatement> iterator() {
return children(ASTStatement.class).iterator();
}
@Override
public ASTStatement jjtGetChild(int index) {
return (ASTStatement) super.jjtGetChild(index);
}
}

View File

@ -4,6 +4,12 @@
package net.sourceforge.pmd.lang.java.ast;
/**
* @deprecated {@link ASTStatement} has been turned into an interface. Usages of BlockStatement can
* either be replaced with Statement if you don't care about the specific statement, or removed if
* you were extracting the contained node anyway.
*/
@Deprecated
public final class ASTBlockStatement extends AbstractJavaNode {
ASTBlockStatement(int id) {

View File

@ -4,7 +4,17 @@
package net.sourceforge.pmd.lang.java.ast;
public final class ASTBreakStatement extends AbstractJavaNode {
/**
* A break statement, that jumps to a named label (or exits the current loop).
*
* <pre class="grammar">
*
* BreakStatement ::= "break" &lt;IDENTIFIER&gt;? ";"
*
* </pre>
*
*/
public final class ASTBreakStatement extends AbstractStatement {
ASTBreakStatement(int id) {
super(id);
@ -25,6 +35,10 @@ public final class ASTBreakStatement extends AbstractJavaNode {
visitor.visit(this, data);
}
public String getLabel() {
return getImage();
}
@Override
public String getImage() {
String result = super.getImage();

View File

@ -9,20 +9,20 @@ import java.util.List;
/**
* Catch statement node.
* A "catch" clause of a {@linkplain ASTTryStatement try statement}.
*
* <pre class="grammar">
*
* CatchStatement ::= "catch" "(" {@link ASTFormalParameter FormalParameter} ")" {@link ASTBlock Block}
* CatchClause ::= "catch" "(" {@link ASTFormalParameter FormalParameter} ")" {@link ASTBlock Block}
*
* </pre>
*/
public final class ASTCatchStatement extends AbstractJavaNode {
ASTCatchStatement(int id) {
public final class ASTCatchClause extends AbstractJavaNode {
ASTCatchClause(int id) {
super(id);
}
ASTCatchStatement(JavaParser p, int id) {
ASTCatchClause(JavaParser p, int id) {
super(p, id);
}

View File

@ -4,7 +4,17 @@
package net.sourceforge.pmd.lang.java.ast;
public final class ASTContinueStatement extends AbstractJavaNode {
/**
* A continue statement, that jumps to the next iteration of an enclosing loop.
*
* <pre class="grammar">
*
* ContinueStatement ::= "continue" &lt;IDENTIFIER&gt;? ";"
*
* </pre>
*/
public final class ASTContinueStatement extends AbstractStatement {
ASTContinueStatement(int id) {
super(id);

View File

@ -14,7 +14,7 @@ package net.sourceforge.pmd.lang.java.ast;
*
* </pre>
*/
public final class ASTDoStatement extends AbstractJavaNode {
public final class ASTDoStatement extends AbstractStatement {
ASTDoStatement(int id) {
super(id);
@ -29,7 +29,7 @@ public final class ASTDoStatement extends AbstractJavaNode {
* Returns the node that represents the guard of this loop.
* This may be any expression of type boolean.
*/
public ASTExpression getGuardExpressionNode() {
public ASTExpression getCondition() {
return (ASTExpression) jjtGetChild(1);
}

View File

@ -5,7 +5,8 @@
package net.sourceforge.pmd.lang.java.ast;
/**
* An empty declaration (useless).
* An empty declaration (useless). This is kept separate from {@link ASTStatement}
* because they don't occur in the same syntactic contexts.
*
* <pre class="grammar">
*

View File

@ -13,7 +13,7 @@ package net.sourceforge.pmd.lang.java.ast;
*
* </pre>
*/
public final class ASTEmptyStatement extends AbstractJavaNode {
public final class ASTEmptyStatement extends AbstractStatement {
ASTEmptyStatement(int id) {
super(id);

View File

@ -22,7 +22,7 @@ import net.sourceforge.pmd.lang.java.ast.InternalInterfaces.QualifierOwner;
*
* </pre>
*/
public final class ASTExplicitConstructorInvocation extends AbstractJavaNode implements QualifierOwner {
public final class ASTExplicitConstructorInvocation extends AbstractStatement implements QualifierOwner {
private boolean isSuper;

View File

@ -0,0 +1,46 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.ast;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* A statement that contains an expression. Note that this is not an
* expression itself.
*
* <pre class="grammar">
*
* ExpressionStatement ::= {@link ASTExpression StatementExpression} ";"
*
* </pre>
*/
public final class ASTExpressionStatement extends AbstractStatement {
ASTExpressionStatement(int id) {
super(id);
}
ASTExpressionStatement(JavaParser p, int id) {
super(p, id);
}
@Override
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
@Override
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
/** Returns the contained expression. */
@NonNull
public ASTExpression getExpr() {
return (ASTExpression) jjtGetChild(0);
}
}

View File

@ -4,13 +4,23 @@
package net.sourceforge.pmd.lang.java.ast;
public final class ASTFinallyStatement extends AbstractJavaNode {
/**
* The "finally" clause of a {@linkplain ASTTryStatement try statement}.
*
*
* <pre class="grammar">
*
* FinallyClause ::= "finally" {@link ASTBlock Block}
*
* </pre>
*/
public final class ASTFinallyClause extends AbstractJavaNode {
ASTFinallyStatement(int id) {
ASTFinallyClause(int id) {
super(id);
}
ASTFinallyStatement(JavaParser p, int id) {
ASTFinallyClause(JavaParser p, int id) {
super(p, id);
}
@ -24,4 +34,11 @@ public final class ASTFinallyStatement extends AbstractJavaNode {
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
/**
* Returns the block.
*/
public ASTBlock getBlock() {
return (ASTBlock) jjtGetChild(0);
}
}

View File

@ -4,6 +4,19 @@
package net.sourceforge.pmd.lang.java.ast;
/**
* The initialization clause of a {@linkplain ASTForStatement for loop}.
* Note: ForInit nodes are necessary in the tree to differentiate them
* from the update clause. They just confer a contextual role to their
* child.
*
* <pre class="grammar">
*
* ForInit ::= {@link ASTLocalVariableDeclaration LocalVariableDeclaration}
* | {@link ASTStatementExpressionList StatementExpressionList}
*
* </pre>
*/
public final class ASTForInit extends AbstractJavaNode {
ASTForInit(int id) {
@ -24,4 +37,10 @@ public final class ASTForInit extends AbstractJavaNode {
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
/** Returns the statement nested within this node. */
public ASTStatement getStatement() {
return (ASTStatement) getFirstChild();
}
}

View File

@ -4,19 +4,19 @@
package net.sourceforge.pmd.lang.java.ast;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents a {@code for}-loop, or a foreach loop.
* Represents a {@code for} loop (distinct from {@linkplain ASTForeachStatement foreach loops}).
*
* <pre class="grammar">
*
* ForStatement ::= "for" "(" {@linkplain ASTLocalVariableDeclaration LocalVariableDeclaration} ":" {@linkplain ASTExpression Expression} ")" {@linkplain ASTStatement Statement}
* | "for" "(" {@linkplain ASTForInit ForInit}? ";" {@linkplain ASTExpression Expression}? ";" {@linkplain ASTForUpdate ForUpdate}? ")" {@linkplain ASTStatement Statement}
* ForStatement ::= "for" "(" {@linkplain ASTForInit ForInit}? ";" {@linkplain ASTExpression Expression}? ";" {@linkplain ASTForUpdate ForUpdate}? ")"
* {@linkplain ASTStatement Statement}
*
* </pre>
*/
// TODO this should be split into two different nodes, otherwise
// we can't enrich the API without returning null half the time
public final class ASTForStatement extends AbstractJavaNode {
public final class ASTForStatement extends AbstractStatement {
ASTForStatement(int id) {
super(id);
@ -41,32 +41,35 @@ public final class ASTForStatement extends AbstractJavaNode {
/**
* Returns the node that represents the guard of this loop.
* Returns the node that represents the condition of this loop.
* This may be any expression of type boolean.
*
* <p>If this node represents a foreach loop, or if there is
* no specified guard, then returns null.
* <p>If there is no specified guard, then returns null.
*/
public ASTExpression getGuardExpressionNode() {
if (isForeach()) {
return null;
}
@Nullable
public ASTExpression getCondition() {
return getFirstChildOfType(ASTExpression.class);
}
/**
* Returns true if this node represents a foreach loop.
* Returns the statement nested within the {@linkplain ASTForInit init clause}, if it exists.
* This is either a {@linkplain ASTLocalVariableDeclaration local variable declaration} or a
* {@linkplain ASTStatementExpressionList statement expression list}.
*/
public boolean isForeach() {
return jjtGetChild(0) instanceof ASTLocalVariableDeclaration;
public @Nullable ASTStatement getInit() {
ASTForInit init = AstImplUtil.getChildAs(this, 0, ASTForInit.class);
return init == null ? null : init.getStatement();
}
/**
* Returns the statement that represents the body of this
* loop.
* Returns the statement nested within the update clause, if it exists.
*/
public @Nullable ASTStatementExpressionList getUpdate() {
ASTForUpdate update = getFirstChildOfType(ASTForUpdate.class);
return update == null ? null : update.getExprList();
}
/** Returns the statement that represents the body of this loop. */
public ASTStatement getBody() {
return (ASTStatement) jjtGetChild(jjtGetNumChildren() - 1);
}

View File

@ -35,4 +35,10 @@ public final class ASTForUpdate extends AbstractJavaNode {
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
/** Returns the expression list nested within this node. */
public ASTStatementExpressionList getExprList() {
return (ASTStatementExpressionList) jjtGetChild(0);
}
}

View File

@ -0,0 +1,65 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.ast;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* Represents a "foreach"-loop on an {@link Iterable}.
*
* <pre class="grammar">
*
* ForeachStatement ::= "for" "(" {@linkplain ASTLocalVariableDeclaration LocalVariableDeclaration} ":" {@linkplain ASTExpression Expression} ")" {@linkplain ASTStatement Statement}
*
* </pre>
*/
public final class ASTForeachStatement extends AbstractStatement {
ASTForeachStatement(int id) {
super(id);
}
ASTForeachStatement(JavaParser p, int id) {
super(p, id);
}
@Override
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
@Override
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
/** Returns the id of the declared variable. */
@NonNull
public ASTVariableDeclaratorId getVariableId() {
return getFirstChildOfType(ASTLocalVariableDeclaration.class).iterator().next();
}
/**
* Returns the expression that evaluates to the {@link Iterable}
* being looped upon.
*/
@NonNull
public ASTExpression getIterableExpr() {
return getFirstChildOfType(ASTExpression.class);
}
/**
* Returns the statement that represents the body of this
* loop.
*/
public ASTStatement getBody() {
return (ASTStatement) jjtGetChild(jjtGetNumChildren() - 1);
}
}

View File

@ -11,7 +11,7 @@ import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefin
/**
* Formal parameter node. Used in the {@link ASTFormalParameters}
* production of {@link ASTMethodDeclarator} to represent a
* method's formal parameter. Also used in the {@link ASTCatchStatement}
* method's formal parameter. Also used in the {@link ASTCatchClause}
* production to represent the declared exception variable.
* Also used in LambdaExpressions for the LambdaParameters.
*

View File

@ -14,7 +14,7 @@ package net.sourceforge.pmd.lang.java.ast;
*
* </pre>
*/
public final class ASTIfStatement extends AbstractJavaNode {
public final class ASTIfStatement extends AbstractStatement {
private boolean hasElse;
@ -46,7 +46,7 @@ public final class ASTIfStatement extends AbstractJavaNode {
* Returns the node that represents the guard of this conditional.
* This may be any expression of type boolean.
*/
public ASTExpression getGuardExpressionNode() {
public ASTExpression getCondition() {
return (ASTExpression) jjtGetChild(0);
}

View File

@ -4,7 +4,16 @@
package net.sourceforge.pmd.lang.java.ast;
public final class ASTLabeledStatement extends AbstractJavaNode {
/**
* A wrapper around a statement that assigns it a label.
*
* <pre class="grammar">
*
* LabeledStatement ::= &lt;IDENTIFIER&gt; ":" {@link ASTStatement Statement}
*
* </pre>
*/
public final class ASTLabeledStatement extends AbstractStatement {
ASTLabeledStatement(int id) {
super(id);
@ -25,4 +34,18 @@ public final class ASTLabeledStatement extends AbstractJavaNode {
visitor.visit(this, data);
}
/**
* Returns the name of the label.
*/
public String getLabel() {
return getImage();
}
/**
* Returned the statement named by this label.
*/
public ASTStatement getStatement() {
return (ASTStatement) jjtGetChild(1);
}
}

View File

@ -0,0 +1,48 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.ast;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* A statement that contains a local class declaration. Note that this
* is not a declaration itself.
*
* <pre class="grammar">
*
* LocalClassStatement ::= {@link ASTClassOrInterfaceDeclaration ClassDeclaration}
*
* </pre>
*/
public final class ASTLocalClassStatement extends AbstractStatement implements LeftRecursiveNode {
ASTLocalClassStatement(int id) {
super(id);
}
ASTLocalClassStatement(JavaParser p, int id) {
super(p, id);
}
@Override
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
@Override
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
/**
* Returns the contained declaration.
*/
@NonNull
public ASTClassOrInterfaceDeclaration getDeclaration() {
return (ASTClassOrInterfaceDeclaration) jjtGetChild(0);
}
}

View File

@ -8,13 +8,13 @@ import java.util.Iterator;
/**
* Represents a local variable declaration. This is a {@linkplain ASTBlockStatement block statement},
* Represents a local variable declaration. This is a {@linkplain ASTStatement statement},
* but the node is also used in {@linkplain ASTForInit for-loop initialisers} and
* {@linkplain ASTForStatement foreach statements}.
*
* <p>This statement may define several variables, possibly of different types (see {@link
* ASTVariableDeclaratorId#getType()}).
* The nodes corresponding to the declared variables are accessible through {@link #iterator()}.
* <p>This statement may define several variables, possibly of different types
* (see {@link ASTVariableDeclaratorId#getType()}). The nodes corresponding to
* the declared variables are accessible through {@link #iterator()}.
*
* <pre class="grammar">
*
@ -22,7 +22,8 @@ import java.util.Iterator;
*
* </pre>
*/
public final class ASTLocalVariableDeclaration extends AbstractJavaAccessNode implements Dimensionable, Iterable<ASTVariableDeclaratorId> {
// TODO extend AbstractStatement
public final class ASTLocalVariableDeclaration extends AbstractJavaAccessNode implements Dimensionable, Iterable<ASTVariableDeclaratorId>, ASTStatement {
ASTLocalVariableDeclaration(int id) {
super(id);
@ -44,6 +45,17 @@ public final class ASTLocalVariableDeclaration extends AbstractJavaAccessNode im
}
/**
* Returns true if the local variables declared by this statement
* are final.
*/
@Override
@SuppressWarnings("PMD.UselessOverridingMethod")
public boolean isFinal() {
// TODO unimplement AccessNode, this causes compilation errors because of our current symbol table
return super.isFinal();
}
/**
* If true, this local variable declaration represents a declaration,
* which makes use of local variable type inference, e.g. java10 "var".

View File

@ -4,7 +4,19 @@
package net.sourceforge.pmd.lang.java.ast;
public final class ASTReturnStatement extends AbstractJavaNode {
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* A return statement in a method or constructor body.
*
*
* <pre class="grammar">
*
* ReturnStatement ::= "return" {@link ASTExpression Expression}? ";"
*
* </pre>
*/
public final class ASTReturnStatement extends AbstractStatement {
ASTReturnStatement(int id) {
super(id);
@ -24,4 +36,12 @@ public final class ASTReturnStatement extends AbstractJavaNode {
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
/**
* Returns the returned expression, or null if this is a simple return.
*/
@Nullable
public ASTExpression getExpr() {
return AstImplUtil.getChildAs(this, 0, ASTExpression.class);
}
}

View File

@ -4,24 +4,38 @@
package net.sourceforge.pmd.lang.java.ast;
public final class ASTStatement extends AbstractJavaNode {
/**
* Represents a code statement.
*
* <pre class="grammar">
*
* Statement ::= {@link ASTAssertStatement AssertStatement}
* | {@link ASTBlock Block}
* | {@link ASTBreakStatement BreakStatement}
* | {@link ASTContinueStatement ContinueStatement}
* | {@link ASTDoStatement DoStatement}
* | {@link ASTEmptyStatement EmptyStatement}
* | {@link ASTExplicitConstructorInvocation ExplicitConstructorInvocation}
* | {@link ASTExpressionStatement ExpressionStatement}
* | {@link ASTForeachStatement ForeachStatement}
* | {@link ASTForStatement ForStatement}
* | {@link ASTIfStatement IfStatement}
* | {@link ASTLabeledStatement LabeledStatement}
* | {@link ASTLocalClassStatement LocalClassStatement}
* | {@link ASTLocalVariableDeclaration LocalVariableDeclaration}
* | {@link ASTReturnStatement ReturnStatement}
* | {@link ASTStatementExpressionList StatementExpressionList}
* | {@link ASTSwitchStatement SwitchStatement}
* | {@link ASTSynchronizedStatement SynchronizedStatement}
* | {@link ASTThrowStatement ThrowStatement}
* | {@link ASTTryStatement TryStatement}
* | {@link ASTWhileStatement WhileStatement}
* | {@link ASTYieldStatement YieldStatement}
*
* </pre>
*
*
*/
public interface ASTStatement extends JavaNode {
public ASTStatement(int id) {
super(id);
}
public ASTStatement(JavaParser p, int id) {
super(p, id);
}
@Override
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
@Override
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
}

View File

@ -4,6 +4,11 @@
package net.sourceforge.pmd.lang.java.ast;
/**
* @deprecated Use {@link ASTExpression} inside {@link ASTStatementExpressionList},
* or {@link ASTExpressionStatement} inside {@link ASTBlock}
*/
@Deprecated
public final class ASTStatementExpression extends AbstractJavaTypeNode {
ASTStatementExpression(int id) {

View File

@ -4,7 +4,23 @@
package net.sourceforge.pmd.lang.java.ast;
public final class ASTStatementExpressionList extends AbstractJavaNode {
import java.util.Iterator;
/**
* A list of statement expressions. Statement expressions are those
* expressions which can appear in an {@linkplain ASTExpressionStatement expression statement}.
*
*
* <p>Statement expression lists occur only {@link ASTForInit} and {@link ASTForUpdate}.
* To improve the API of {@link ASTForInit}, however, this node implements {@link ASTStatement}.
*
* <pre class="grammar">
*
* StatementExpressionList ::= {@link ASTExpression Expression} ( "," {@link ASTExpression Expression} )*
*
* </pre>
*/
public final class ASTStatementExpressionList extends AbstractStatement implements Iterable<ASTExpression> {
ASTStatementExpressionList(int id) {
super(id);
@ -24,4 +40,9 @@ public final class ASTStatementExpressionList extends AbstractJavaNode {
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
@Override
public Iterator<ASTExpression> iterator() {
return children(ASTExpression.class).iterator();
}
}

View File

@ -15,7 +15,7 @@ import org.apache.commons.lang3.EnumUtils;
* {@link ASTSwitchExpression SwitchExpression}, though it does not need
* to be exhaustive. See the doc of that node for details.
*/
public final class ASTSwitchStatement extends AbstractJavaNode implements Iterable<ASTSwitchLabel> {
public final class ASTSwitchStatement extends AbstractStatement implements Iterable<ASTSwitchLabel> {
ASTSwitchStatement(int id) {
super(id);
}

View File

@ -4,7 +4,17 @@
package net.sourceforge.pmd.lang.java.ast;
public final class ASTSynchronizedStatement extends AbstractJavaNode {
/**
* A synchronized statement.
*
* <pre class="grammar">
*
* SynchronizedStatement ::= "synchronized" "(" {@link ASTExpression Expression} ")" {@link ASTBlock Block}
*
* </pre>
*/
public final class ASTSynchronizedStatement extends AbstractStatement {
ASTSynchronizedStatement(int id) {
super(id);
@ -24,4 +34,18 @@ public final class ASTSynchronizedStatement extends AbstractJavaNode {
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
/**
* Returns the expression evaluating to the lock object.
*/
public ASTExpression getLockExpression() {
return (ASTExpression) jjtGetChild(0);
}
/**
* Returns the body of the statement.
*/
public ASTBlock getBody() {
return (ASTBlock) jjtGetChild(1);
}
}

View File

@ -13,7 +13,7 @@ package net.sourceforge.pmd.lang.java.ast;
*
* </pre>
*/
public final class ASTThrowStatement extends AbstractJavaNode {
public final class ASTThrowStatement extends AbstractStatement {
ASTThrowStatement(int id) {
super(id);
@ -34,6 +34,10 @@ public final class ASTThrowStatement extends AbstractJavaNode {
visitor.visit(this, data);
}
/** Returns the expression for the thrown exception. */
public ASTExpression getExpr() {
return (ASTExpression) getFirstChild();
}
/**
* Gets the image of the first ASTClassOrInterfaceType child or

View File

@ -20,12 +20,12 @@ import net.sourceforge.pmd.internal.util.IteratorUtil;
*
* TryStatement ::= "try" {@link ASTResourceList ResourceList}?
* {@link ASTBlock Block}
* {@link ASTCatchStatement CatchStatement}*
* {@link ASTFinallyStatement FinallyStatement}?
* {@link ASTCatchClause CatchClause}*
* {@link ASTFinallyClause FinallyClause}?
*
* </pre>
*/
public final class ASTTryStatement extends AbstractJavaNode {
public final class ASTTryStatement extends AbstractStatement {
ASTTryStatement(int id) {
super(id);
@ -66,22 +66,18 @@ public final class ASTTryStatement extends AbstractJavaNode {
return list == null ? Collections.emptyList() : IteratorUtil.toList(list.iterator());
}
/** Returns the body of the statement. */
public ASTBlock getBody() {
return (ASTBlock) jjtGetChild(1);
}
/**
* Returns the catch statement nodes of this try statement.
* If there are none, returns an empty list.
*/
public List<ASTCatchStatement> getCatchStatements() {
return findChildrenOfType(ASTCatchStatement.class);
}
/**
* Returns true if this try statement has a {@code finally} statement,
* in which case {@link #getFinally()} won't return {@code null}.
*/
public boolean hasFinally() {
return getFirstChildOfType(ASTFinallyStatement.class) != null;
public List<ASTCatchClause> getCatchClauses() {
return findChildrenOfType(ASTCatchClause.class);
}
@ -90,8 +86,9 @@ public final class ASTTryStatement extends AbstractJavaNode {
*
* @return The finally statement, or null if there is none
*/
public ASTFinallyStatement getFinally() {
return getFirstChildOfType(ASTFinallyStatement.class);
@Nullable
public ASTFinallyClause getFinally() {
return AstImplUtil.getChildAs(this, jjtGetNumChildren() - 1, ASTFinallyClause.class);
}
}

Some files were not shown because too many files have changed in this diff Show More