1 /*******************************************************************************
2 * Copyright (c) 2004, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.core.dom;
13 import java.util.ArrayList;
14 import java.util.List;
17 * Single member annotation node (added in JLS3 API). The single member annotation
18 * "@foo(bar)" is equivalent to the normal annotation "@foo(value=bar)".
21 * SingleMemberAnnotation:
22 * <b>@</b> TypeName <b>(</b> Expression <b>)</b>
24 * Within annotations, only certain kinds of expressions are meaningful,
25 * including other annotations.
29 * @noinstantiate This class is not intended to be instantiated by clients.
31 public final class SingleMemberAnnotation extends Annotation {
34 * The "typeName" structural property of this node type.
36 public static final ChildPropertyDescriptor TYPE_NAME_PROPERTY =
37 internalTypeNamePropertyFactory(SingleMemberAnnotation.class);
40 * The "value" structural property of this node type.
42 public static final ChildPropertyDescriptor VALUE_PROPERTY =
43 new ChildPropertyDescriptor(SingleMemberAnnotation.class, "value", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
46 * A list of property descriptors (element type:
47 * {@link StructuralPropertyDescriptor}),
48 * or null if uninitialized.
50 private static final List PROPERTY_DESCRIPTORS;
53 List propertyList = new ArrayList(3);
54 createPropertyList(SingleMemberAnnotation.class, propertyList);
55 addProperty(TYPE_NAME_PROPERTY, propertyList);
56 addProperty(VALUE_PROPERTY, propertyList);
57 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
61 * Returns a list of structural property descriptors for this node type.
62 * Clients must not modify the result.
64 * @param apiLevel the API level; one of the AST.JLS* constants
65 * @return a list of property descriptors (element type:
66 * {@link StructuralPropertyDescriptor})
68 public static List propertyDescriptors(int apiLevel) {
69 return PROPERTY_DESCRIPTORS;
73 * The value; lazily initialized; defaults to a unspecified, but legal,
76 private Expression value = null;
79 * Creates a new unparented normal annotation node owned
80 * by the given AST. By default, the annotation has an
81 * unspecified type name and an unspecified value.
83 * N.B. This constructor is package-private.
86 * @param ast the AST that is to own this node
88 SingleMemberAnnotation(AST ast) {
93 /* (omit javadoc for this method)
94 * Method declared on ASTNode.
96 final List internalStructuralPropertiesForType(int apiLevel) {
97 return propertyDescriptors(apiLevel);
100 /* (omit javadoc for this method)
101 * Method declared on ASTNode.
103 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
104 if (property == TYPE_NAME_PROPERTY) {
106 return getTypeName();
108 setTypeName((Name) child);
112 if (property == VALUE_PROPERTY) {
116 setValue((Expression) child);
120 // allow default implementation to flag the error
121 return super.internalGetSetChildProperty(property, get, child);
124 /* (omit javadoc for this method)
125 * Method declared on BodyDeclaration.
127 final ChildPropertyDescriptor internalTypeNameProperty() {
128 return TYPE_NAME_PROPERTY;
131 /* (omit javadoc for this method)
132 * Method declared on ASTNode.
134 final int getNodeType0() {
135 return SINGLE_MEMBER_ANNOTATION;
138 /* (omit javadoc for this method)
139 * Method declared on ASTNode.
141 ASTNode clone0(AST target) {
142 SingleMemberAnnotation result = new SingleMemberAnnotation(target);
143 result.setSourceRange(this.getStartPosition(), this.getLength());
144 result.setTypeName((Name) ASTNode.copySubtree(target, getTypeName()));
145 result.setValue((Expression) ASTNode.copySubtree(target, getValue()));
149 /* (omit javadoc for this method)
150 * Method declared on ASTNode.
152 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
153 // dispatch to correct overloaded match method
154 return matcher.match(this, other);
157 /* (omit javadoc for this method)
158 * Method declared on ASTNode.
160 void accept0(ASTVisitor visitor) {
161 boolean visitChildren = visitor.visit(this);
163 // visit children in normal left to right reading order
164 acceptChild(visitor, getTypeName());
165 acceptChild(visitor, getValue());
167 visitor.endVisit(this);
171 * Returns the value of this annotation.
173 * @return the value node
175 public Expression getValue() {
176 if (this.value == null) {
177 // lazy init must be thread-safe for readers
178 synchronized (this) {
179 if (this.value == null) {
181 this.value = new SimpleName(this.ast);
182 postLazyInit(this.value, VALUE_PROPERTY);
190 * Sets the value of this annotation.
192 * @param value the new value
193 * @exception IllegalArgumentException if:
195 * <li>the node belongs to a different AST</li>
196 * <li>the node already has a parent</li>
197 * <li>a cycle in would be created</li>
200 public void setValue(Expression value) {
202 throw new IllegalArgumentException();
204 ASTNode oldChild = this.value;
205 preReplaceChild(oldChild, value, VALUE_PROPERTY);
207 postReplaceChild(oldChild, value, VALUE_PROPERTY);
210 /* (omit javadoc for this method)
211 * Method declared on ASTNode.
214 return super.memSize() + 1 * 4;
217 /* (omit javadoc for this method)
218 * Method declared on ASTNode.
223 + (this.typeName == null ? 0 : getTypeName().treeSize())
224 + (this.value == null ? 0 : getValue().treeSize());