1 11 12 package org.eclipse.jdt.internal.ui.text.correction; 13 14 import java.util.ArrayList ; 15 import java.util.List ; 16 17 import org.eclipse.core.runtime.Assert; 18 import org.eclipse.core.runtime.CoreException; 19 20 import org.eclipse.swt.graphics.Image; 21 22 import org.eclipse.jdt.core.ICompilationUnit; 23 import org.eclipse.jdt.core.dom.AST; 24 import org.eclipse.jdt.core.dom.ASTNode; 25 import org.eclipse.jdt.core.dom.Block; 26 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; 27 import org.eclipse.jdt.core.dom.CompilationUnit; 28 import org.eclipse.jdt.core.dom.ITypeBinding; 29 import org.eclipse.jdt.core.dom.IVariableBinding; 30 import org.eclipse.jdt.core.dom.Javadoc; 31 import org.eclipse.jdt.core.dom.MethodDeclaration; 32 import org.eclipse.jdt.core.dom.PrimitiveType; 33 import org.eclipse.jdt.core.dom.ReturnStatement; 34 import org.eclipse.jdt.core.dom.SimpleName; 35 import org.eclipse.jdt.core.dom.Type; 36 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 37 import org.eclipse.jdt.core.dom.rewrite.ListRewrite; 38 39 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; 40 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 41 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 42 import org.eclipse.jdt.internal.corext.dom.Bindings; 43 44 import org.eclipse.jdt.ui.CodeGeneration; 45 46 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; 47 48 public abstract class AbstractMethodCompletionProposal extends LinkedCorrectionProposal { 49 50 private ASTNode fNode; 51 private ITypeBinding fSenderBinding; 52 53 public AbstractMethodCompletionProposal(String label, ICompilationUnit targetCU, ASTNode invocationNode, ITypeBinding binding, int relevance, Image image) { 54 super(label, targetCU, null, relevance, image); 55 56 Assert.isTrue(binding != null && Bindings.isDeclarationBinding(binding)); 57 58 fNode= invocationNode; 59 fSenderBinding= binding; 60 } 61 62 protected ASTNode getInvocationNode() { 63 return fNode; 64 } 65 66 69 protected ITypeBinding getSenderBinding() { 70 return fSenderBinding; 71 } 72 73 protected ASTRewrite getRewrite() throws CoreException { 74 CompilationUnit astRoot= ASTResolving.findParentCompilationUnit(fNode); 75 ASTNode typeDecl= astRoot.findDeclaringNode(fSenderBinding); 76 ASTNode newTypeDecl= null; 77 boolean isInDifferentCU; 78 if (typeDecl != null) { 79 isInDifferentCU= false; 80 newTypeDecl= typeDecl; 81 } else { 82 isInDifferentCU= true; 83 astRoot= ASTResolving.createQuickFixAST(getCompilationUnit(), null); 84 newTypeDecl= astRoot.findDeclaringNode(fSenderBinding.getKey()); 85 } 86 createImportRewrite(astRoot); 87 88 if (newTypeDecl != null) { 89 ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST()); 90 91 MethodDeclaration newStub= getStub(rewrite, newTypeDecl); 92 93 ChildListPropertyDescriptor property= ASTNodes.getBodyDeclarationsProperty(newTypeDecl); 94 List members= (List ) newTypeDecl.getStructuralProperty(property); 95 96 int insertIndex; 97 if (isConstructor()) { 98 insertIndex= findConstructorInsertIndex(members); 99 } else if (!isInDifferentCU) { 100 insertIndex= findMethodInsertIndex(members, fNode.getStartPosition()); 101 } else { 102 insertIndex= members.size(); 103 } 104 ListRewrite listRewriter= rewrite.getListRewrite(newTypeDecl, property); 105 listRewriter.insertAt(newStub, insertIndex, null); 106 107 return rewrite; 108 } 109 return null; 110 } 111 112 private MethodDeclaration getStub(ASTRewrite rewrite, ASTNode targetTypeDecl) throws CoreException { 113 AST ast= targetTypeDecl.getAST(); 114 MethodDeclaration decl= ast.newMethodDeclaration(); 115 116 SimpleName newNameNode= getNewName(rewrite); 117 118 decl.setConstructor(isConstructor()); 119 120 addNewModifiers(rewrite, targetTypeDecl, decl.modifiers()); 121 122 ArrayList takenNames= new ArrayList (); 123 addNewTypeParameters(rewrite, takenNames, decl.typeParameters()); 124 125 decl.setName(newNameNode); 126 127 IVariableBinding[] declaredFields= fSenderBinding.getDeclaredFields(); 128 for (int i= 0; i < declaredFields.length; i++) { takenNames.add(declaredFields[i].getName()); 130 } 131 132 String bodyStatement= ""; if (!isConstructor()) { 134 Type returnType= getNewMethodType(rewrite); 135 if (returnType == null) { 136 decl.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); 137 } else { 138 decl.setReturnType2(returnType); 139 } 140 if (!fSenderBinding.isInterface() && returnType != null) { 141 ReturnStatement returnStatement= ast.newReturnStatement(); 142 returnStatement.setExpression(ASTNodeFactory.newDefaultExpression(ast, returnType, 0)); 143 bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, String.valueOf('\n'), getCompilationUnit().getJavaProject().getOptions(true)); 144 } 145 } 146 147 addNewParameters(rewrite, takenNames, decl.parameters()); 148 addNewExceptions(rewrite, decl.thrownExceptions()); 149 150 Block body= null; 151 if (!fSenderBinding.isInterface()) { 152 body= ast.newBlock(); 153 String placeHolder= CodeGeneration.getMethodBodyContent(getCompilationUnit(), fSenderBinding.getName(), newNameNode.getIdentifier(), isConstructor(), bodyStatement, String.valueOf('\n')); 154 if (placeHolder != null) { 155 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT); 156 body.statements().add(todoNode); 157 } 158 } 159 decl.setBody(body); 160 161 CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(getCompilationUnit().getJavaProject()); 162 if (settings.createComments && !fSenderBinding.isAnonymous()) { 163 String string= CodeGeneration.getMethodComment(getCompilationUnit(), fSenderBinding.getName(), decl, null, String.valueOf('\n')); 164 if (string != null) { 165 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC); 166 decl.setJavadoc(javadoc); 167 } 168 } 169 return decl; 170 } 171 172 173 174 private int findMethodInsertIndex(List decls, int currPos) { 175 int nDecls= decls.size(); 176 for (int i= 0; i < nDecls; i++) { 177 ASTNode curr= (ASTNode) decls.get(i); 178 if (curr instanceof MethodDeclaration && currPos < curr.getStartPosition() + curr.getLength()) { 179 return i + 1; 180 } 181 } 182 return nDecls; 183 } 184 185 private int findConstructorInsertIndex(List decls) { 186 int nDecls= decls.size(); 187 int lastMethod= 0; 188 for (int i= nDecls - 1; i >= 0; i--) { 189 ASTNode curr= (ASTNode) decls.get(i); 190 if (curr instanceof MethodDeclaration) { 191 if (((MethodDeclaration) curr).isConstructor()) { 192 return i + 1; 193 } 194 lastMethod= i; 195 } 196 } 197 return lastMethod; 198 } 199 200 protected abstract boolean isConstructor(); 201 202 protected abstract void addNewModifiers(ASTRewrite rewrite, ASTNode targetTypeDecl, List exceptions); 203 protected abstract void addNewTypeParameters(ASTRewrite rewrite, List takenNames, List params) throws CoreException; 204 protected abstract void addNewParameters(ASTRewrite rewrite, List takenNames, List params) throws CoreException; 205 protected abstract void addNewExceptions(ASTRewrite rewrite, List exceptions) throws CoreException; 206 207 protected abstract SimpleName getNewName(ASTRewrite rewrite); 208 protected abstract Type getNewMethodType(ASTRewrite rewrite) throws CoreException; 209 210 211 } 212 | Popular Tags |