1 11 12 package org.eclipse.jdt.internal.ui.text.correction; 13 14 import java.util.List ; 15 16 import org.eclipse.core.runtime.CoreException; 17 18 import org.eclipse.swt.graphics.Image; 19 20 import org.eclipse.jdt.core.ICompilationUnit; 21 import org.eclipse.jdt.core.dom.AST; 22 import org.eclipse.jdt.core.dom.ASTNode; 23 import org.eclipse.jdt.core.dom.Block; 24 import org.eclipse.jdt.core.dom.CompilationUnit; 25 import org.eclipse.jdt.core.dom.IMethodBinding; 26 import org.eclipse.jdt.core.dom.ITypeBinding; 27 import org.eclipse.jdt.core.dom.Javadoc; 28 import org.eclipse.jdt.core.dom.MethodDeclaration; 29 import org.eclipse.jdt.core.dom.Modifier; 30 import org.eclipse.jdt.core.dom.Name; 31 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 32 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 33 import org.eclipse.jdt.core.dom.TypeDeclaration; 34 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 35 36 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; 37 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 38 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 39 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 40 import org.eclipse.jdt.internal.corext.dom.Bindings; 41 import org.eclipse.jdt.internal.corext.util.Messages; 42 43 import org.eclipse.jdt.ui.CodeGeneration; 44 import org.eclipse.jdt.ui.JavaElementImageDescriptor; 45 46 import org.eclipse.jdt.internal.ui.JavaPlugin; 47 import org.eclipse.jdt.internal.ui.JavaPluginImages; 48 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; 49 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider; 50 51 public class ConstructorFromSuperclassProposal extends LinkedCorrectionProposal { 52 53 private TypeDeclaration fTypeNode; 54 private IMethodBinding fSuperConstructor; 55 56 public ConstructorFromSuperclassProposal(ICompilationUnit cu, TypeDeclaration typeNode, IMethodBinding superConstructor, int relevance) { 57 super("", cu, null, relevance, null); fTypeNode= typeNode; 59 fSuperConstructor= superConstructor; 60 } 61 62 65 public Image getImage() { 66 return JavaPlugin.getImageDescriptorRegistry().get( 67 new JavaElementImageDescriptor(JavaPluginImages.DESC_MISC_PUBLIC, JavaElementImageDescriptor.CONSTRUCTOR, JavaElementImageProvider.SMALL_SIZE) 68 ); 69 } 70 71 74 public String getDisplayString() { 75 StringBuffer buf= new StringBuffer (); 76 buf.append(fTypeNode.getName().getIdentifier()); 77 buf.append('('); 78 if (fSuperConstructor != null) { 79 ITypeBinding[] paramTypes= fSuperConstructor.getParameterTypes(); 80 for (int i= 0; i < paramTypes.length; i++) { 81 if (i > 0) { 82 buf.append(','); 83 } 84 buf.append(paramTypes[i].getName()); 85 } 86 } 87 buf.append(')'); 88 return Messages.format(CorrectionMessages.ConstructorFromSuperclassProposal_description, buf.toString()); 89 } 90 91 94 protected ASTRewrite getRewrite() throws CoreException { 95 AST ast= fTypeNode.getAST(); 96 97 ASTRewrite rewrite= ASTRewrite.create(ast); 98 99 createImportRewrite((CompilationUnit) fTypeNode.getRoot()); 100 101 CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(getCompilationUnit().getJavaProject()); 102 if (!settings.createComments) { 103 settings= null; 104 } 105 106 MethodDeclaration newMethodDecl= createNewMethodDeclaration(ast, fSuperConstructor, rewrite, settings); 107 rewrite.getListRewrite(fTypeNode, TypeDeclaration.BODY_DECLARATIONS_PROPERTY).insertFirst(newMethodDecl, null); 108 109 addLinkedRanges(rewrite, newMethodDecl); 110 111 return rewrite; 112 } 113 114 private void addLinkedRanges(ASTRewrite rewrite, MethodDeclaration newStub) { 115 List parameters= newStub.parameters(); 116 for (int i= 0; i < parameters.size(); i++) { 117 SingleVariableDeclaration curr= (SingleVariableDeclaration) parameters.get(i); 118 String name= curr.getName().getIdentifier(); 119 addLinkedPosition(rewrite.track(curr.getType()), false, "arg_type_" + name); addLinkedPosition(rewrite.track(curr.getName()), false, "arg_name_" + name); } 122 } 123 124 private MethodDeclaration createNewMethodDeclaration(AST ast, IMethodBinding binding, ASTRewrite rewrite, CodeGenerationSettings commentSettings) throws CoreException { 125 String name= fTypeNode.getName().getIdentifier(); 126 MethodDeclaration decl= ast.newMethodDeclaration(); 127 decl.setConstructor(true); 128 decl.setName(ast.newSimpleName(name)); 129 Block body= ast.newBlock(); 130 decl.setBody(body); 131 132 SuperConstructorInvocation invocation= null; 133 134 List parameters= decl.parameters(); 135 String [] paramNames= getArgumentNames(binding); 136 137 ITypeBinding enclosingInstance= getEnclosingInstance(); 138 if (enclosingInstance != null) { 139 invocation= addEnclosingInstanceAccess(rewrite, parameters, paramNames, enclosingInstance); 140 } 141 142 if (binding == null) { 143 decl.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); 144 } else { 145 decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, binding.getModifiers())); 146 147 ITypeBinding[] params= binding.getParameterTypes(); 148 for (int i= 0; i < params.length; i++) { 149 SingleVariableDeclaration var= ast.newSingleVariableDeclaration(); 150 var.setType(getImportRewrite().addImport(params[i], ast)); 151 var.setName(ast.newSimpleName(paramNames[i])); 152 parameters.add(var); 153 } 154 155 List thrownExceptions= decl.thrownExceptions(); 156 ITypeBinding[] excTypes= binding.getExceptionTypes(); 157 for (int i= 0; i < excTypes.length; i++) { 158 String excTypeName= getImportRewrite().addImport(excTypes[i]); 159 thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName)); 160 } 161 162 if (invocation == null) { 163 invocation= ast.newSuperConstructorInvocation(); 164 } 165 166 List arguments= invocation.arguments(); 167 for (int i= 0; i < paramNames.length; i++) { 168 Name argument= ast.newSimpleName(paramNames[i]); 169 arguments.add(argument); 170 addLinkedPosition(rewrite.track(argument), false, "arg_name_" + paramNames[i]); } 172 } 173 174 String bodyStatement= (invocation == null) ? "" : ASTNodes.asFormattedString(invocation, 0, String.valueOf('\n'), getCompilationUnit().getJavaProject().getOptions(true)); String placeHolder= CodeGeneration.getMethodBodyContent(getCompilationUnit(), name, name, true, bodyStatement, String.valueOf('\n')); 176 if (placeHolder != null) { 177 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT); 178 body.statements().add(todoNode); 179 } 180 if (commentSettings != null) { 181 String string= CodeGeneration.getMethodComment(getCompilationUnit(), name, decl, null, String.valueOf('\n')); 182 if (string != null) { 183 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC); 184 decl.setJavadoc(javadoc); 185 } 186 } 187 return decl; 188 } 189 190 private SuperConstructorInvocation addEnclosingInstanceAccess(ASTRewrite rewrite, List parameters, String [] paramNames, ITypeBinding enclosingInstance) throws CoreException { 191 AST ast= rewrite.getAST(); 192 SuperConstructorInvocation invocation= ast.newSuperConstructorInvocation(); 193 194 SingleVariableDeclaration var= ast.newSingleVariableDeclaration(); 195 var.setType(getImportRewrite().addImport(enclosingInstance, ast)); 196 String [] enclosingArgNames= StubUtility.getArgumentNameSuggestions(getCompilationUnit().getJavaProject(), enclosingInstance.getTypeDeclaration().getName(), 0, paramNames); 197 String firstName= enclosingArgNames[0]; 198 var.setName(ast.newSimpleName(firstName)); 199 parameters.add(var); 200 201 Name enclosing= ast.newSimpleName(firstName); 202 invocation.setExpression(enclosing); 203 204 String key= "arg_name_" + firstName; addLinkedPosition(rewrite.track(enclosing), false, key); 206 for (int i= 0; i < enclosingArgNames.length; i++) { 207 addLinkedPositionProposal(key, enclosingArgNames[i], null); } 209 return invocation; 210 } 211 212 private ITypeBinding getEnclosingInstance() { 213 ITypeBinding currBinding= fTypeNode.resolveBinding(); 214 if (currBinding == null || Modifier.isStatic(currBinding.getModifiers())) { 215 return null; 216 } 217 ITypeBinding superBinding= currBinding.getSuperclass(); 218 if (superBinding == null || superBinding.getDeclaringClass() == null || Modifier.isStatic(superBinding.getModifiers())) { 219 return null; 220 } 221 ITypeBinding enclosing= superBinding.getDeclaringClass(); 222 223 while (currBinding != null) { 224 if (Bindings.isSuperType(enclosing, currBinding)) { 225 return null; } 227 if (Modifier.isStatic(currBinding.getModifiers())) { 228 return null; } 230 currBinding= currBinding.getDeclaringClass(); 231 } 232 return enclosing; 233 } 234 235 236 private String [] getArgumentNames(IMethodBinding binding) { 237 if (binding == null) { 238 return new String [0]; 239 } 240 return StubUtility.suggestArgumentNames(getCompilationUnit().getJavaProject(), binding); 241 } 242 } 243 | Popular Tags |