/*******************************************************************************
 * Copyright (c) 2003, 2005 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.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
 */
public class TypeParameter extends ASTNode {
	
	/**
	 * The "name" structural property of this node type.
	 */
	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.
	 */
	public static final ChildListPropertyDescriptor TYPE_BOUNDS_PROPERTY = 
		new ChildListPropertyDescriptor(TypeParameter.class, "typeBounds", Type.class, 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;
	
	static {
		List propertyList = new ArrayList(3);
		createPropertyList(TypeParameter.class, propertyList);
		addProperty(NAME_PROPERTY, propertyList);
		addProperty(TYPE_BOUNDS_PROPERTY, propertyList);
		PROPERTY_DESCRIPTORS = 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
	 * <code>AST.JLS&ast;</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: <code>Type</code>). 
	 * 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);
	}
	
	/* (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(this.getStartPosition(), this.getLength());
		result.setName((SimpleName) ((ASTNode) getName()).clone(target));
		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: <code>Type</code>)
	 */ 
	public List typeBounds() {
		return this.typeBounds;
	}
	
	/* (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();
	}
}

