All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.pmd.lang.java.ast.ModifierOwner Maven / Gradle / Ivy

The newest version!
/*
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 */

package net.sourceforge.pmd.lang.java.ast;

import java.util.Set;

import org.checkerframework.checker.nullness.qual.NonNull;

import net.sourceforge.pmd.lang.ast.NodeStream;

/**
 * A node that owns a {@linkplain ASTModifierList modifier list}.
 *
 * 

{@link ModifierOwner} methods take into account the syntactic context of the * declaration, e.g. {@link #hasModifiers(JModifier, JModifier...) hasModifiers(JModifier.PUBLIC)} * 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...)}. * *

Modifiers are accessible from XPath through the functions {@code pmd:modifiers()} and * {@code pmd:explicitModifiers()}. They return a sequence, e.g. {@code ("public", "static", "final")}. * *

Note: This interface was called AccessNode in PMD 6. * * @see net.sourceforge.pmd.lang.java.rule.xpath.internal.GetModifiersFun */ public interface ModifierOwner extends Annotatable { @Override default NodeStream getDeclaredAnnotations() { return getModifiers().children(ASTAnnotation.class); } /** * Returns the node representing the modifier list of this node. */ default @NonNull ASTModifierList getModifiers() { return firstChild(ASTModifierList.class); } /** * 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)}) * *

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 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; } } /** * Returns the "effective" visibility of a member. This is the minimum * visibility of its enclosing type declarations. For example, a public * method of a private class is "effectively private". * *

Local declarations keep local visibility, eg a local variable * somewhere in an anonymous class doesn't get anonymous visibility. */ default Visibility getEffectiveVisibility() { Visibility minv = getVisibility(); if (minv == Visibility.V_LOCAL) { return minv; } for (ASTTypeDeclaration enclosing : ancestors(ASTTypeDeclaration.class)) { minv = Visibility.min(minv, enclosing.getVisibility()); if (minv == Visibility.V_LOCAL) { return minv; } } return minv; } /** * Returns true if this node has all the given modifiers * either explicitly written or inferred through context. */ default boolean hasModifiers(JModifier mod1, JModifier... mod) { return getModifiers().hasAll(mod1, mod); } /** * Returns true if this node has all the given modifiers * explicitly written in the source. */ default boolean hasExplicitModifiers(JModifier mod1, JModifier... mod) { return getModifiers().hasAllExplicitly(mod1, mod); } /** * Returns true if this node has the given visibility * either explicitly written or inferred through context. * @see #getVisibility() * @see #getEffectiveVisibility() */ default boolean hasVisibility(Visibility visibility) { return getVisibility() == visibility; } /** * Represents the visibility of a declaration. * *

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 lower than or equal to the * parameter. */ public boolean isAtMost(Visibility other) { return this.compareTo(other) <= 0; } /** * The minimum of both visibilities. */ static Visibility min(Visibility v1, Visibility v2) { return v1.compareTo(v2) <= 0 ? v1 : v2; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy