/******************************************************************************* * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.ext.java.jdt.core.dom; import java.util.Iterator; import java.util.List; /** * Abstract base class of all AST nodes that represent body declarations that may appear in the body of some kind of class or * interface declaration, including anonymous class declarations, enumeration declarations, and enumeration constant declarations. * <p> * For JLS2: * <p/> * <pre> * BodyDeclaration: * ClassDeclaration * InterfaceDeclaration * MethodDeclaration * ConstructorDeclaration * FieldDeclaration * Initializer * </pre> * <p/> * For JLS3, a number of new node types were introduced: * <p/> * <pre> * BodyDeclaration: * ClassDeclaration * InterfaceDeclaration * EnumDeclaration * MethodDeclaration * ConstructorDeclaration * FieldDeclaration * Initializer * EnumConstantDeclaration * AnnotationTypeDeclaration * AnnotationTypeMemberDeclaration * </pre> * <p/> * </p> * <p> * All types of body declarations carry modifiers (and annotations), although they differ in which modifiers are allowed. Most * types of body declarations can carry a doc comment; Initializer is the only ones that does not. The source range for body * declarations always includes the doc comment if present. * </p> */ public abstract class BodyDeclaration extends ASTNode { /** The doc comment, or <code>null</code> if none. Defaults to none. */ Javadoc optionalDocComment = null; /** * The modifier flags; bit-wise or of Modifier flags. Defaults to none. Not used in 3.0. * * @since 3.0 - field was moved up from subclasses */ private int modifierFlags = Modifier.NONE; /** * The extended modifiers (element type: {@link IExtendedModifier}). Null in JLS2. Added in JLS3; defaults to an empty list * (see constructor). */ ASTNode.NodeList modifiers = null; /** * Returns structural property descriptor for the "modifiers" property of this node as used in JLS2 (type: {@link Integer}). * * @return the property descriptor */ abstract SimplePropertyDescriptor internalModifiersProperty(); /** * Returns structural property descriptor for the "modifiers" property of this node as used in JLS3 (element type: * {@link IExtendedModifier}). * * @return the property descriptor */ abstract ChildListPropertyDescriptor internalModifiers2Property(); /** * Returns structural property descriptor for the "modifiers" property of this node as used in JLS3 (element type: * {@link IExtendedModifier}). * * @return the property descriptor * @since 3.1 */ public final ChildListPropertyDescriptor getModifiersProperty() { // important: return property for AST.JLS3 return internalModifiers2Property(); } /** * Returns structural property descriptor for the "javadoc" property of this node (child type: {@link Javadoc}). * * @return the property descriptor */ abstract ChildPropertyDescriptor internalJavadocProperty(); /** * Returns structural property descriptor for the "javadoc" property of this node (child type: {@link Javadoc}). * * @return the property descriptor * @since 3.1 */ public final ChildPropertyDescriptor getJavadocProperty() { return internalJavadocProperty(); } /** * Creates and returns a structural property descriptor for the "javadoc" property declared on the given concrete node type * (child type: {@link Javadoc}). * * @return the property descriptor */ static final ChildPropertyDescriptor internalJavadocPropertyFactory(Class<?> nodeClass) { return new ChildPropertyDescriptor(nodeClass, "javadoc", Javadoc.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$ } /** * Creates and returns a structural property descriptor for the "modifiers" property declared on the given concrete node type * (type: {@link Integer}). * * @return the property descriptor */ static final SimplePropertyDescriptor internalModifiersPropertyFactory(Class<?> nodeClass) { return new SimplePropertyDescriptor(nodeClass, "modifiers", int.class, MANDATORY); //$NON-NLS-1$ } /** * Creates and returns a structural property descriptor for the "modifiers" property declared on the given concrete node type * (element type: {@link IExtendedModifier}). * * @return the property descriptor */ static final ChildListPropertyDescriptor internalModifiers2PropertyFactory(Class<?> nodeClass) { return new ChildListPropertyDescriptor(nodeClass, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$ } /** * Creates a new AST node for a body declaration node owned by the given AST. * <p> * N.B. This constructor is package-private. * </p> * * @param ast * the AST that is to own this node */ BodyDeclaration(AST ast) { super(ast); if (ast.apiLevel >= AST.JLS3) { this.modifiers = new ASTNode.NodeList(internalModifiers2Property()); } } /** * Returns the doc comment node. * * @return the doc comment node, or <code>null</code> if none */ public Javadoc getJavadoc() { return this.optionalDocComment; } /** * Sets or clears the doc comment node. * * @param docComment * the doc comment node, or <code>null</code> if none * @throws IllegalArgumentException * if the doc comment string is invalid */ public void setJavadoc(Javadoc docComment) { ChildPropertyDescriptor p = internalJavadocProperty(); ASTNode oldChild = this.optionalDocComment; preReplaceChild(oldChild, docComment, p); this.optionalDocComment = docComment; postReplaceChild(oldChild, docComment, p); } /** * Returns the modifiers explicitly specified on this declaration. * <p> * In the JLS3 API, this method is a convenience method that computes these flags from <code>modifiers()</code>. * </p> * * @return the bit-wise or of <code>Modifier</code> constants * @see Modifier */ public int getModifiers() { // more efficient than checking getAST().API_LEVEL if (this.modifiers == null) { // JLS2 behavior - bona fide property return this.modifierFlags; } else { // JLS3 behavior - convenience method // performance could be improved by caching computed flags // but this would require tracking changes to this.modifiers int computedmodifierFlags = Modifier.NONE; for (Iterator<IExtendedModifier> it = modifiers().iterator(); it.hasNext(); ) { IExtendedModifier x = it.next(); if (x instanceof Modifier) { computedmodifierFlags |= ((Modifier)x).getKeyword().toFlagValue(); } } return computedmodifierFlags; } } /** * Sets the modifiers explicitly specified on this declaration (JLS2 API only). * * @param modifiers * the given modifiers (bit-wise or of <code>Modifier</code> constants) * @throws UnsupportedOperationException * if this operation is used in an AST later than JLS2 * @see Modifier * @deprecated In the JLS3 API, this method is replaced by {@link #modifiers()} which contains a list of a * <code>Modifier</code> nodes. */ public void setModifiers(int modifiers) { internalSetModifiers(modifiers); } /** * Internal synonym for deprecated method. Used to avoid deprecation warnings. * * @since 3.1 */ /* package */ final void internalSetModifiers(int pmodifiers) { // more efficient than just calling supportedOnlyIn2() to check if (this.modifiers != null) { supportedOnlyIn2(); } SimplePropertyDescriptor p = internalModifiersProperty(); preValueChange(p); this.modifierFlags = pmodifiers; postValueChange(p); } /** * Returns the live ordered list of modifiers and annotations of this declaration (added in JLS3 API). * * @return the live list of modifiers and annotations (element type: {@link IExtendedModifier}) * @throws UnsupportedOperationException * if this operation is used in a JLS2 AST */ public List<IExtendedModifier> modifiers() { // more efficient than just calling unsupportedIn2() to check if (this.modifiers == null) { unsupportedIn2(); } return this.modifiers; } /* (omit javadoc for this method) Method declared on ASTNode. */ int memSize() { return BASE_NODE_SIZE + 3 * 4; } }