| /******************************************************************************* |
| * Copyright (c) 2000, 2011 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.internal.corext.refactoring.delegates; |
| |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.Assert; |
| |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.dom.ASTNode; |
| import org.eclipse.jdt.core.dom.Block; |
| import org.eclipse.jdt.core.dom.BodyDeclaration; |
| import org.eclipse.jdt.core.dom.ChildPropertyDescriptor; |
| import org.eclipse.jdt.core.dom.ConstructorInvocation; |
| import org.eclipse.jdt.core.dom.Expression; |
| import org.eclipse.jdt.core.dom.ExpressionStatement; |
| import org.eclipse.jdt.core.dom.IBinding; |
| import org.eclipse.jdt.core.dom.MethodDeclaration; |
| import org.eclipse.jdt.core.dom.MethodInvocation; |
| import org.eclipse.jdt.core.dom.MethodRef; |
| import org.eclipse.jdt.core.dom.MethodRefParameter; |
| import org.eclipse.jdt.core.dom.PrimitiveType; |
| import org.eclipse.jdt.core.dom.ReturnStatement; |
| import org.eclipse.jdt.core.dom.SimpleName; |
| import org.eclipse.jdt.core.dom.SingleVariableDeclaration; |
| import org.eclipse.jdt.core.dom.Statement; |
| import org.eclipse.jdt.core.dom.Type; |
| |
| import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; |
| import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; |
| |
| /** |
| * Delegate creator for static and non-static methods. |
| * |
| * @since 3.2 |
| */ |
| public class DelegateMethodCreator extends DelegateCreator { |
| |
| private ASTNode fDelegateInvocation; |
| private MethodRef fDocMethodReference; |
| |
| @Override |
| protected void initialize() { |
| |
| Assert.isTrue(getDeclaration() instanceof MethodDeclaration); |
| |
| if (getNewElementName() == null) |
| setNewElementName(((MethodDeclaration) getDeclaration()).getName().getIdentifier()); |
| |
| setInsertBefore(true); |
| } |
| |
| @Override |
| protected ASTNode createBody(BodyDeclaration bd) throws JavaModelException { |
| |
| MethodDeclaration methodDeclaration= (MethodDeclaration) bd; |
| |
| // interface or abstract method ? => don't create a method body. |
| if (methodDeclaration.getBody() == null) |
| return null; |
| |
| return createDelegateMethodBody(methodDeclaration); |
| } |
| |
| @Override |
| protected ASTNode createDocReference(final BodyDeclaration declaration) throws JavaModelException { |
| fDocMethodReference= getAst().newMethodRef(); |
| fDocMethodReference.setName(getAst().newSimpleName(getNewElementName())); |
| if (isMoveToAnotherFile()) |
| fDocMethodReference.setQualifier(createDestinationTypeName()); |
| createArguments((MethodDeclaration) declaration, fDocMethodReference.parameters(), false); |
| return fDocMethodReference; |
| } |
| |
| @Override |
| protected ASTNode getBodyHead(BodyDeclaration result) { |
| return result; |
| } |
| |
| @Override |
| protected ChildPropertyDescriptor getJavaDocProperty() { |
| return MethodDeclaration.JAVADOC_PROPERTY; |
| } |
| |
| @Override |
| protected ChildPropertyDescriptor getBodyProperty() { |
| return MethodDeclaration.BODY_PROPERTY; |
| } |
| |
| /** |
| * @return the delegate incovation, either a {@link ConstructorInvocation} |
| * or a {@link MethodInvocation}. May be null if the delegate |
| * method is abstract (and therefore has no body at all) |
| */ |
| public ASTNode getDelegateInvocation() { |
| return fDelegateInvocation; |
| } |
| |
| /** |
| * @return the javadoc reference to the old method in the javadoc comment. |
| * May be null if no comment was created. |
| */ |
| public MethodRef getJavadocReference() { |
| return fDocMethodReference; |
| } |
| |
| /** |
| * Creates the corresponding statement for the method invocation, based on |
| * the return type. |
| * |
| * @param declaration the method declaration where the invocation statement |
| * is inserted |
| * @param invocation the method invocation being encapsulated by the |
| * resulting statement |
| * @return the corresponding statement |
| */ |
| protected Statement createMethodInvocation(final MethodDeclaration declaration, final MethodInvocation invocation) { |
| Assert.isNotNull(declaration); |
| Assert.isNotNull(invocation); |
| Statement statement= null; |
| final Type type= declaration.getReturnType2(); |
| if (type == null) |
| statement= createExpressionStatement(invocation); |
| else { |
| if (type instanceof PrimitiveType) { |
| final PrimitiveType primitive= (PrimitiveType) type; |
| if (primitive.getPrimitiveTypeCode().equals(PrimitiveType.VOID)) |
| statement= createExpressionStatement(invocation); |
| else |
| statement= createReturnStatement(invocation); |
| } else |
| statement= createReturnStatement(invocation); |
| } |
| return statement; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected IBinding getDeclarationBinding() { |
| final MethodDeclaration declaration= (MethodDeclaration) getDeclaration(); |
| return declaration.resolveBinding(); |
| } |
| |
| @SuppressWarnings("unchecked") |
| private void createArguments(final MethodDeclaration declaration, final List<? extends ASTNode> arguments, boolean methodInvocation) { |
| Assert.isNotNull(declaration); |
| Assert.isNotNull(arguments); |
| SingleVariableDeclaration variable= null; |
| final int size= declaration.parameters().size(); |
| for (int index= 0; index < size; index++) { |
| variable= (SingleVariableDeclaration) declaration.parameters().get(index); |
| |
| if (methodInvocation) { |
| // we are creating method invocation parameters |
| final SimpleName expression= getAst().newSimpleName(variable.getName().getIdentifier()); |
| ((List<Expression>) arguments).add(expression); |
| } else { |
| // we are creating type info for the javadoc |
| final MethodRefParameter parameter= getAst().newMethodRefParameter(); |
| parameter.setType(ASTNodeFactory.newType(getAst(), variable)); |
| if ((index == size - 1) && declaration.isVarargs()) |
| parameter.setVarargs(true); |
| ((List<MethodRefParameter>) arguments).add(parameter); |
| } |
| } |
| } |
| |
| private Block createDelegateMethodBody(final MethodDeclaration declaration) { |
| Assert.isNotNull(declaration); |
| |
| MethodDeclaration old= (MethodDeclaration) getDeclaration(); |
| List<Expression> arguments; |
| Statement call; |
| if (old.isConstructor()) { |
| ConstructorInvocation invocation= getAst().newConstructorInvocation(); |
| arguments= invocation.arguments(); |
| call= invocation; |
| fDelegateInvocation= invocation; |
| } else { |
| MethodInvocation invocation= getAst().newMethodInvocation(); |
| invocation.setName(getAst().newSimpleName(getNewElementName())); |
| invocation.setExpression(getAccess()); |
| arguments= invocation.arguments(); |
| call= createMethodInvocation(declaration, invocation); |
| fDelegateInvocation= invocation; |
| } |
| createArguments(declaration, arguments, true); |
| |
| final Block body= getAst().newBlock(); |
| body.statements().add(call); |
| |
| return body; |
| } |
| |
| /** |
| * Creates a new expression statement for the method invocation. |
| * |
| * @param invocation the method invocation |
| * @return the corresponding statement |
| */ |
| private ExpressionStatement createExpressionStatement(final MethodInvocation invocation) { |
| Assert.isNotNull(invocation); |
| return invocation.getAST().newExpressionStatement(invocation); |
| } |
| |
| /** |
| * Creates a new return statement for the method invocation. |
| * |
| * @param invocation the method invocation to create a return statement for |
| * @return the corresponding statement |
| */ |
| private ReturnStatement createReturnStatement(final MethodInvocation invocation) { |
| Assert.isNotNull(invocation); |
| final ReturnStatement statement= invocation.getAST().newReturnStatement(); |
| statement.setExpression(invocation); |
| return statement; |
| } |
| |
| @Override |
| protected String getTextEditGroupLabel() { |
| return RefactoringCoreMessages.DelegateMethodCreator_text_edit_group_field; |
| } |
| } |