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

net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration 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 org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken;
import net.sourceforge.pmd.lang.document.FileLocation;
import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol;
import net.sourceforge.pmd.lang.java.types.JMethodSig;
import net.sourceforge.pmd.lang.java.types.TypeSystem;
import net.sourceforge.pmd.lang.java.types.TypeTestUtil;


/**
 * A method declaration, in a class or interface declaration. Since 7.0,
 * this also represents annotation methods. Annotation methods have a
 * much more restricted grammar though, in particular:
 * 
    *
  • They can't declare a {@linkplain #getThrowsList() throws clause} *
  • They can't declare {@linkplain #getTypeParameters() type parameters} *
  • Their {@linkplain #getFormalParameters() formal parameters} must be empty *
  • They can't be declared void *
  • They must be abstract *
* They can however declare a {@link #getDefaultClause() default value}. * *
 *
 * MethodDeclaration ::= {@link ASTModifierList ModifierList}
 *                       {@link ASTTypeParameters TypeParameters}?
 *                       {@link ASTType Type}
 *                       <IDENTIFIER>
 *                       {@link ASTFormalParameters FormalParameters}
 *                       {@link ASTArrayDimensions ArrayDimensions}?
 *                       {@link ASTThrowsList ThrowsList}?
 *                       ({@link ASTBlock Block} | ";" )
 *
 * 
*/ public final class ASTMethodDeclaration extends AbstractExecutableDeclaration { private String name; /** * Populated by {@link OverrideResolutionPass}. */ private JMethodSig overriddenMethod = null; ASTMethodDeclaration(int id) { super(id); } @Override protected R acceptVisitor(JavaVisitor visitor, P data) { return visitor.visit(this, data); } /** * Returns true if this method is overridden. */ public boolean isOverridden() { return overriddenMethod != null; } /** * Returns the signature of the method this method overrides in a * supertype. Note that this method may be implementing several methods * of super-interfaces at once, in that case, an arbitrary one is returned. * *

If the method has an {@link Override} annotation, but we couldn't * resolve any method that is actually implemented, this will return * {@link TypeSystem#UNRESOLVED_METHOD}. */ public JMethodSig getOverriddenMethod() { return overriddenMethod; } void setOverriddenMethod(JMethodSig overriddenMethod) { this.overriddenMethod = overriddenMethod; } @Override public FileLocation getReportLocation() { // the method identifier JavaccToken ident = TokenUtils.nthPrevious(getModifiers().getLastToken(), getFormalParameters().getFirstToken(), 1); return ident.getReportLocation(); } /** Returns the simple name of the method. */ @Override public String getName() { return name; } void setName(String name) { this.name = name; } /** * If this method declaration is an explicit record component accessor, * returns the corresponding record component. Otherwise returns null. */ public @Nullable ASTRecordComponent getAccessedRecordComponent() { if (getArity() != 0) { return null; } ASTRecordComponentList components = getEnclosingType().getRecordComponents(); if (components == null) { return null; } return components.toStream().first(it -> it.getVarId().getName().equals(this.getName())); } /** * Returns true if the result type of this method is {@code void}. */ public boolean isVoid() { return getResultTypeNode().isVoid(); } /** * Returns the default clause, if this is an annotation method declaration * that features one. Otherwise returns null. */ @Nullable public ASTDefaultValue getDefaultClause() { return AstImplUtil.getChildAs(this, getNumChildren() - 1, ASTDefaultValue.class); } /** * Returns the result type node of the method. This may be a {@link ASTVoidType}. */ public @NonNull ASTType getResultTypeNode() { // TODO rename to getResultType() return firstChild(ASTType.class); } /** * Returns the extra array dimensions that may be after the * formal parameters. */ @Nullable public ASTArrayDimensions getExtraDimensions() { return children(ASTArrayDimensions.class).first(); } /** * Returns whether this is a main method declaration. */ public boolean isMainMethod() { return this.hasModifiers(JModifier.PUBLIC, JModifier.STATIC) && "main".equals(this.getName()) && this.isVoid() && this.getArity() == 1 && TypeTestUtil.isExactlyA(String[].class, this.getFormalParameters().get(0)) || isMainMethodInImplicitlyDeclaredClass(); } /** * With JEP 445/463/477 (Java 23 Preview) the main method does not need to be static anymore and * does not need to be public or have a formal parameter. */ private boolean isMainMethodInImplicitlyDeclaredClass() { return this.getRoot().isSimpleCompilationUnit() && "main".equals(this.getName()) && !this.hasModifiers(JModifier.PRIVATE) && this.isVoid() && (this.getArity() == 0 || this.getArity() == 1 && TypeTestUtil.isExactlyA(String[].class, this.getFormalParameters().get(0))); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy