/*******************************************************************************
 * Copyright (c) 2003, 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
 *     Technical University Berlin - extended API and implementation
 *******************************************************************************/

package org.eclipse.jdt.core.dom;

import java.util.ArrayList;
import java.util.List;

/**
 * Type parameter node (added in JLS3 API).
 * <pre>
 * TypeParameter:
 *    TypeVariable [ <b>extends</b> Type { <b>&</b> Type } ]
 * </pre>
 *
 * @since 3.1
 * @noinstantiate This class is not intended to be instantiated by clients.
 */
public class TypeParameter extends ASTNode {

	/**
	 * The "name" structural property of this node type (child type: {@link SimpleName}).
	 */
	public static final ChildPropertyDescriptor NAME_PROPERTY =
		new ChildPropertyDescriptor(TypeParameter.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$

	/**
	 * The "typeBounds" structural property of this node type (element type: {@link Type}).
	 */
	public static final ChildListPropertyDescriptor TYPE_BOUNDS_PROPERTY =
		new ChildListPropertyDescriptor(TypeParameter.class, "typeBounds", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$

//{ObjectTeams: distinguish value parameters and <B base R>:
	public static final SimplePropertyDescriptor VALUE_PARAMETER_PROPERTY =
		new SimplePropertyDescriptor(TypeParameter.class, "valueParameter", boolean.class, MANDATORY); //$NON-NLS-1$
	public static final SimplePropertyDescriptor BASE_BOUND_PROPERTY =
		new SimplePropertyDescriptor(TypeParameter.class, "baseBound", boolean.class, MANDATORY); //$NON-NLS-1$
// SH}

	/**
	 * A list of property descriptors (element type:
	 * {@link StructuralPropertyDescriptor}),
	 * or null if uninitialized.
	 */
	private static final List PROPERTY_DESCRIPTORS;

	static {
		List propertyList = new ArrayList(3);
		createPropertyList(TypeParameter.class, propertyList);
		addProperty(NAME_PROPERTY, propertyList);
		addProperty(TYPE_BOUNDS_PROPERTY, propertyList);
//{ObjectTeams: value parameter:
		addProperty(VALUE_PARAMETER_PROPERTY, propertyList);
// SH}
		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
	}

//{ObjectTeams: value parameter, <B base R>:
	private boolean isValueParameter= false;
	private boolean hasBaseBound= false;
//SH}

	/**
	 * 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
	 * <code>AST.JLS*</code> constants

	 * @return a list of property descriptors (element type:
	 * {@link StructuralPropertyDescriptor})
	 */
	public static List propertyDescriptors(int apiLevel) {
		return PROPERTY_DESCRIPTORS;
	}

	/**
	 * The type variable node; lazily initialized; defaults to an unspecfied,
	 * but legal, name.
	 */
	private SimpleName typeVariableName = null;

	/**
	 * The type bounds (element type: {@link Type}).
	 * Defaults to an empty list.
	 */
	private ASTNode.NodeList typeBounds =
		new ASTNode.NodeList(TYPE_BOUNDS_PROPERTY);

	/**
	 * Creates a new unparented node for a parameterized type owned by the
	 * given AST. By default, an unspecified, but legal, type variable name,
	 * and no type bounds.
	 * <p>
	 * N.B. This constructor is package-private.
	 * </p>
	 *
	 * @param ast the AST that is to own this node
	 */
	TypeParameter(AST ast) {
		super(ast);
	    unsupportedIn2();
	}

	/* (omit javadoc for this method)
	 * Method declared on ASTNode.
	 */
	final List internalStructuralPropertiesForType(int apiLevel) {
		return propertyDescriptors(apiLevel);
	}

	/* (omit javadoc for this method)
	 * Method declared on ASTNode.
	 */
	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
		if (property == NAME_PROPERTY) {
			if (get) {
				return getName();
			} else {
				setName((SimpleName) child);
				return null;
			}
		}
		// allow default implementation to flag the error
		return super.internalGetSetChildProperty(property, get, child);
	}

//{ObjectTeams: value parameter?
	boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
		if (property == VALUE_PARAMETER_PROPERTY) {
			if (get) {
				return isValueParameter();
			} else {
				setIsValueParameter(value);
				return false;
			}
		}
		// allow default implementation to flag the error
		return super.internalGetSetBooleanProperty(property, get, value);
	}
// SH}
	/* (omit javadoc for this method)
	 * Method declared on ASTNode.
	 */
	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
		if (property == TYPE_BOUNDS_PROPERTY) {
			return typeBounds();
		}
		// allow default implementation to flag the error
		return super.internalGetChildListProperty(property);
	}

	/* (omit javadoc for this method)
	 * Method declared on ASTNode.
	 */
	final int getNodeType0() {
		return TYPE_PARAMETER;
	}

	/* (omit javadoc for this method)
	 * Method declared on ASTNode.
	 */
	ASTNode clone0(AST target) {
		TypeParameter result = new TypeParameter(target);
		result.setSourceRange(getStartPosition(), getLength());
		result.setName((SimpleName) ((ASTNode) getName()).clone(target));
//{ObjectTeams: value parameter?
		result.setIsValueParameter(this.isValueParameter());
// SH}
		result.typeBounds().addAll(
			ASTNode.copySubtrees(target, typeBounds()));
		return result;
	}

	/* (omit javadoc for this method)
	 * Method declared on ASTNode.
	 */
	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
		// dispatch to correct overloaded match method
		return matcher.match(this, other);
	}

	/* (omit javadoc for this method)
	 * Method declared on ASTNode.
	 */
	void accept0(ASTVisitor visitor) {
		boolean visitChildren = visitor.visit(this);
		if (visitChildren) {
			// visit children in normal left to right reading order
			acceptChild(visitor, getName());
			acceptChildren(visitor, this.typeBounds);
		}
		visitor.endVisit(this);
	}

	/**
	 * Returns the name of the type variable declared in this type parameter.
	 *
	 * @return the name of the type variable
	 */
	public SimpleName getName() {
		if (this.typeVariableName == null) {
			// lazy init must be thread-safe for readers
			synchronized (this) {
				if (this.typeVariableName == null) {
					preLazyInit();
					this.typeVariableName = new SimpleName(this.ast);
					postLazyInit(this.typeVariableName, NAME_PROPERTY);
				}
			}
		}
		return this.typeVariableName;
	}

	/**
	 * Resolves and returns the binding for this type parameter.
	 * <p>
	 * Note that bindings are generally unavailable unless requested when the
	 * AST is being built.
	 * </p>
	 *
	 * @return the binding, or <code>null</code> if the binding cannot be
	 *    resolved
	 */
	public final ITypeBinding resolveBinding() {
		return this.ast.getBindingResolver().resolveTypeParameter(this);
	}

	/**
	 * Sets the name of the type variable of this type parameter to the given
	 * name.
	 *
	 * @param typeName the new name of this type parameter
	 * @exception IllegalArgumentException if:
	 * <ul>
	 * <li>the node belongs to a different AST</li>
	 * <li>the node already has a parent</li>
	 * </ul>
	 */
	public void setName(SimpleName typeName) {
		if (typeName == null) {
			throw new IllegalArgumentException();
		}
		ASTNode oldChild = this.typeVariableName;
		preReplaceChild(oldChild, typeName, NAME_PROPERTY);
		this.typeVariableName = typeName;
		postReplaceChild(oldChild, typeName, NAME_PROPERTY);
	}

	/**
	 * Returns the live ordered list of type bounds of this type parameter.
	 * For the type parameter to be plausible, there can be at most one
	 * class in the list, and it must be first, and the remaining ones must be
	 * interfaces; the list should not contain primitive types (but array types
	 * and parameterized types are allowed).
	 *
	 * @return the live list of type bounds
	 *    (element type: {@link Type})
	 */
	public List typeBounds() {
		return this.typeBounds;
	}

//{ObjectTeams: value parameters & <B base R>:
	/**
	 * Returns whether this type parameter is a value parameter.
	 */
	public boolean isValueParameter() {
		return this.isValueParameter;
	}

	/**
	 * Sets whether this type parameter is a value parameter.
	 */
	public void setIsValueParameter(boolean isValueParameter) {
		preValueChange(VALUE_PARAMETER_PROPERTY);
		this.isValueParameter= isValueParameter;
		postValueChange(VALUE_PARAMETER_PROPERTY);
	}

	/**
	 * Returns whether this type parameter has a "base" bound.
	 */
	public boolean hasBaseBound() {
		return this.hasBaseBound;
	}

	/**
	 * Sets whether this type parameter has a "base" bound.
	 */
	public void setHasBaseBound(boolean hasBaseBound) {
		preValueChange(BASE_BOUND_PROPERTY);
		this.hasBaseBound = hasBaseBound;
		postValueChange(BASE_BOUND_PROPERTY);
	}
// SH}

	/* (omit javadoc for this method)
	 * Method declared on ASTNode.
	 */
	int memSize() {
		// treat Code as free
		return BASE_NODE_SIZE + 2 * 4;
	}

	/* (omit javadoc for this method)
	 * Method declared on ASTNode.
	 */
	int treeSize() {
		return
			memSize()
			+ (this.typeVariableName == null ? 0 : getName().treeSize())
			+ this.typeBounds.listSize();
	}
}

