Rework AccessNode
Introduce a ModifierList node, that ranges over the modifiers of a declaration (including annotations). This is a combination of a few old commits: Figure out modifiers Fix tests Remove AccessTypeNode Document Remove specific methods Fix symboltable test Fix tests Rename to JModifier Fix copypaste default/abstract Improve doc Test anon classes Remove useless impl Static modifier should not be present on toplevel classes Simplify impl Add visibility enum Port some tests Fix test ranges Fix modifier ordering Cleanup Fix unnecessary modifier rule Rename to use plural Improve visibility doc Simplify some things Checkstyle Remove some usages of typekind Fix missing import Remove irrelevant method REmove some duplication Replace AccessNode with ModifierOwner Rename to AccessNode to reduce diff Remove changes to rules Add convenience methods Make VariableDeclaratorId a ModifierOwner Fix variable name decl Make enum constant an implicit AccessNode Fix compil Checkstyle Cleanup Deprecate TypeKind Cleanup Remove TypeKind Revert "Remove TypeKind" This reverts commit 222c169c3401a01507726f339ae9f9b2b20dc69a. Fix doc Fix UnnecessaryModifierRule Use special node instead of ModifierSet Remove useless tests Fix tests WIP Work should be resumed when #2211 is merged into java-grammar Fix some tests Doc
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,7 @@ import net.sourceforge.pmd.lang.java.ast.MethodLikeNode.MethodLikeKind;
|
||||
* enclosing type is an annotation.
|
||||
*/
|
||||
@Deprecated
|
||||
public final class ASTAnnotationMethodDeclaration extends AbstractJavaAccessNode {
|
||||
public final class ASTAnnotationMethodDeclaration extends AbstractJavaNode implements AccessNode {
|
||||
|
||||
ASTAnnotationMethodDeclaration(int id) {
|
||||
super(id);
|
||||
|
@ -4,27 +4,19 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The declaration of an annotation type.
|
||||
*
|
||||
* <p>Note that in constrast to interface types, no {@linkplain ASTExtendsList extends clause}
|
||||
* <p>Note that in contrast to interface types, no {@linkplain ASTExtendsList extends clause}
|
||||
* is permitted, and an annotation type cannot be generic.
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* AnnotationTypeDeclaration ::= AnnotationTypeModifier*
|
||||
* AnnotationTypeDeclaration ::= {@link ASTModifierList ModifierList}
|
||||
* "@" "interface"
|
||||
* <IDENTIFIER>
|
||||
* {@link ASTAnnotationTypeBody AnnotationTypeBody}
|
||||
*
|
||||
*
|
||||
*
|
||||
* AnnotationTypeModifier ::= "public" | "private" | "protected"
|
||||
* | "abstract" | "static"
|
||||
* | {@linkplain ASTAnnotation Annotation}
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
@ -52,10 +44,9 @@ public final class ASTAnnotationTypeDeclaration extends AbstractAnyTypeDeclarati
|
||||
return TypeKind.ANNOTATION;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<ASTAnyTypeBodyDeclaration> getDeclarations() {
|
||||
return getFirstChildOfType(ASTAnnotationTypeBody.class)
|
||||
.findChildrenOfType(ASTAnyTypeBodyDeclaration.class);
|
||||
public boolean isInterface() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,23 +4,19 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.qname.JavaTypeQualifiedName;
|
||||
|
||||
|
||||
/**
|
||||
* An anonymous class declaration. This can occur in a {@linkplain ASTConstructorCall class instance creation expression}
|
||||
* An anonymous class declaration. This can occur in a {@linkplain ASTConstructorCall class instance creation
|
||||
* expression}
|
||||
* or in an {@linkplain ASTEnumConstant enum constant declaration}.
|
||||
*
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* AnonymousClassDeclaration ::= {@link ASTClassOrInterfaceBody}
|
||||
* AnonymousClassDeclaration ::= {@link ASTModifierList EmptyModifierList} {@link ASTClassOrInterfaceBody}
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTAnonymousClassDeclaration extends AbstractJavaTypeNode implements JavaQualifiableNode {
|
||||
|
||||
private JavaTypeQualifiedName qualifiedName;
|
||||
public final class ASTAnonymousClassDeclaration extends AbstractAnyTypeDeclaration {
|
||||
|
||||
|
||||
ASTAnonymousClassDeclaration(int id) {
|
||||
@ -34,6 +30,11 @@ public final class ASTAnonymousClassDeclaration extends AbstractJavaTypeNode imp
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Visibility getVisibility() {
|
||||
return Visibility.V_ANONYMOUS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
@ -45,27 +46,8 @@ public final class ASTAnonymousClassDeclaration extends AbstractJavaTypeNode imp
|
||||
visitor.visit(this, data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the body of the anonymous class.
|
||||
*/
|
||||
public ASTClassOrInterfaceBody getBody() {
|
||||
return (ASTClassOrInterfaceBody) getChild(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the qualified name of the anonymous class
|
||||
* declared by this node.
|
||||
*/
|
||||
@Override
|
||||
public JavaTypeQualifiedName getQualifiedName() {
|
||||
return qualifiedName;
|
||||
public TypeKind getTypeKind() {
|
||||
return TypeKind.CLASS;
|
||||
}
|
||||
|
||||
|
||||
public void setQualifiedName(JavaTypeQualifiedName qname) {
|
||||
this.qualifiedName = qname;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,22 +4,32 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import static net.sourceforge.pmd.lang.java.ast.JModifier.ABSTRACT;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.NodeStream;
|
||||
import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil;
|
||||
import net.sourceforge.pmd.lang.java.qname.JavaTypeQualifiedName;
|
||||
|
||||
|
||||
/**
|
||||
* Groups enum, class, annotation and interface declarations.
|
||||
*
|
||||
* @author Clément Fournier
|
||||
* Groups enum, class, annotation and interface declarations under a common
|
||||
* supertype.
|
||||
*/
|
||||
public interface ASTAnyTypeDeclaration extends TypeNode, JavaQualifiableNode, AccessNode, JavaNode {
|
||||
public interface ASTAnyTypeDeclaration extends TypeNode, JavaQualifiableNode, AccessNode, FinalizableNode {
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getBinaryName()}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
JavaTypeQualifiedName getQualifiedName();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -47,6 +57,15 @@ public interface ASTAnyTypeDeclaration extends TypeNode, JavaQualifiableNode, Ac
|
||||
// @NotNull
|
||||
String getBinaryName();
|
||||
|
||||
/**
|
||||
* Returns true if this is an abstract type. Interfaces and annotations
|
||||
* types are implicitly abstract.
|
||||
*/
|
||||
@Override
|
||||
default boolean isAbstract() {
|
||||
return hasModifiers(ABSTRACT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds the type kind of this declaration.
|
||||
@ -59,21 +78,31 @@ public interface ASTAnyTypeDeclaration extends TypeNode, JavaQualifiableNode, Ac
|
||||
TypeKind getTypeKind();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the enum constants declared by this enum. If this is not
|
||||
* an enum declaration, returns an empty stream.
|
||||
*/
|
||||
default NodeStream<ASTEnumConstant> getEnumConstants() {
|
||||
return getFirstChildOfType(ASTEnumBody.class).children(ASTEnumConstant.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the member declarations (fields, methods, classes, etc.) from the body of this type declaration.
|
||||
*
|
||||
* @return The member declarations declared in this type declaration
|
||||
*/
|
||||
List<ASTAnyTypeBodyDeclaration> getDeclarations();
|
||||
default List<ASTAnyTypeBodyDeclaration> getDeclarations() {
|
||||
return getBody().children(ASTAnyTypeBodyDeclaration.class).toList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getBinaryName()}
|
||||
* Returns the body of this type declaration.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
JavaTypeQualifiedName getQualifiedName();
|
||||
|
||||
default ASTTypeBody getBody() {
|
||||
return (ASTTypeBody) getLastChild();
|
||||
}
|
||||
|
||||
default List<ASTTypeParameter> getTypeParameters() {
|
||||
ASTTypeParameters parameters = getFirstChildOfType(ASTTypeParameters.class);
|
||||
@ -85,22 +114,65 @@ public interface ASTAnyTypeDeclaration extends TypeNode, JavaQualifiableNode, Ac
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this type declaration is nested inside an interface, class or annotation.
|
||||
* Returns true if this type declaration is nested inside an interface,
|
||||
* class or annotation.
|
||||
*/
|
||||
default boolean isNested() {
|
||||
return getParent() instanceof ASTClassOrInterfaceBodyDeclaration
|
||||
|| getParent() instanceof ASTAnnotationTypeMemberDeclaration;
|
||||
return getParent() instanceof ASTAnyTypeBodyDeclaration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this is a local class declaration.
|
||||
* Returns true if the class is declared inside a block other
|
||||
* than the body of another class, or the top level. Anonymous
|
||||
* classes are not considered local. Only class declarations
|
||||
* can be local. Local classes cannot be static.
|
||||
*/
|
||||
default boolean isLocal() {
|
||||
return getParent() instanceof ASTLocalClassStatement;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this type is declared at the top-level of a file.
|
||||
*/
|
||||
default boolean isTopLevel() {
|
||||
return getParent() instanceof ASTTypeDeclaration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this is an {@linkplain ASTAnonymousClassDeclaration anonymous class declaration}.
|
||||
*/
|
||||
default boolean isAnonymous() {
|
||||
return this instanceof ASTAnonymousClassDeclaration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this is an {@linkplain ASTEnumDeclaration enum class declaration}.
|
||||
*/
|
||||
default boolean isEnum() {
|
||||
return this instanceof ASTEnumDeclaration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is an interface type declaration (including
|
||||
* annotation types). This is consistent with {@link Class#isInterface()}.
|
||||
*/
|
||||
default boolean isInterface() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Returns true if this is an {@linkplain ASTAnnotationTypeDeclaration annotation type declaration}. */
|
||||
default boolean isAnnotation() {
|
||||
return this instanceof ASTAnnotationTypeDeclaration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The kind of type this node declares.
|
||||
*
|
||||
@ -125,27 +197,7 @@ public interface ASTAnyTypeDeclaration extends TypeNode, JavaQualifiableNode, Ac
|
||||
*/
|
||||
@Deprecated
|
||||
enum TypeKind {
|
||||
CLASS, INTERFACE, ENUM, ANNOTATION;
|
||||
|
||||
|
||||
public String getPrintableName() {
|
||||
return name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
|
||||
public static TypeKind ofClass(Class<?> clazz) {
|
||||
|
||||
if (clazz.isInterface()) {
|
||||
return INTERFACE;
|
||||
} else if (clazz.isEnum()) {
|
||||
return ENUM;
|
||||
} else if (clazz.isAnnotation()) {
|
||||
return ANNOTATION;
|
||||
} else {
|
||||
return CLASS;
|
||||
}
|
||||
|
||||
}
|
||||
CLASS, INTERFACE, ENUM, ANNOTATION
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,11 +13,13 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* CatchParameter ::= ( "final" | {@link ASTAnnotation Annotation} )* {@link ASTType Type} {@link ASTVariableDeclaratorId VariableDeclaratorId}
|
||||
* CatchParameter ::= {@link ASTModifierList LocalVarModifierList} {@link ASTType Type} {@link ASTVariableDeclaratorId VariableDeclaratorId}
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTCatchParameter extends AbstractJavaAccessNode implements InternalInterfaces.VariableIdOwner {
|
||||
public final class ASTCatchParameter extends AbstractJavaNode
|
||||
implements InternalInterfaces.VariableIdOwner,
|
||||
FinalizableNode {
|
||||
|
||||
ASTCatchParameter(int id) {
|
||||
super(id);
|
||||
|
@ -17,18 +17,13 @@ import net.sourceforge.pmd.util.CollectionUtil;
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* ClassOrInterfaceDeclaration ::= ClassModifier*
|
||||
* ClassOrInterfaceDeclaration ::= {@link ASTModifierList ModifierList}
|
||||
* ( "class" | "interface" )
|
||||
* <IDENTIFIER>
|
||||
* {@linkplain ASTTypeParameters TypeParameters}?
|
||||
* {@linkplain ASTExtendsList ExtendsList}?
|
||||
* {@linkplain ASTImplementsList ImplementsList}?
|
||||
* {@linkplain ASTClassOrInterfaceBody ClassOrInterfaceBody}
|
||||
*
|
||||
*
|
||||
* ClassModifier ::= "public" | "private" | "protected"
|
||||
* | "final" | "abstract" | "static" | "strictfp"
|
||||
* | {@linkplain ASTAnnotation Annotation}
|
||||
* {@link ASTTypeParameters TypeParameters}?
|
||||
* {@link ASTExtendsList ExtendsList}?
|
||||
* {@link ASTImplementsList ImplementsList}?
|
||||
* {@link ASTClassOrInterfaceBody ClassOrInterfaceBody}
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@ -45,16 +40,12 @@ public final class ASTClassOrInterfaceDeclaration extends AbstractAnyTypeDeclara
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackagePrivate() {
|
||||
return super.isPackagePrivate() && !isLocal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
|
||||
visitor.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterface() {
|
||||
return this.isInterface;
|
||||
}
|
||||
@ -69,13 +60,6 @@ public final class ASTClassOrInterfaceDeclaration extends AbstractAnyTypeDeclara
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<ASTAnyTypeBodyDeclaration> getDeclarations() {
|
||||
return getFirstChildOfType(ASTClassOrInterfaceBody.class)
|
||||
.findChildrenOfType(ASTAnyTypeBodyDeclaration.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the superclass type node if this node is a class
|
||||
* declaration and explicitly declares an {@code extends}
|
||||
|
@ -12,18 +12,13 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* ConstructorDeclaration ::= ConstructorModifier*
|
||||
* ConstructorDeclaration ::= {@link ASTModifierList ModifierList}
|
||||
* {@link ASTTypeParameters TypeParameters}?
|
||||
* <IDENTIFIER>
|
||||
* {@link ASTFormalParameters FormalParameters}
|
||||
* ({@link ASTThrowsList ThrowsList})?
|
||||
* {@link ASTBlock Block}
|
||||
*
|
||||
*
|
||||
* ConstructorModifier ::= "public" | "private" | "protected"
|
||||
* | {@linkplain ASTAnnotation Annotation}
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTConstructorDeclaration extends AbstractMethodOrConstructorDeclaration {
|
||||
|
@ -11,15 +11,15 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* EnumConstant ::= {@link ASTAnnotation Annotation}* {@link ASTVariableDeclaratorId VariableDeclaratorId} {@linkplain ASTArgumentList ArgumentList}? {@linkplain ASTAnonymousClassDeclaration AnonymousClassDeclaration}?
|
||||
* EnumConstant ::= {@link ASTModifierList AnnotationList} {@link ASTVariableDeclaratorId VariableDeclaratorId} {@linkplain ASTArgumentList ArgumentList}? {@linkplain ASTAnonymousClassDeclaration AnonymousClassDeclaration}?
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTEnumConstant extends AbstractJavaNode
|
||||
implements Annotatable,
|
||||
AccessNode,
|
||||
InternalInterfaces.VariableIdOwner {
|
||||
|
||||
|
||||
ASTEnumConstant(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
|
||||
/**
|
||||
@ -18,18 +16,12 @@ import net.sourceforge.pmd.lang.ast.Node;
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* EnumDeclaration ::= EnumModifier*
|
||||
* EnumDeclaration ::= {@link ASTModifierList ModifierList}
|
||||
* "enum"
|
||||
* <IDENTIFIER>
|
||||
* {@linkplain ASTImplementsList ImplementsList}?
|
||||
* {@link ASTEnumBody EnumBody}
|
||||
*
|
||||
*
|
||||
*
|
||||
* EnumModifier ::= "public" | "private" | "protected"
|
||||
* | "strictfp" | "static"
|
||||
* | {@linkplain ASTAnnotation Annotation}
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTEnumDeclaration extends AbstractAnyTypeDeclaration {
|
||||
@ -56,16 +48,8 @@ public final class ASTEnumDeclaration extends AbstractAnyTypeDeclaration {
|
||||
return TypeKind.ENUM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the enum constants declared by this enum.
|
||||
*/
|
||||
public List<ASTEnumConstant> getConstants() {
|
||||
return getFirstChildOfType(ASTEnumBody.class).findChildrenOfType(ASTEnumConstant.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ASTAnyTypeBodyDeclaration> getDeclarations() {
|
||||
return getFirstChildOfType(ASTEnumBody.class)
|
||||
.findChildrenOfType(ASTAnyTypeBodyDeclaration.class);
|
||||
public ASTEnumBody getBody() {
|
||||
return (ASTEnumBody) getLastChild();
|
||||
}
|
||||
}
|
||||
|
@ -15,31 +15,21 @@ import net.sourceforge.pmd.lang.java.multifile.signature.JavaFieldSignature;
|
||||
* types (see {@link ASTVariableDeclaratorId#getType()}). The nodes
|
||||
* corresponding to the declared variables are accessible through {@link #iterator()}.
|
||||
*
|
||||
* <p>{@link AccessNode} methods take into account the syntactic context of the
|
||||
* declaration, e.g. {@link #isPublic()} will always return true if the field is
|
||||
* declared inside an interface, regardless of whether the {@code public} modifier
|
||||
* was specified or not. If you want to know whether the modifier was explicitly
|
||||
* stated, use e.g {@link #isSyntacticallyPublic()}.
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* FieldDeclaration ::= FieldModifier* {@linkplain ASTType Type} {@linkplain ASTVariableDeclarator VariableDeclarator} ( "," {@linkplain ASTVariableDeclarator VariableDeclarator} )* ";"
|
||||
*
|
||||
* FieldModifier ::= "public" | "static" | "protected" | "private"
|
||||
* | "final" | "transient" | "volatile"
|
||||
* | {@linkplain ASTAnnotation Annotation}
|
||||
* FieldDeclaration ::= {@link ASTModifierList ModifierList} {@linkplain ASTType Type} {@linkplain ASTVariableDeclarator VariableDeclarator} ( "," {@linkplain ASTVariableDeclarator VariableDeclarator} )* ";"
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTFieldDeclaration extends AbstractJavaAccessNode
|
||||
public final class ASTFieldDeclaration extends AbstractJavaNode
|
||||
implements SignedNode<ASTFieldDeclaration>,
|
||||
Iterable<ASTVariableDeclaratorId>,
|
||||
LeftRecursiveNode,
|
||||
AccessNode,
|
||||
InternalInterfaces.MultiVariableIdOwner {
|
||||
|
||||
private JavaFieldSignature signature;
|
||||
|
||||
|
||||
ASTFieldDeclaration(int id) {
|
||||
super(id);
|
||||
}
|
||||
@ -55,86 +45,6 @@ public final class ASTFieldDeclaration extends AbstractJavaAccessNode
|
||||
visitor.visit(this, data);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSyntacticallyPublic() {
|
||||
return super.isPublic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPublic() {
|
||||
if (isAnnotationMember() || isInterfaceMember()) {
|
||||
return true;
|
||||
}
|
||||
return super.isPublic();
|
||||
}
|
||||
|
||||
public boolean isSyntacticallyStatic() {
|
||||
return super.isStatic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
if (isAnnotationMember() || isInterfaceMember()) {
|
||||
return true;
|
||||
}
|
||||
return super.isStatic();
|
||||
}
|
||||
|
||||
public boolean isSyntacticallyFinal() {
|
||||
return super.isFinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
if (isAnnotationMember() || isInterfaceMember()) {
|
||||
return true;
|
||||
}
|
||||
return super.isFinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivate() {
|
||||
if (isAnnotationMember() || isInterfaceMember()) {
|
||||
return false;
|
||||
}
|
||||
return super.isPrivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackagePrivate() {
|
||||
if (isAnnotationMember() || isInterfaceMember()) {
|
||||
return false;
|
||||
}
|
||||
return super.isPackagePrivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtected() {
|
||||
if (isAnnotationMember() || isInterfaceMember()) {
|
||||
return false;
|
||||
}
|
||||
return super.isProtected();
|
||||
}
|
||||
|
||||
public boolean isAnnotationMember() {
|
||||
return getNthParent(2) instanceof ASTAnnotationTypeBody;
|
||||
}
|
||||
|
||||
public boolean isInterfaceMember() {
|
||||
if (getNthParent(2) instanceof ASTEnumBody) {
|
||||
return false;
|
||||
}
|
||||
ASTClassOrInterfaceBody classOrInterfaceBody = getFirstParentOfType(ASTClassOrInterfaceBody.class);
|
||||
if (classOrInterfaceBody == null || classOrInterfaceBody.isAnonymousInnerClass()) {
|
||||
return false;
|
||||
}
|
||||
if (classOrInterfaceBody.getParent() instanceof ASTClassOrInterfaceDeclaration) {
|
||||
ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) classOrInterfaceBody.getParent();
|
||||
return n.isInterface();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the variable name of this field. This method searches the first
|
||||
* VariableDeclartorId node and returns its image or <code>null</code> if
|
||||
|
@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.lang.java.ast.InternalInterfaces.VariableIdOwner;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
|
||||
|
||||
|
||||
@ -19,13 +20,14 @@ import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefin
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* FormalParameter ::= ( "final" | {@link ASTAnnotation Annotation} )* {@link ASTType Type} {@link ASTVariableDeclaratorId VariableDeclaratorId}
|
||||
* FormalParameter ::= {@link ASTModifierList LocalVarModifierList} {@link ASTType Type} {@link ASTVariableDeclaratorId VariableDeclaratorId}
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTFormalParameter extends AbstractJavaAccessTypeNode
|
||||
implements Annotatable,
|
||||
InternalInterfaces.VariableIdOwner {
|
||||
public final class ASTFormalParameter extends AbstractJavaTypeNode
|
||||
implements FinalizableNode,
|
||||
Annotatable,
|
||||
VariableIdOwner {
|
||||
|
||||
@InternalApi
|
||||
@Deprecated
|
||||
@ -33,6 +35,12 @@ public final class ASTFormalParameter extends AbstractJavaAccessTypeNode
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Visibility getVisibility() {
|
||||
return Visibility.V_LOCAL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this node is a varargs parameter. Then, the type
|
||||
* node is an {@link ASTArrayType ArrayType}, and its last dimension
|
||||
|
@ -35,7 +35,7 @@ import net.sourceforge.pmd.lang.java.ast.InternalInterfaces.BinaryExpressionLike
|
||||
* <img src="doc-files/binaryExpr_60x.svg" />
|
||||
* </figure>
|
||||
*/
|
||||
public final class ASTInfixExpression extends AbstractJavaExpr implements LeftRecursiveNode, BinaryExpressionLike, AtLeastOneChild {
|
||||
public final class ASTInfixExpression extends AbstractJavaExpr implements BinaryExpressionLike, AtLeastOneChild {
|
||||
|
||||
private BinaryOp operator;
|
||||
|
||||
|
@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.NodeStream;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
|
||||
import net.sourceforge.pmd.lang.java.qname.JavaOperationQualifiedName;
|
||||
|
||||
|
||||
/**
|
||||
@ -20,10 +20,9 @@ import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefin
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTLambdaExpression extends AbstractMethodLikeNode implements ASTExpression {
|
||||
public final class ASTLambdaExpression extends AbstractJavaExpr implements ASTExpression, MethodLikeNode {
|
||||
|
||||
private JavaTypeDefinition typeDefinition;
|
||||
private int parenDepth;
|
||||
private JavaOperationQualifiedName qualifiedName;
|
||||
|
||||
ASTLambdaExpression(int id) {
|
||||
super(id);
|
||||
@ -43,9 +42,11 @@ public final class ASTLambdaExpression extends AbstractMethodLikeNode implements
|
||||
return !isBlockBody();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the body of this lambda if it is a block.
|
||||
*/
|
||||
@Nullable
|
||||
public ASTBlock getBlockBody() {
|
||||
return NodeStream.of(getLastChild()).filterIs(ASTBlock.class).first();
|
||||
}
|
||||
@ -53,40 +54,12 @@ public final class ASTLambdaExpression extends AbstractMethodLikeNode implements
|
||||
/**
|
||||
* Returns the body of this lambda if it is an expression.
|
||||
*/
|
||||
@Nullable
|
||||
public ASTExpression getExpressionBody() {
|
||||
return NodeStream.of(getLastChild()).filterIs(ASTExpression.class).first();
|
||||
}
|
||||
|
||||
|
||||
// TODO MethodLikeNode should be removed, and this class extend AbstractJavaExpr
|
||||
|
||||
void bumpParenDepth() {
|
||||
parenDepth++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getParenthesisDepth() {
|
||||
return parenDepth;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> getType() {
|
||||
return typeDefinition == null ? null : typeDefinition.getType();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JavaTypeDefinition getTypeDefinition() {
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
|
||||
void setTypeDefinition(JavaTypeDefinition typeDefinition) {
|
||||
this.typeDefinition = typeDefinition;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isFindBoundary() {
|
||||
@ -106,6 +79,15 @@ public final class ASTLambdaExpression extends AbstractMethodLikeNode implements
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public JavaOperationQualifiedName getQualifiedName() {
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
void setQualifiedName(JavaOperationQualifiedName qualifiedName) {
|
||||
this.qualifiedName = qualifiedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodLikeKind getKind() {
|
||||
return MethodLikeKind.LAMBDA;
|
||||
|
@ -15,30 +15,19 @@ import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefin
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* LambdaParameter ::= ( "final" | {@link ASTAnnotation Annotation} )* ( "var" | {@link ASTType Type} ) {@link ASTVariableDeclaratorId VariableDeclaratorId}
|
||||
* | {@link ASTVariableDeclaratorId VariableDeclaratorId}
|
||||
* LambdaParameter ::= {@link ASTModifierList LocalVarModifierList} ( "var" | {@link ASTType Type} ) {@link ASTVariableDeclaratorId VariableDeclaratorId}
|
||||
* | {@link ASTModifierList EmptyModifierList} {@link ASTVariableDeclaratorId VariableDeclaratorId}
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTLambdaParameter extends AbstractJavaTypeNode
|
||||
implements InternalInterfaces.VariableIdOwner {
|
||||
|
||||
private boolean isFinal;
|
||||
implements InternalInterfaces.VariableIdOwner,
|
||||
FinalizableNode {
|
||||
|
||||
ASTLambdaParameter(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
|
||||
void setFinal(boolean aFinal) {
|
||||
isFinal = aFinal;
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return isFinal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If true, this formal parameter represents one without explicit types.
|
||||
* This can appear as part of a lambda expression with java11 using "var".
|
||||
|
@ -15,14 +15,15 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* LocalVariableDeclaration ::= ( "final" | {@linkplain ASTAnnotation Annotation} )* {@linkplain ASTType Type} {@linkplain ASTVariableDeclarator VariableDeclarator} ( "," {@linkplain ASTVariableDeclarator VariableDeclarator} )*
|
||||
* LocalVariableDeclaration ::= {@link ASTModifierList LocalVarModifierList} {@linkplain ASTType Type} {@linkplain ASTVariableDeclarator VariableDeclarator} ( "," {@linkplain ASTVariableDeclarator VariableDeclarator} )*
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
// TODO extend AbstractStatement
|
||||
public final class ASTLocalVariableDeclaration extends AbstractJavaAccessNode
|
||||
public final class ASTLocalVariableDeclaration extends AbstractJavaNode
|
||||
implements Iterable<ASTVariableDeclaratorId>,
|
||||
ASTStatement,
|
||||
FinalizableNode,
|
||||
InternalInterfaces.MultiVariableIdOwner {
|
||||
|
||||
ASTLocalVariableDeclaration(int id) {
|
||||
@ -40,16 +41,9 @@ public final class ASTLocalVariableDeclaration extends AbstractJavaAccessNode
|
||||
visitor.visit(this, data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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();
|
||||
public Visibility getVisibility() {
|
||||
return Visibility.V_LOCAL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.dfa.DFAGraphMethod;
|
||||
|
||||
|
||||
@ -26,7 +25,7 @@ import net.sourceforge.pmd.lang.dfa.DFAGraphMethod;
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* MethodDeclaration ::= MethodModifier*
|
||||
* MethodDeclaration ::= {@link ASTModifierList ModifierList}
|
||||
* {@link ASTTypeParameters TypeParameters}?
|
||||
* {@link ASTResultType ResultType}
|
||||
* <IDENTIFIER>
|
||||
@ -35,11 +34,6 @@ import net.sourceforge.pmd.lang.dfa.DFAGraphMethod;
|
||||
* {@link ASTThrowsList ThrowsList}?
|
||||
* ({@link ASTBlock Block} | ";" )
|
||||
*
|
||||
*
|
||||
* MethodModifier ::= "public" | "private" | "protected" | "static"
|
||||
* | "final" | "abstract" | "native"
|
||||
* | {@linkplain ASTAnnotation Annotation}
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTMethodDeclaration extends AbstractMethodOrConstructorDeclaration implements DFAGraphMethod {
|
||||
@ -81,67 +75,10 @@ public final class ASTMethodDeclaration extends AbstractMethodOrConstructorDecla
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this method is explicitly modified by
|
||||
* the {@code public} modifier.
|
||||
*/
|
||||
public boolean isSyntacticallyPublic() {
|
||||
return super.isPublic();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this method is explicitly modified by
|
||||
* the {@code abstract} modifier.
|
||||
*/
|
||||
public boolean isSyntacticallyAbstract() {
|
||||
return super.isAbstract();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this method has public visibility.
|
||||
* Non-private interface members are implicitly public,
|
||||
* whether they declare the {@code public} modifier or
|
||||
* not.
|
||||
*/
|
||||
@Override
|
||||
public boolean isPublic() {
|
||||
// interface methods are public by default, but could be private since java9
|
||||
return isInterfaceMember() && !isPrivate() || super.isPublic();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this method is abstract, so doesn't
|
||||
* declare a body. Interface members are
|
||||
* implicitly abstract, whether they declare the
|
||||
* {@code abstract} modifier or not. Default interface
|
||||
* methods are not abstract though, consistently with the
|
||||
* standard reflection API.
|
||||
*/
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return isInterfaceMember() && !isDefault() || super.isAbstract();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this method declaration is a member of an interface type.
|
||||
*/
|
||||
public boolean isInterfaceMember() {
|
||||
// for a real class/interface the 3rd parent is a ClassOrInterfaceDeclaration,
|
||||
// for anonymous classes, the parent is e.g. a AllocationExpression
|
||||
Node potentialTypeDeclaration = getNthParent(3);
|
||||
|
||||
return potentialTypeDeclaration instanceof ASTClassOrInterfaceDeclaration
|
||||
&& ((ASTClassOrInterfaceDeclaration) potentialTypeDeclaration).isInterface()
|
||||
|| potentialTypeDeclaration instanceof ASTAnnotationTypeDeclaration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the result type of this method is {@code void}.
|
||||
*
|
||||
* TODO remove, just as simple to write getResultType().isVoid()
|
||||
*/
|
||||
public boolean isVoid() {
|
||||
return getResultType().isVoid();
|
||||
|
@ -26,7 +26,7 @@ import net.sourceforge.pmd.lang.java.qname.JavaOperationQualifiedName;
|
||||
* @see MethodLikeNode
|
||||
* @since 5.8.1
|
||||
*/
|
||||
public interface ASTMethodOrConstructorDeclaration extends MethodLikeNode, SignedNode<ASTMethodOrConstructorDeclaration> {
|
||||
public interface ASTMethodOrConstructorDeclaration extends MethodLikeNode, AccessNode, SignedNode<ASTMethodOrConstructorDeclaration> {
|
||||
|
||||
|
||||
/**
|
||||
@ -41,6 +41,21 @@ public interface ASTMethodOrConstructorDeclaration extends MethodLikeNode, Signe
|
||||
JavaOperationSignature getSignature();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this method is abstract, so doesn't
|
||||
* declare a body. Interface members are
|
||||
* implicitly abstract, whether they declare the
|
||||
* {@code abstract} modifier or not. Default interface
|
||||
* methods are not abstract though, consistently with the
|
||||
* standard reflection API.
|
||||
*/
|
||||
// TODO is this relevant?
|
||||
@Override
|
||||
default boolean isAbstract() {
|
||||
return hasModifiers(JModifier.ABSTRACT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the formal parameters node of this method or constructor.
|
||||
*/
|
||||
|
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import static net.sourceforge.pmd.lang.java.ast.JModifier.ABSTRACT;
|
||||
import static net.sourceforge.pmd.lang.java.ast.JModifier.DEFAULT;
|
||||
import static net.sourceforge.pmd.lang.java.ast.JModifier.FINAL;
|
||||
import static net.sourceforge.pmd.lang.java.ast.JModifier.PRIVATE;
|
||||
import static net.sourceforge.pmd.lang.java.ast.JModifier.PUBLIC;
|
||||
import static net.sourceforge.pmd.lang.java.ast.JModifier.STATIC;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* List of modifiers of a declaration.
|
||||
*
|
||||
* <p>This class keeps track of two modifier sets: the {@linkplain #getExplicitModifiers() explicit}
|
||||
* one, which is the modifiers that appeared in the source, and the
|
||||
* {@linkplain #getEffectiveModifiers() effective} one, which includes
|
||||
* modifiers implicitly given by the context of the node.
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
*
|
||||
*
|
||||
* ModifierList ::= Modifier*
|
||||
*
|
||||
* Modifier ::= "public" | "private" | "protected"
|
||||
* | "final" | "abstract" | "static" | "strictfp"
|
||||
* | "synchronized" | "native" | "default"
|
||||
* | "volatile" | "transient"
|
||||
* | {@linkplain ASTAnnotation Annotation}
|
||||
*
|
||||
*
|
||||
* LocalVarModifierList ::= ( "final" | {@link ASTAnnotation Annotation} )*
|
||||
*
|
||||
* AnnotationList ::= {@link ASTAnnotation Annotation}*
|
||||
*
|
||||
* EmptyModifierList ::= ()
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public final class ASTModifierList extends AbstractJavaNode {
|
||||
|
||||
/** Might as well share it. */
|
||||
static final Set<JModifier> JUST_FINAL = Collections.singleton(FINAL);
|
||||
|
||||
private Set<JModifier> explicitModifiers;
|
||||
private Set<JModifier> effectiveModifiers;
|
||||
|
||||
|
||||
ASTModifierList(int id) {
|
||||
super(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);
|
||||
}
|
||||
|
||||
|
||||
void setDeclaredModifiers(Set<JModifier> explicit) {
|
||||
this.explicitModifiers = explicit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of modifiers written out in the source explicitly.
|
||||
* The returned set is unmodifiable.
|
||||
*/
|
||||
public Set<JModifier> getExplicitModifiers() {
|
||||
assert explicitModifiers != null : "Parser should have set the explicit modifiers";
|
||||
return Collections.unmodifiableSet(explicitModifiers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@linkplain #getExplicitModifiers() declared modifiers},
|
||||
* plus the modifiers that are implicitly bestowed by the context or
|
||||
* the type of this declaration. E.g. an interface is implicitly abstract,
|
||||
* while an interface field is implicitly static.
|
||||
* The returned set is unmodifiable.
|
||||
*/
|
||||
public Set<JModifier> getEffectiveModifiers() {
|
||||
assert explicitModifiers != null : "Parser should have set the explicit modifiers";
|
||||
|
||||
if (effectiveModifiers == null) {
|
||||
|
||||
EnumSet<JModifier> mods =
|
||||
explicitModifiers.isEmpty()
|
||||
? EnumSet.noneOf(JModifier.class)
|
||||
: EnumSet.copyOf(explicitModifiers);
|
||||
|
||||
getOwner().jjtAccept(EffectiveModifierVisitor.INSTANCE, mods);
|
||||
|
||||
this.effectiveModifiers = Collections.unmodifiableSet(mods);
|
||||
|
||||
}
|
||||
|
||||
return effectiveModifiers;
|
||||
}
|
||||
|
||||
public JavaNode getOwner() {
|
||||
return getParent(); // TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the effective modifiers contain all of the mentioned
|
||||
* modifiers.
|
||||
*
|
||||
* @param mod1 First mod
|
||||
* @param mods Other mods
|
||||
*/
|
||||
public boolean hasAll(JModifier mod1, JModifier... mods) {
|
||||
Set<JModifier> actual = getEffectiveModifiers();
|
||||
return actual.contains(mod1) && (mods.length == 0 || actual.containsAll(Arrays.asList(mods)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the explicit modifiers contain all of the mentioned
|
||||
* modifiers.
|
||||
*
|
||||
* @param mod1 First mod
|
||||
* @param mods Other mods
|
||||
*/
|
||||
public boolean hasAllExplicitly(JModifier mod1, JModifier... mods) {
|
||||
Set<JModifier> actual = getExplicitModifiers();
|
||||
return actual.contains(mod1) && (mods.length == 0 || actual.containsAll(Arrays.asList(mods)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the effective modifiers contain any of the mentioned
|
||||
* modifiers.
|
||||
*
|
||||
* @param mod1 First mod
|
||||
* @param mods Other mods
|
||||
*/
|
||||
public boolean hasAny(JModifier mod1, JModifier... mods) {
|
||||
Set<JModifier> actual = getEffectiveModifiers();
|
||||
return actual.contains(mod1) || Arrays.stream(mods).anyMatch(actual::contains);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the explicit modifiers contain any of the mentioned
|
||||
* modifiers.
|
||||
*
|
||||
* @param mod1 First mod
|
||||
* @param mods Other mods
|
||||
*/
|
||||
public boolean hasAnyExplicitly(JModifier mod1, JModifier... mods) {
|
||||
Set<JModifier> actual = getExplicitModifiers();
|
||||
return actual.contains(mod1) || Arrays.stream(mods).anyMatch(actual::contains);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates effective modifiers from the declared ones.
|
||||
*/
|
||||
private static class EffectiveModifierVisitor extends SideEffectingVisitorAdapter<Set<JModifier>> {
|
||||
|
||||
|
||||
private static final EffectiveModifierVisitor INSTANCE = new EffectiveModifierVisitor();
|
||||
|
||||
// TODO strictfp modifier is also implicitly given to descendants
|
||||
|
||||
@Override
|
||||
public void visit(ASTAnyTypeDeclaration node, Set<JModifier> effective) {
|
||||
|
||||
if (node.getEnclosingType().isInterface()) {
|
||||
effective.add(PUBLIC);
|
||||
effective.add(STATIC);
|
||||
}
|
||||
|
||||
if (node.isInterface() || node.isAnnotation()) {
|
||||
effective.add(ABSTRACT);
|
||||
if (!node.isTopLevel()) {
|
||||
effective.add(STATIC);
|
||||
}
|
||||
} else if (node instanceof ASTEnumDeclaration && !node.isTopLevel()) {
|
||||
effective.add(STATIC);
|
||||
}
|
||||
|
||||
if (node instanceof ASTEnumDeclaration
|
||||
&& node.getEnumConstants().none(ASTEnumConstant::isAnonymousClass)) {
|
||||
effective.add(FINAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(ASTFieldDeclaration node, Set<JModifier> effective) {
|
||||
if (node.getEnclosingType().isInterface()) {
|
||||
effective.add(PUBLIC);
|
||||
effective.add(STATIC);
|
||||
effective.add(FINAL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ASTLocalVariableDeclaration node, Set<JModifier> effective) {
|
||||
// resources are implicitly final
|
||||
if (node.getParent() instanceof ASTResource) {
|
||||
effective.add(FINAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(ASTEnumConstant node, Set<JModifier> effective) {
|
||||
effective.add(PUBLIC);
|
||||
effective.add(STATIC);
|
||||
effective.add(FINAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ASTAnonymousClassDeclaration node, Set<JModifier> effective) {
|
||||
// TODO add static modifier in static context
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ASTMethodDeclaration node, Set<JModifier> effective) {
|
||||
|
||||
if (node.getEnclosingType().isInterface()) {
|
||||
|
||||
Set<JModifier> declared = node.getModifiers().explicitModifiers;
|
||||
|
||||
if (!declared.contains(PRIVATE)) {
|
||||
effective.add(PUBLIC);
|
||||
}
|
||||
if (!declared.contains(DEFAULT) && !declared.contains(STATIC)) {
|
||||
effective.add(ABSTRACT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* PackageDeclaration ::= "package" Name ";"
|
||||
* PackageDeclaration ::= {@link ASTModifierList AnnotationList} "package" Name ";"
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -5,6 +5,8 @@
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
@ -28,6 +30,10 @@ public final class ASTTypeParameter extends AbstractJavaTypeNode implements Anno
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ASTAnnotation> getDeclaredAnnotations() {
|
||||
return children(ASTAnnotation.class).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the type variable introduced by this declaration.
|
||||
|
@ -43,7 +43,7 @@ import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
|
||||
*
|
||||
*/
|
||||
// @formatter:on
|
||||
public final class ASTVariableDeclaratorId extends AbstractJavaTypeNode {
|
||||
public final class ASTVariableDeclaratorId extends AbstractJavaTypeNode implements AccessNode {
|
||||
|
||||
private VariableNameDeclaration nameDeclaration;
|
||||
|
||||
@ -90,6 +90,19 @@ public final class ASTVariableDeclaratorId extends AbstractJavaTypeNode {
|
||||
return children(ASTArrayDimensions.class).first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTModifierList getModifiers() {
|
||||
// delegates modifiers
|
||||
return getModifierOwnerParent().getModifiers();
|
||||
}
|
||||
|
||||
private AccessNode getModifierOwnerParent() {
|
||||
JavaNode parent = getParent();
|
||||
if (parent instanceof ASTVariableDeclarator) {
|
||||
return (AccessNode) parent.getParent();
|
||||
}
|
||||
return (AccessNode) parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the declared variable has an array type.
|
||||
@ -163,6 +176,7 @@ public final class ASTVariableDeclaratorId extends AbstractJavaTypeNode {
|
||||
* Doesn't account for the "effectively-final" nuance. Resource
|
||||
* declarations are implicitly final.
|
||||
*/
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
if (isResourceDeclaration()) {
|
||||
// this is implicit even if "final" is not explicitly declared.
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.qname.JavaTypeQualifiedName;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
|
||||
|
||||
@ -12,9 +11,10 @@ import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefin
|
||||
/**
|
||||
* Abstract class for type declarations nodes.
|
||||
*/
|
||||
abstract class AbstractAnyTypeDeclaration extends AbstractJavaAccessTypeNode implements ASTAnyTypeDeclaration, LeftRecursiveNode {
|
||||
abstract class AbstractAnyTypeDeclaration extends AbstractJavaNode implements ASTAnyTypeDeclaration, LeftRecursiveNode {
|
||||
|
||||
private JavaTypeQualifiedName qualifiedName;
|
||||
private JavaTypeDefinition typeDefinition;
|
||||
|
||||
|
||||
AbstractAnyTypeDeclaration(int i) {
|
||||
@ -33,53 +33,8 @@ abstract class AbstractAnyTypeDeclaration extends AbstractJavaAccessTypeNode imp
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSimpleName() {
|
||||
return getImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFindBoundary() {
|
||||
return isNested() || isLocal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the enclosing type of this type declaration
|
||||
* is any of the given kinds. If this declaration is a top-level
|
||||
* declaration, returns false. This won't consider anonymous classes
|
||||
* until #905 is tackled. TODO 7.0.0
|
||||
*
|
||||
* @param kinds Kinds to test
|
||||
*/
|
||||
// TODO 7.0.0 move that up to ASTAnyTypeDeclaration
|
||||
public final boolean enclosingTypeIsA(TypeKind... kinds) {
|
||||
|
||||
ASTAnyTypeDeclaration parent = getEnclosingTypeDeclaration();
|
||||
if (parent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TypeKind k : kinds) {
|
||||
if (parent.getTypeKind() == k) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the enclosing type of this type, if it is nested.
|
||||
* Otherwise returns null. This won't consider anonymous classes
|
||||
* until #905 is tackled. TODO 7.0.0
|
||||
*/
|
||||
public final ASTAnyTypeDeclaration getEnclosingTypeDeclaration() {
|
||||
if (!isNested()) {
|
||||
return null;
|
||||
}
|
||||
Node parent = getNthParent(3);
|
||||
|
||||
return parent instanceof ASTAnyTypeDeclaration ? (ASTAnyTypeDeclaration) parent : null;
|
||||
public Visibility getVisibility() {
|
||||
return isLocal() ? Visibility.V_LOCAL : ASTAnyTypeDeclaration.super.getVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,5 +46,14 @@ abstract class AbstractAnyTypeDeclaration extends AbstractJavaAccessTypeNode imp
|
||||
this.qualifiedName = qualifiedName;
|
||||
this.typeDefinition = JavaTypeDefinition.forClass(qualifiedName.getType());
|
||||
}
|
||||
|
||||
void setTypeDefinition(JavaTypeDefinition typeDefinition) {
|
||||
this.typeDefinition = typeDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDefinition getTypeDefinition() {
|
||||
return typeDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,114 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
abstract class AbstractJavaAccessNode extends AbstractJavaNode implements AccessNode {
|
||||
|
||||
private int modifiers;
|
||||
|
||||
AbstractJavaAccessNode(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModifiers() {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
void setModifiers(int modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPublic() {
|
||||
return isModifier(PUBLIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtected() {
|
||||
return isModifier(PROTECTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivate() {
|
||||
return isModifier(PRIVATE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return isModifier(ABSTRACT);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return isModifier(STATIC);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return isModifier(FINAL);
|
||||
}
|
||||
|
||||
void setFinal(boolean enable) {
|
||||
setModifier(enable, FINAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSynchronized() {
|
||||
return isModifier(SYNCHRONIZED);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isNative() {
|
||||
return isModifier(NATIVE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isTransient() {
|
||||
return isModifier(TRANSIENT);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isVolatile() {
|
||||
return isModifier(VOLATILE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isStrictfp() {
|
||||
return isModifier(STRICTFP);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDefault() {
|
||||
return isModifier(DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
private boolean isModifier(int mask) {
|
||||
return (modifiers & mask) == mask;
|
||||
}
|
||||
|
||||
void setModifier(boolean enable, int mask) {
|
||||
if (enable) {
|
||||
this.modifiers |= mask;
|
||||
} else {
|
||||
this.modifiers &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackagePrivate() {
|
||||
return !isPrivate() && !isPublic() && !isProtected();
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
|
||||
|
||||
abstract class AbstractJavaAccessTypeNode extends AbstractJavaAccessNode implements TypeNode {
|
||||
|
||||
/**
|
||||
* Type definition, used to get the type of the node.
|
||||
*/
|
||||
protected JavaTypeDefinition typeDefinition;
|
||||
|
||||
AbstractJavaAccessTypeNode(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType() {
|
||||
if (typeDefinition != null) {
|
||||
return typeDefinition.getType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDefinition getTypeDefinition() {
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
void setTypeDefinition(JavaTypeDefinition typeDefinition) {
|
||||
this.typeDefinition = typeDefinition;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.qname.JavaOperationQualifiedName;
|
||||
|
||||
abstract class AbstractMethodLikeNode extends AbstractJavaAccessNode implements MethodLikeNode {
|
||||
|
||||
private JavaOperationQualifiedName qualifiedName;
|
||||
|
||||
|
||||
AbstractMethodLikeNode(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
|
||||
void setQualifiedName(JavaOperationQualifiedName qualifiedName) {
|
||||
this.qualifiedName = qualifiedName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public JavaOperationQualifiedName getQualifiedName() {
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
}
|
@ -5,12 +5,13 @@
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.multifile.signature.JavaOperationSignature;
|
||||
import net.sourceforge.pmd.lang.java.qname.JavaOperationQualifiedName;
|
||||
|
||||
|
||||
abstract class AbstractMethodOrConstructorDeclaration extends AbstractMethodLikeNode implements ASTMethodOrConstructorDeclaration, LeftRecursiveNode {
|
||||
abstract class AbstractMethodOrConstructorDeclaration extends AbstractJavaNode implements ASTMethodOrConstructorDeclaration, LeftRecursiveNode, AccessNode {
|
||||
|
||||
private JavaOperationSignature signature;
|
||||
|
||||
private JavaOperationQualifiedName qualifiedName;
|
||||
|
||||
AbstractMethodOrConstructorDeclaration(int i) {
|
||||
super(i);
|
||||
@ -25,4 +26,17 @@ abstract class AbstractMethodOrConstructorDeclaration extends AbstractMethodLike
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
|
||||
void setQualifiedName(JavaOperationQualifiedName qualifiedName) {
|
||||
this.qualifiedName = qualifiedName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public JavaOperationQualifiedName getQualifiedName() {
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,70 +1,250 @@
|
||||
/**
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import static net.sourceforge.pmd.lang.java.ast.JModifier.STRICTFP;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* This interface captures Java access modifiers.
|
||||
* A node that owns a {@linkplain ASTModifierList modifier list}.
|
||||
*
|
||||
* <p>{@link AccessNode} methods take into account the syntactic context of the
|
||||
* declaration, e.g. {@link #isPublic()} will always return true for a field
|
||||
* declared inside an interface, regardless of whether the {@code public}
|
||||
* modifier was specified explicitly or not. If you want to know whether
|
||||
* the modifier was explicitly stated, use {@link #hasExplicitModifiers(JModifier, JModifier...)}.
|
||||
*
|
||||
* TODO make modifiers accessible from XPath
|
||||
* * Ideally we'd have two attributes, eg @EffectiveModifiers and @ExplicitModifiers,
|
||||
* which would each return a sequence, eg ("public", "static", "final")
|
||||
* * Ideally we'd have a way to add attributes that are not necessarily
|
||||
* getters on the node. It makes no sense in the Java API to expose
|
||||
* those getters on the node, it's more orthogonal to query getModifiers() directly.
|
||||
*
|
||||
* TODO rename to ModifierOwner, kept out from PR to reduce diff
|
||||
*/
|
||||
public interface AccessNode extends Annotatable {
|
||||
|
||||
int PUBLIC = 0x0001;
|
||||
int PROTECTED = 0x0002;
|
||||
int PRIVATE = 0x0004;
|
||||
int ABSTRACT = 0x0008;
|
||||
int STATIC = 0x0010;
|
||||
int FINAL = 0x0020;
|
||||
int SYNCHRONIZED = 0x0040;
|
||||
int NATIVE = 0x0080;
|
||||
int TRANSIENT = 0x0100;
|
||||
int VOLATILE = 0x0200;
|
||||
int STRICTFP = 0x1000;
|
||||
int DEFAULT = 0x2000;
|
||||
|
||||
@Override
|
||||
default List<ASTAnnotation> getDeclaredAnnotations() {
|
||||
return getModifiers().children(ASTAnnotation.class).toList();
|
||||
}
|
||||
|
||||
|
||||
int getModifiers();
|
||||
/**
|
||||
* Returns the node representing the modifier list of this node.
|
||||
*/
|
||||
@NonNull
|
||||
default ASTModifierList getModifiers() {
|
||||
return children(ASTModifierList.class).firstOrThrow();
|
||||
}
|
||||
|
||||
|
||||
boolean isPublic();
|
||||
/**
|
||||
* Returns the visibility corresponding to the {@link ASTModifierList#getEffectiveModifiers() effective modifiers}.
|
||||
* Eg a public method will have visibility {@link Visibility#V_PUBLIC public},
|
||||
* a local class will have visibility {@link Visibility#V_LOCAL local}.
|
||||
* There cannot be any conflict with {@link #hasModifiers(JModifier, JModifier...)}} on
|
||||
* well-formed code (e.g. for any {@code n}, {@code (n.getVisibility() == V_PROTECTED) ==
|
||||
* n.hasModifiers(PROTECTED)})
|
||||
*
|
||||
* <p>TODO a public method of a private class can be considered to be private
|
||||
* we could probably add another method later on that takes this into account
|
||||
*/
|
||||
default Visibility getVisibility() {
|
||||
Set<JModifier> effective = getModifiers().getEffectiveModifiers();
|
||||
if (effective.contains(JModifier.PUBLIC)) {
|
||||
return Visibility.V_PUBLIC;
|
||||
} else if (effective.contains(JModifier.PROTECTED)) {
|
||||
return Visibility.V_PROTECTED;
|
||||
} else if (effective.contains(JModifier.PRIVATE)) {
|
||||
return Visibility.V_PRIVATE;
|
||||
} else {
|
||||
return Visibility.V_PACKAGE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean isProtected();
|
||||
/**
|
||||
* Returns true if this node has <i>all</i> the given modifiers
|
||||
* either explicitly written or inferred through context.
|
||||
*/
|
||||
default boolean hasModifiers(JModifier mod1, JModifier... mod) {
|
||||
return getModifiers().hasAll(mod1, mod);
|
||||
}
|
||||
|
||||
|
||||
boolean isPrivate();
|
||||
/**
|
||||
* Returns true if this node has <i>all</i> the given modifiers
|
||||
* explicitly written in the source.
|
||||
*/
|
||||
default boolean hasExplicitModifiers(JModifier mod1, JModifier... mod) {
|
||||
return getModifiers().hasAllExplicitly(mod1, mod);
|
||||
}
|
||||
|
||||
|
||||
boolean isAbstract();
|
||||
// TODO remove all those, kept only for compatibility with rules
|
||||
|
||||
// these are about effective modifiers
|
||||
|
||||
|
||||
|
||||
boolean isStatic();
|
||||
@Deprecated
|
||||
default boolean isFinal() {
|
||||
return hasModifiers(JModifier.FINAL);
|
||||
}
|
||||
|
||||
|
||||
boolean isFinal();
|
||||
@Deprecated
|
||||
default boolean isAbstract() {
|
||||
return hasModifiers(JModifier.ABSTRACT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean isSynchronized();
|
||||
@Deprecated
|
||||
default boolean isStrictfp() {
|
||||
return hasModifiers(STRICTFP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean isNative();
|
||||
@Deprecated
|
||||
default boolean isSynchronized() {
|
||||
return hasModifiers(JModifier.SYNCHRONIZED);
|
||||
}
|
||||
|
||||
|
||||
boolean isTransient();
|
||||
@Deprecated
|
||||
default boolean isNative() {
|
||||
return hasModifiers(JModifier.NATIVE);
|
||||
}
|
||||
|
||||
|
||||
boolean isVolatile();
|
||||
@Deprecated
|
||||
default boolean isStatic() {
|
||||
return hasModifiers(JModifier.STATIC);
|
||||
}
|
||||
|
||||
|
||||
boolean isStrictfp();
|
||||
@Deprecated
|
||||
default boolean isVolatile() {
|
||||
return hasModifiers(JModifier.VOLATILE);
|
||||
}
|
||||
|
||||
|
||||
boolean isPackagePrivate();
|
||||
@Deprecated
|
||||
default boolean isTransient() {
|
||||
return hasModifiers(JModifier.TRANSIENT);
|
||||
}
|
||||
|
||||
|
||||
boolean isDefault();
|
||||
// these are about visibility
|
||||
|
||||
|
||||
@Deprecated
|
||||
default boolean isPrivate() {
|
||||
return getVisibility() == Visibility.V_PRIVATE;
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
default boolean isPublic() {
|
||||
return getVisibility() == Visibility.V_PUBLIC;
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
default boolean isProtected() {
|
||||
return getVisibility() == Visibility.V_PROTECTED;
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
default boolean isPackagePrivate() {
|
||||
return getVisibility() == Visibility.V_PACKAGE;
|
||||
}
|
||||
|
||||
// these are about explicit modifiers
|
||||
|
||||
|
||||
@Deprecated
|
||||
default boolean isSyntacticallyAbstract() {
|
||||
return hasExplicitModifiers(JModifier.ABSTRACT);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
default boolean isSyntacticallyPublic() {
|
||||
return hasExplicitModifiers(JModifier.PUBLIC);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
default boolean isSyntacticallyStatic() {
|
||||
return hasExplicitModifiers(JModifier.STATIC);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
default boolean isSyntacticallyFinal() {
|
||||
return hasExplicitModifiers(JModifier.FINAL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Represents the visibility of a declaration.
|
||||
*
|
||||
* <p>The ordering of the constants encodes a "contains" relationship,
|
||||
* ie, given two visibilities {@code v1} and {@code v2}, {@code v1 < v2}
|
||||
* means that {@code v2} is strictly more permissive than {@code v1}.
|
||||
*/
|
||||
enum Visibility {
|
||||
// Note: constants are prefixed with "V_" to avoid conflicts with JModifier
|
||||
|
||||
/** Special visibility of anonymous classes, even more restricted than local. */
|
||||
V_ANONYMOUS("anonymous"),
|
||||
/** Confined to a local scope, eg method parameters, local variables, local classes. */
|
||||
V_LOCAL("local"),
|
||||
/** File-private. Corresponds to modifier {@link JModifier#PRIVATE}. */
|
||||
V_PRIVATE("private"),
|
||||
/** Package-private. */
|
||||
V_PACKAGE("package"),
|
||||
/** Package-private + visible to subclasses. Corresponds to modifier {@link JModifier#PROTECTED}. */
|
||||
V_PROTECTED("protected"),
|
||||
/** Visible everywhere. Corresponds to modifier {@link JModifier#PUBLIC}. */
|
||||
V_PUBLIC("public");
|
||||
|
||||
private final String myName;
|
||||
|
||||
Visibility(String name) {
|
||||
this.myName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this visibility is greater than or equal to
|
||||
* the parameter.
|
||||
*/
|
||||
public boolean isAtLeast(Visibility other) {
|
||||
return this.compareTo(other) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this visibility is strictly lower than the
|
||||
* parameter.
|
||||
*/
|
||||
public boolean isAtMost(Visibility other) {
|
||||
return this.compareTo(other) < 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
/**
|
||||
* Package private, though the method is public.
|
||||
*/
|
||||
interface FinalizableNode extends AccessNode {
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this variable, method or class is final (even implicitly).
|
||||
*/
|
||||
@Override
|
||||
default boolean isFinal() {
|
||||
return hasModifiers(JModifier.FINAL);
|
||||
}
|
||||
|
||||
}
|
@ -40,25 +40,23 @@ public final class InternalApiBridge {
|
||||
((AbstractJavaNode) node).comment(comment);
|
||||
}
|
||||
|
||||
public static void setModifier(AccessNode node, int modifier) {
|
||||
((AbstractJavaAccessNode) node).setModifier(true, modifier);
|
||||
}
|
||||
|
||||
public static void setQname(ASTAnyTypeDeclaration declaration, JavaTypeQualifiedName qualifiedName) {
|
||||
((AbstractAnyTypeDeclaration) declaration).setQualifiedName(qualifiedName);
|
||||
}
|
||||
|
||||
public static void setQname(MethodLikeNode node, JavaOperationQualifiedName qualifiedName) {
|
||||
((AbstractMethodLikeNode) node).setQualifiedName(qualifiedName);
|
||||
if (node instanceof ASTLambdaExpression) {
|
||||
((ASTLambdaExpression) node).setQualifiedName(qualifiedName);
|
||||
} else if (node instanceof AbstractMethodOrConstructorDeclaration) {
|
||||
((AbstractMethodOrConstructorDeclaration) node).setQualifiedName(qualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setTypeDefinition(TypeNode node, JavaTypeDefinition definition) {
|
||||
if (node instanceof AbstractJavaTypeNode) {
|
||||
((AbstractJavaTypeNode) node).setTypeDefinition(definition);
|
||||
} else if (node instanceof AbstractJavaAccessTypeNode) {
|
||||
((AbstractJavaAccessTypeNode) node).setTypeDefinition(definition);
|
||||
} else if (node instanceof ASTLambdaExpression) {
|
||||
((ASTLambdaExpression) node).setTypeDefinition(definition);
|
||||
} else if (node instanceof AbstractAnyTypeDeclaration) {
|
||||
((AbstractAnyTypeDeclaration) node).setTypeDefinition(definition);
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user