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 *******************************************************************************/
12 package net.sourceforge.phpdt.core.dom;
14 import java.util.ArrayList;
15 import java.util.List;
18 * Member value pair node (added in JLS3 API). Member value pairs appear in annotations.
22 * SimpleName <b>=</b> Expression
24 * Within annotations, only certain kinds of expressions are meaningful,
25 * including other annotations.
28 * @see NormalAnnotation
30 * @noinstantiate This class is not intended to be instantiated by clients.
32 public class MemberValuePair extends ASTNode {
35 * The "name" structural property of this node type.
37 public static final ChildPropertyDescriptor NAME_PROPERTY =
38 new ChildPropertyDescriptor(MemberValuePair.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
41 * The "value" structural property of this node type.
43 public static final ChildPropertyDescriptor VALUE_PROPERTY =
44 new ChildPropertyDescriptor(MemberValuePair.class, "value", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
47 * A list of property descriptors (element type:
48 * {@link StructuralPropertyDescriptor}),
49 * or null if uninitialized.
51 private static final List PROPERTY_DESCRIPTORS;
54 List propertyList = new ArrayList(3);
55 createPropertyList(MemberValuePair.class, propertyList);
56 addProperty(NAME_PROPERTY, propertyList);
57 addProperty(VALUE_PROPERTY, propertyList);
58 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
62 * Returns a list of structural property descriptors for this node type.
63 * Clients must not modify the result.
65 * @param apiLevel the API level; one of the AST.JLS* constants
66 * @return a list of property descriptors (element type:
67 * {@link StructuralPropertyDescriptor})
69 public static List propertyDescriptors(int apiLevel) {
70 return PROPERTY_DESCRIPTORS;
74 * The member name; lazily initialized; defaults to a unspecified,
77 private SimpleName name = null;
80 * The value; lazily initialized; defaults to a unspecified,
83 private Expression value = null;
86 * Creates a new AST node for a member value pair owned by the given
87 * AST. By default, the node has an unspecified (but legal) member
90 * N.B. This constructor is package-private.
93 * @param ast the AST that is to own this node
95 MemberValuePair(AST ast) {
100 /* (omit javadoc for this method)
101 * Method declared on ASTNode.
103 final List internalStructuralPropertiesForType(int apiLevel) {
104 return propertyDescriptors(apiLevel);
107 /* (omit javadoc for this method)
108 * Method declared on ASTNode.
110 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
111 if (property == NAME_PROPERTY) {
115 setName((SimpleName) child);
119 if (property == VALUE_PROPERTY) {
123 setValue((Expression) child);
127 // allow default implementation to flag the error
128 return super.internalGetSetChildProperty(property, get, child);
131 /* (omit javadoc for this method)
132 * Method declared on ASTNode.
134 final int getNodeType0() {
135 return MEMBER_VALUE_PAIR;
138 /* (omit javadoc for this method)
139 * Method declared on ASTNode.
141 ASTNode clone0(AST target) {
142 MemberValuePair result = new MemberValuePair(target);
143 result.setSourceRange(this.getStartPosition(), this.getLength());
144 result.setName((SimpleName) ASTNode.copySubtree(target, getName()));
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, getName());
165 acceptChild(visitor, getValue());
167 visitor.endVisit(this);
171 * Returns the member name.
173 * @return the member name node
175 public SimpleName getName() {
176 if (this.name == null) {
177 // lazy init must be thread-safe for readers
178 synchronized (this) {
179 if (this.name == null) {
181 this.name = new SimpleName(this.ast);
182 postLazyInit(this.name, NAME_PROPERTY);
190 * Resolves and returns the member value pair binding for this member value pair.
192 * Note that bindings are generally unavailable unless requested when the
193 * AST is being built.
196 * @return the binding, or <code>null</code> if the binding cannot be
200 public final IMemberValuePairBinding resolveMemberValuePairBinding() {
201 return this.ast.getBindingResolver().resolveMemberValuePair(this);
205 * Sets the member name.
207 * @param name the member name node
208 * @exception IllegalArgumentException if:
210 * <li>the node belongs to a different AST</li>
211 * <li>the node already has a parent</li>
214 public void setName(SimpleName name) {
216 throw new IllegalArgumentException();
218 ASTNode oldChild = this.name;
219 preReplaceChild(oldChild, name, NAME_PROPERTY);
221 postReplaceChild(oldChild, name, NAME_PROPERTY);
225 * Returns the value expression.
227 * @return the value expression
229 public Expression getValue() {
230 if (this.value == null) {
231 // lazy init must be thread-safe for readers
232 synchronized (this) {
233 if (this.value == null) {
235 this.value= new SimpleName(this.ast);
236 postLazyInit(this.value, VALUE_PROPERTY);
244 * Sets the value of this pair.
246 * @param value the new value
247 * @exception IllegalArgumentException if:
249 * <li>the node belongs to a different AST</li>
250 * <li>the node already has a parent</li>
251 * <li>a cycle in would be created</li>
254 public void setValue(Expression value) {
256 throw new IllegalArgumentException();
258 ASTNode oldChild = this.value;
259 preReplaceChild(oldChild, value, VALUE_PROPERTY);
261 postReplaceChild(oldChild, value, VALUE_PROPERTY);
264 /* (omit javadoc for this method)
265 * Method declared on ASTNode.
268 return BASE_NODE_SIZE + 2 * 4;
271 /* (omit javadoc for this method)
272 * Method declared on ASTNode.
277 + (this.name == null ? 0 : getName().treeSize())
278 + (this.value == null ? 0 : getValue().treeSize());