blob: 9b587c43dd5751fb9bcb12fe5169178ade212bf5 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
*
* 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
* $Id: FieldAccessSpec.java 23416 2010-02-03 19:59:31Z stephan $
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Fraunhofer FIRST - Initial API and implementation
* Technical University Berlin - Initial API and implementation
**********************************************************************/
package org.eclipse.jdt.core.dom;
import java.util.ArrayList;
import java.util.List;
/**
* NEW for OTDT
*
*
* Represents DOM-ASTNode for callout binding to a field of the corresponding base class (OTJLD ยง3.5),
* which has to handle code from e.g. :
* get value
* set value
* to e.g. :
* get int value
* set String value
*
* This class has following properties:
* modifiers (JLS2) or isSetter (JLS3)
* fieldType,
* name,
* signature
*
* This node can be used only in CalloutMethodDeclaration.
*
* @author jsv
*/
public class FieldAccessSpec extends MethodMappingElement
{
/**
* The "signature" structural property of this node type.
*/
public static final SimplePropertyDescriptor SIGNATURE_PROPERTY =
internalSignaturePropertyFactory(FieldAccessSpec.class);
/**
* The "name" structural property of this node type.
*/
public static final ChildPropertyDescriptor NAME_PROPERTY =
internalNamePropertyFactory(FieldAccessSpec.class);
/**
* The "fieldType" structural property of this node type.
*/
public static final ChildPropertyDescriptor FIELD_TYPE_PROPERTY =
new ChildPropertyDescriptor(FieldAccessSpec.class, "fieldType", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
/**
* A list of property descriptors (element type:
* {@link StructuralPropertyDescriptor}),
* or null if uninitialized.
*/
private static final List PROPERTY_DESCRIPTORS_2_0;
private static final List PROPERTY_DESCRIPTORS_3_0;
static
{
List propertyList = new ArrayList(4);
createPropertyList(FieldAccessSpec.class, propertyList);
addProperty(SIGNATURE_PROPERTY, propertyList);
addProperty(NAME_PROPERTY, propertyList);
addProperty(FIELD_TYPE_PROPERTY, propertyList);
PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
propertyList = new ArrayList(4);
createPropertyList(FieldAccessSpec.class, propertyList);
addProperty(SIGNATURE_PROPERTY, propertyList);
addProperty(NAME_PROPERTY, propertyList);
addProperty(FIELD_TYPE_PROPERTY, propertyList);
PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
}
/**
* Returns a list of structural property descriptors for this node type.
* Clients must not modify the result.
*
* @param apiLevel the API level; one of the AST.JLS* constants
* @return a list of property descriptors (element type:
* {@link StructuralPropertyDescriptor})
*/
public static List propertyDescriptors(int apiLevel)
{
if (apiLevel == AST.JLS2_INTERNAL)
return PROPERTY_DESCRIPTORS_2_0;
else
return PROPERTY_DESCRIPTORS_3_0;
}
boolean isSetter = false;
/**
* The field type.
* JLS2 behevior: lazily initialized; defaults to void.
* Note that this field is ignored for constructor declarations.
*/
private Type _fieldType = null;
FieldAccessSpec(AST ast)
{
super(ast);
}
final List internalStructuralPropertiesForType(int apiLevel)
{
return propertyDescriptors(apiLevel);
}
final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean isGetRequest, boolean value)
{
if (property == SIGNATURE_PROPERTY)
{
if (isGetRequest)
{
return hasSignature();
}
else
{
setSignatureFlag(value);
return false;
}
}
return super.internalGetSetBooleanProperty(property, isGetRequest, value);
}
final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean isGetRequest, ASTNode child)
{
if (property == NAME_PROPERTY)
{
if (isGetRequest)
{
return getName();
}
else
{
setName((SimpleName) child);
return null;
}
}
if (property == FIELD_TYPE_PROPERTY)
{
if (isGetRequest)
{
return getFieldType();
}
else
{
setFieldType((Type) child);
return null;
}
}
// allow default implementation to flag the error
return super.internalGetSetChildProperty(property, isGetRequest, child);
}
SimplePropertyDescriptor internalSignatureProperty() {
return SIGNATURE_PROPERTY;
}
ChildPropertyDescriptor internalNameProperty() {
return NAME_PROPERTY;
}
final int getNodeType0()
{
return FIELD_ACCESS_SPEC;
}
ASTNode clone0(AST target)
{
FieldAccessSpec result = new FieldAccessSpec(target);
result.setSourceRange(this.getStartPosition(), this.getLength());
result.setSignatureFlag(this.hasSignature());
result.setName((SimpleName) this.getName().clone(target));
result.setFieldType(
(Type) ASTNode.copySubtree(target, getFieldType()));
return result;
}
void accept0(ASTVisitor visitor)
{
boolean visitChildren = visitor.visit(this);
if (visitChildren)
{
// visit children in normal left to right reading order
acceptChild(visitor, getFieldType());
acceptChild(visitor, getName());
}
visitor.endVisit(this);
}
final boolean subtreeMatch0(ASTMatcher matcher, Object other)
{
// dispatch to correct overloaded match method
return matcher.match(this, other);
}
int treeSize()
{
return memSize()
+ (this.getName() == null ? 0 : getName().treeSize())
+ (this.getFieldType() == null ? 0 : getFieldType().treeSize());
}
int memSize()
{
return BASE_NODE_SIZE + 3 * 4;
}
/**
* Returns the field type of the field in this FieldAccessSpec,
* exclusive of any extra array dimensions (JLS2 API only).
* This is one of the few places where the void type is meaningful.
* <p>
* Note that this child is not relevant for constructor declarations
* (although, it does still figure in subtree equality comparisons
* and visits), and is devoid of the binding information ordinarily
* available.
* </p>
*
* @return the return type, possibly the void primitive type
*/
public Type getFieldType()
{
if (this._fieldType == null)
{
// lazy init must be thread-safe for readers
synchronized (this)
{
if (this._fieldType == null)
{
preLazyInit();
this._fieldType = this.ast.newPrimitiveType(PrimitiveType.VOID);
postLazyInit(this._fieldType, FIELD_TYPE_PROPERTY);
}
}
}
return this._fieldType;
}
/**
* Sets the field type of the field declared in this FieldAccessSpec
* declaration to the given type, exclusive of any extra array dimensions
* (JLS2 API only). This is one of the few places where the void type is meaningful.
* <p>
* Note that this child is not relevant for constructor declarations
* (although it does still figure in subtree equality comparisons and visits).
* </p>
*
* @param type the new return type, possibly the void primitive type
* @exception IllegalArgumentException if:
* <ul>
* <li>the node belongs to a different AST</li>
* <li>the node already has a parent</li>
* </ul>
*/
public void setFieldType(Type type)
{
if (type == null)
{
throw new IllegalArgumentException();
}
ASTNode oldChild = this._fieldType;
preReplaceChild(oldChild, type, FIELD_TYPE_PROPERTY);
this._fieldType = type;
postReplaceChild(oldChild, type, FIELD_TYPE_PROPERTY);
}
public IVariableBinding resolveBinding() {
return this.ast.getBindingResolver().resolveVariable(this);
}
}