/**
* Copyright (c) 2006-2007 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 - Initial API and implementation
*/
package org.eclipse.emf.codegen.merge.java.facade.ast;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.emf.codegen.merge.java.facade.JMethod;
/**
* Wraps {@link MethodDeclaration} object.
*
* @since 2.2.0
*/
public class ASTJMethod extends ASTJMember<MethodDeclaration> implements JMethod
{
protected String returnType = UNITIALIZED_STRING;
protected String[] typeParameters = EMPTY_STRING_ARRAY;
protected String[] parameterNames = EMPTY_STRING_ARRAY;
protected String[] parameters = EMPTY_STRING_ARRAY;
/**
* Array of cached exceptions. Current exceptions is a combination of
* this array and {@link #addedExceptions}.
*/
protected String[] exceptions = EMPTY_STRING_ARRAY;
/**
* List of added exceptions by calling {@link #addException(String)}.
* This list does not include existing exceptions, nor exceptions set by {@link #setExceptions(String[])}
*/
protected List<String> addedExceptions = null;
protected String body = UNITIALIZED_STRING;
/**
* @param methodDeclaration
*/
public ASTJMethod(MethodDeclaration methodDeclaration)
{
super(methodDeclaration);
}
@Override
public void dispose()
{
returnType = null;
typeParameters = null;
parameterNames = null;
parameters = null;
exceptions = null;
body = null;
if (addedExceptions != null)
{
addedExceptions.clear();
addedExceptions = null;
}
super.dispose();
}
public boolean isConstructor()
{
// always returns original value
return getASTNode().isConstructor();
}
public String getName()
{
if (name == UNITIALIZED_STRING)
{
name = (isConstructor() ? null : ASTFacadeHelper.toString(getASTNode().getName()));
}
return name;
}
public void setName(String name)
{
this.name = name;
setNodeProperty(getASTNode(), name, MethodDeclaration.NAME_PROPERTY, ASTNode.SIMPLE_NAME);
}
public String getReturnType()
{
if (returnType == UNITIALIZED_STRING)
{
returnType = getFacadeHelper().toString(getASTNode().getReturnType2());
if (returnType != null)
{
// append extra dimensions since they are not stored in Type object
for (int i = 0; i < getASTNode().getExtraDimensions(); i++)
{
returnType += "[]";
}
}
}
return returnType;
}
@SuppressWarnings("deprecation")
public void setReturnType(String type)
{
this.returnType = type;
setNodeProperty(getASTNode(), 0, MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY);
setTrackedNodeProperty(getASTNode(), type, MethodDeclaration.RETURN_TYPE2_PROPERTY, ASTNode.SIMPLE_TYPE);
}
@SuppressWarnings("unchecked")
public String[] getTypeParameters()
{
if (typeParameters == EMPTY_STRING_ARRAY)
{
typeParameters = convertASTNodeListToStringArray(getASTNode().typeParameters());
}
return typeParameters;
}
public void setTypeParameters(String[] typeParameters)
{
this.typeParameters = typeParameters;
setListNodeProperty(getASTNode(), typeParameters, MethodDeclaration.TYPE_PARAMETERS_PROPERTY, ASTNode.TYPE_PARAMETER);
}
/**
* Returns parameter names.
* <p>
* Note that if parameters have been changed by {@link #setParameters(String[])} method,
* this method will <b>not</b> parse parameters, and will <b>not</b> return the new parameter names.
* This method will return either parameter names set by {@link #setParameterNames(String[])} method
* or original parameter names.
*
* @see org.eclipse.emf.codegen.merge.java.facade.JMethod#getParameterNames()
*/
public String[] getParameterNames()
{
if (parameterNames == EMPTY_STRING_ARRAY)
{
@SuppressWarnings("unchecked")
List<SingleVariableDeclaration> parameters = getASTNode().parameters();
parameterNames = new String[parameters.size()];
int j = 0;
for (SingleVariableDeclaration parameter : parameters)
{
parameterNames[j++] = ASTFacadeHelper.toString(parameter.getName());
}
}
return parameterNames;
}
/**
* Returns type erasure of all the types of formal parameters of the original method declaration.
* <p>
* This method is used to create a method signature, and match methods by signature.
* <p>
* Note that this implementation does not expand types into fully qualified names, nor
* does it replace type parameters defined for a class or a method.
*
* @see ASTFacadeHelper#getTypeErasure(org.eclipse.jdt.core.dom.Type)
* @see org.eclipse.emf.codegen.merge.java.facade.JMethod#getParameterTypes()
*/
public String[] getParameterTypes()
{
@SuppressWarnings("unchecked")
List<SingleVariableDeclaration> parameters = getASTNode().parameters();
String[] ret = new String[parameters.size()];
int j = 0;
for (SingleVariableDeclaration parameter : parameters)
{
String type = ASTFacadeHelper.getTypeErasure(parameter.getType());
// append extra dimensions if any
for (int i = 0; i < parameter.getExtraDimensions(); i++)
{
type += "[]";
}
// append [] if it is variable arity parameter (@see JLS3 8.4.1, http://java.sun.com/docs/books/jls/third_edition/html/classes.html#300870)
if (parameter.isVarargs())
{
type += "[]";
}
ret[j++] = type;
}
return ret;
}
/**
* Returns all the types of formal parameters of the original method declaration.
* Note that this implementation does not expand types into fully qualified names, nor
* does it replace type parameters defined for a class or a method.
*
* @see org.eclipse.emf.codegen.merge.java.facade.JMethod#getFullParameterTypes()
*/
public String[] getFullParameterTypes()
{
@SuppressWarnings("unchecked")
List<SingleVariableDeclaration> parameters = getASTNode().parameters();
String[] ret = new String[parameters.size()];
int j = 0;
for (SingleVariableDeclaration parameter : parameters)
{
String type = getFacadeHelper().toString(parameter.getType());
// append extra dimensions if any
for (int i = 0; i < parameter.getExtraDimensions(); i++)
{
type += "[]";
}
// append [] if it is variable arity parameter (@see JLS3 8.4.1, http://java.sun.com/docs/books/jls/third_edition/html/classes.html#300870)
if (parameter.isVarargs())
{
type += "[]";
}
ret[j++] = type;
}
return ret;
}
/**
* Sets parameter names. New parameter names will not be returned by {@link #getParameters()},
* but will be returned by {@link #getParameterNames()}.
*
* @see #getParameterNames()
* @see #getParameters()
* @see org.eclipse.emf.codegen.merge.java.facade.JMethod#setParameterNames(java.lang.String[])
*/
public void setParameterNames(String[] names)
{
@SuppressWarnings("unchecked")
List<SingleVariableDeclaration> parameters = getASTNode().parameters();
if (parameters.size() != names.length)
{
throw new IllegalArgumentException("Length of names must match number of existing parameters.");
}
this.parameterNames = names;
int i = 0;
for (SingleVariableDeclaration parameter : parameters)
{
setNodeProperty(parameter, names[i++], SingleVariableDeclaration.NAME_PROPERTY, ASTNode.SIMPLE_NAME);
}
}
public String[] getExceptions()
{
if (exceptions == EMPTY_STRING_ARRAY)
{
@SuppressWarnings({ "unchecked", "deprecation" })
List<Name> exceptionsList = getASTNode().thrownExceptions();
exceptions = new String [exceptionsList.size()];
int j = 0;
for (Name exception : exceptionsList)
{
exceptions[j++] = ASTFacadeHelper.toString(exception);
}
}
exceptions = combineArrayAndList(exceptions, addedExceptions);
return exceptions;
}
@SuppressWarnings("deprecation")
public void setExceptions(String[] exceptionTypes)
{
this.exceptions = exceptionTypes;
this.addedExceptions = null;
setListNodeProperty(getASTNode(), exceptionTypes, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY, ASTNode.SIMPLE_NAME);
}
@SuppressWarnings("deprecation")
public void addException(String exceptionType)
{
if (addedExceptions == null)
{
addedExceptions = new ArrayList<String>();
}
addedExceptions.add(exceptionType);
addValueToListProperty(getASTNode(), exceptionType, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY, ASTNode.SIMPLE_NAME);
}
public String getBody()
{
if (body == UNITIALIZED_STRING)
{
body = getFacadeHelper().toString(getASTNode().getBody());
}
return body;
}
public void setBody(String body)
{
this.body = body;
setTrackedNodeProperty(getASTNode(), body, MethodDeclaration.BODY_PROPERTY, ASTNode.BLOCK);
}
@Override
protected String computeQualifiedName()
{
return computeQualifiedName(this);
}
/**
* Returned parameters will not include new names set by {@link #setParameterNames(String[])}.
*
* @see org.eclipse.emf.codegen.merge.java.facade.JMethod#getParameters()
*/
@SuppressWarnings("unchecked")
public String[] getParameters()
{
if (parameters == EMPTY_STRING_ARRAY)
{
parameters = convertASTNodeListToStringArray(getASTNode().parameters());
}
return parameters;
}
public void setParameters(String[] parameters)
{
this.parameters = parameters;
setListNodeProperty(getASTNode(), parameters, MethodDeclaration.PARAMETERS_PROPERTY, ASTNode.SINGLE_VARIABLE_DECLARATION);
}
}