1 12 package org.eclipse.jdt.internal.ui.text.correction; 13 14 import java.util.ArrayList ; 15 import java.util.Collection ; 16 import java.util.HashSet ; 17 import java.util.List ; 18 19 import org.eclipse.core.runtime.CoreException; 20 21 import org.eclipse.swt.graphics.Image; 22 23 import org.eclipse.ui.ISharedImages; 24 25 import org.eclipse.jdt.core.ICompilationUnit; 26 import org.eclipse.jdt.core.IJavaElement; 27 import org.eclipse.jdt.core.IJavaProject; 28 import org.eclipse.jdt.core.IPackageFragment; 29 import org.eclipse.jdt.core.IType; 30 import org.eclipse.jdt.core.JavaModelException; 31 import org.eclipse.jdt.core.Signature; 32 import org.eclipse.jdt.core.dom.AST; 33 import org.eclipse.jdt.core.dom.ASTMatcher; 34 import org.eclipse.jdt.core.dom.ASTNode; 35 import org.eclipse.jdt.core.dom.Annotation; 36 import org.eclipse.jdt.core.dom.ArrayType; 37 import org.eclipse.jdt.core.dom.Assignment; 38 import org.eclipse.jdt.core.dom.BodyDeclaration; 39 import org.eclipse.jdt.core.dom.CastExpression; 40 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 41 import org.eclipse.jdt.core.dom.CompilationUnit; 42 import org.eclipse.jdt.core.dom.ConstructorInvocation; 43 import org.eclipse.jdt.core.dom.Expression; 44 import org.eclipse.jdt.core.dom.FieldAccess; 45 import org.eclipse.jdt.core.dom.IBinding; 46 import org.eclipse.jdt.core.dom.IMethodBinding; 47 import org.eclipse.jdt.core.dom.IPackageBinding; 48 import org.eclipse.jdt.core.dom.ITypeBinding; 49 import org.eclipse.jdt.core.dom.IVariableBinding; 50 import org.eclipse.jdt.core.dom.MemberValuePair; 51 import org.eclipse.jdt.core.dom.MethodDeclaration; 52 import org.eclipse.jdt.core.dom.MethodInvocation; 53 import org.eclipse.jdt.core.dom.Modifier; 54 import org.eclipse.jdt.core.dom.Name; 55 import org.eclipse.jdt.core.dom.NormalAnnotation; 56 import org.eclipse.jdt.core.dom.ParenthesizedExpression; 57 import org.eclipse.jdt.core.dom.QualifiedName; 58 import org.eclipse.jdt.core.dom.SimpleName; 59 import org.eclipse.jdt.core.dom.SimpleType; 60 import org.eclipse.jdt.core.dom.SingleMemberAnnotation; 61 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; 62 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 63 import org.eclipse.jdt.core.dom.SuperFieldAccess; 64 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 65 import org.eclipse.jdt.core.dom.SwitchCase; 66 import org.eclipse.jdt.core.dom.SwitchStatement; 67 import org.eclipse.jdt.core.dom.ThisExpression; 68 import org.eclipse.jdt.core.dom.ThrowStatement; 69 import org.eclipse.jdt.core.dom.Type; 70 import org.eclipse.jdt.core.dom.TypeDeclaration; 71 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 72 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 73 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 74 75 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 76 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 77 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 78 import org.eclipse.jdt.internal.corext.dom.Bindings; 79 import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; 80 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 81 import org.eclipse.jdt.internal.corext.util.Messages; 82 import org.eclipse.jdt.internal.corext.util.QualifiedTypeNameHistory; 83 import org.eclipse.jdt.internal.corext.util.TypeFilter; 84 85 import org.eclipse.jdt.ui.JavaElementImageDescriptor; 86 import org.eclipse.jdt.ui.JavaElementLabels; 87 import org.eclipse.jdt.ui.text.java.IInvocationContext; 88 import org.eclipse.jdt.ui.text.java.IProblemLocation; 89 90 import org.eclipse.jdt.internal.ui.JavaPlugin; 91 import org.eclipse.jdt.internal.ui.JavaPluginImages; 92 import org.eclipse.jdt.internal.ui.text.correction.ChangeMethodSignatureProposal.ChangeDescription; 93 import org.eclipse.jdt.internal.ui.text.correction.ChangeMethodSignatureProposal.EditDescription; 94 import org.eclipse.jdt.internal.ui.text.correction.ChangeMethodSignatureProposal.InsertDescription; 95 import org.eclipse.jdt.internal.ui.text.correction.ChangeMethodSignatureProposal.RemoveDescription; 96 import org.eclipse.jdt.internal.ui.text.correction.ChangeMethodSignatureProposal.SwapDescription; 97 import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider; 98 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider; 99 100 public class UnresolvedElementsSubProcessor { 101 102 private static final String ADD_IMPORT_ID= "org.eclipse.jdt.ui.correction.addImport"; 104 public static void getVariableProposals(IInvocationContext context, IProblemLocation problem, IVariableBinding resolvedField, Collection proposals) throws CoreException { 105 106 ICompilationUnit cu= context.getCompilationUnit(); 107 108 CompilationUnit astRoot= context.getASTRoot(); 109 ASTNode selectedNode= problem.getCoveredNode(astRoot); 110 if (selectedNode == null) { 111 return; 112 } 113 114 ITypeBinding binding= null; 116 ITypeBinding declaringTypeBinding= Bindings.getBindingOfParentTypeContext(selectedNode); 117 if (declaringTypeBinding == null) { 118 return; 119 } 120 121 boolean suggestVariableProposals= true; 123 int typeKind= 0; 124 125 while (selectedNode instanceof ParenthesizedExpression) { 126 selectedNode= ((ParenthesizedExpression) selectedNode).getExpression(); 127 } 128 129 130 Name node= null; 131 132 switch (selectedNode.getNodeType()) { 133 case ASTNode.SIMPLE_NAME: 134 node= (SimpleName) selectedNode; 135 ASTNode parent= node.getParent(); 136 StructuralPropertyDescriptor locationInParent= node.getLocationInParent(); 137 if (locationInParent == MethodInvocation.EXPRESSION_PROPERTY) { 138 typeKind= SimilarElementsRequestor.CLASSES; 139 } else if (locationInParent == FieldAccess.NAME_PROPERTY) { 140 Expression expression= ((FieldAccess) parent).getExpression(); 141 if (expression != null) { 142 binding= expression.resolveTypeBinding(); 143 if (binding == null) { 144 node= null; 145 } 146 } 147 } else if (parent instanceof SimpleType) { 148 suggestVariableProposals= false; 149 typeKind= SimilarElementsRequestor.REF_TYPES_AND_VAR; 150 } else if (parent instanceof QualifiedName) { 151 Name qualifier= ((QualifiedName) parent).getQualifier(); 152 if (qualifier != node) { 153 binding= qualifier.resolveTypeBinding(); 154 } else { 155 typeKind= SimilarElementsRequestor.REF_TYPES; 156 } 157 ASTNode outerParent= parent.getParent(); 158 while (outerParent instanceof QualifiedName) { 159 outerParent= outerParent.getParent(); 160 } 161 if (outerParent instanceof SimpleType) { 162 typeKind= SimilarElementsRequestor.REF_TYPES; 163 suggestVariableProposals= false; 164 } 165 } else if (locationInParent == SwitchCase.EXPRESSION_PROPERTY) { 166 ITypeBinding switchExp= ((SwitchStatement) node.getParent().getParent()).getExpression().resolveTypeBinding(); 167 if (switchExp != null && switchExp.isEnum()) { 168 binding= switchExp; 169 } 170 } else if (locationInParent == SuperFieldAccess.NAME_PROPERTY) { 171 binding= declaringTypeBinding.getSuperclass(); 172 } 173 break; 174 case ASTNode.QUALIFIED_NAME: 175 QualifiedName qualifierName= (QualifiedName) selectedNode; 176 ITypeBinding qualifierBinding= qualifierName.getQualifier().resolveTypeBinding(); 177 if (qualifierBinding != null) { 178 node= qualifierName.getName(); 179 binding= qualifierBinding; 180 } else { 181 node= qualifierName.getQualifier(); 182 typeKind= SimilarElementsRequestor.REF_TYPES; 183 suggestVariableProposals= node.isSimpleName(); 184 } 185 if (selectedNode.getParent() instanceof SimpleType) { 186 typeKind= SimilarElementsRequestor.REF_TYPES; 187 suggestVariableProposals= false; 188 } 189 break; 190 case ASTNode.FIELD_ACCESS: 191 FieldAccess access= (FieldAccess) selectedNode; 192 Expression expression= access.getExpression(); 193 if (expression != null) { 194 binding= expression.resolveTypeBinding(); 195 if (binding != null) { 196 node= access.getName(); 197 } 198 } 199 break; 200 case ASTNode.SUPER_FIELD_ACCESS: 201 binding= declaringTypeBinding.getSuperclass(); 202 node= ((SuperFieldAccess) selectedNode).getName(); 203 break; 204 default: 205 } 206 207 if (node == null) { 208 return; 209 } 210 211 if (typeKind != 0) { 213 if (!JavaModelUtil.is50OrHigher(cu.getJavaProject())) { 214 typeKind &= ~(SimilarElementsRequestor.ANNOTATIONS | SimilarElementsRequestor.ENUMS | SimilarElementsRequestor.VARIABLES); 215 } 216 217 int relevance= Character.isUpperCase(ASTNodes.getSimpleNameIdentifier(node).charAt(0)) ? 5 : -2; 218 addSimilarTypeProposals(typeKind, cu, node, relevance + 1, proposals); 219 220 typeKind &= ~SimilarElementsRequestor.ANNOTATIONS; 221 addNewTypeProposals(cu, node, typeKind, relevance, proposals); 222 } 223 224 if (!suggestVariableProposals) { 225 return; 226 } 227 228 SimpleName simpleName= node.isSimpleName() ? (SimpleName) node : ((QualifiedName) node).getName(); 229 boolean isWriteAccess= ASTResolving.isWriteAccess(node); 230 231 addSimilarVariableProposals(cu, astRoot, binding, simpleName, isWriteAccess, proposals); 233 234 if (resolvedField == null || binding == null || resolvedField.getDeclaringClass() != binding.getTypeDeclaration() && Modifier.isPrivate(resolvedField.getModifiers())) { 235 236 addNewFieldProposals(cu, astRoot, binding, declaringTypeBinding, simpleName, isWriteAccess, proposals); 238 239 if (binding == null) { 241 addNewVariableProposals(cu, node, simpleName, proposals); 242 } 243 } 244 } 245 246 private static void addNewVariableProposals(ICompilationUnit cu, Name node, SimpleName simpleName, Collection proposals) { 247 String name= simpleName.getIdentifier(); 248 BodyDeclaration bodyDeclaration= ASTResolving.findParentBodyDeclaration(node, true); 249 int type= bodyDeclaration.getNodeType(); 250 if (type == ASTNode.METHOD_DECLARATION) { 251 int relevance= StubUtility.hasParameterName(cu.getJavaProject(), name) ? 8 : 5; 252 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createparameter_description, simpleName.getIdentifier()); 253 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL); 254 proposals.add(new NewVariableCompletionProposal(label, cu, NewVariableCompletionProposal.PARAM, simpleName, null, relevance, image)); 255 } 256 if (type == ASTNode.INITIALIZER || (type == ASTNode.METHOD_DECLARATION && !ASTResolving.isInsideConstructorInvocation((MethodDeclaration) bodyDeclaration, node))) { 257 int relevance= StubUtility.hasLocalVariableName(cu.getJavaProject(), name) ? 10 : 7; 258 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createlocal_description, simpleName.getIdentifier()); 259 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL); 260 proposals.add(new NewVariableCompletionProposal(label, cu, NewVariableCompletionProposal.LOCAL, simpleName, null, relevance, image)); 261 } 262 263 if (node.getParent().getNodeType() == ASTNode.ASSIGNMENT) { 264 Assignment assignment= (Assignment) node.getParent(); 265 if (assignment.getLeftHandSide() == node && assignment.getParent().getNodeType() == ASTNode.EXPRESSION_STATEMENT) { 266 ASTNode statement= assignment.getParent(); 267 ASTRewrite rewrite= ASTRewrite.create(statement.getAST()); 268 if (ASTNodes.isControlStatementBody(assignment.getParent().getLocationInParent())) { 269 rewrite.replace(statement, rewrite.getAST().newBlock(), null); 270 } else { 271 rewrite.remove(statement, null); 272 } 273 String label= CorrectionMessages.UnresolvedElementsSubProcessor_removestatement_description; 274 Image image= JavaPlugin.getDefault().getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_DELETE); 275 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 4, image); 276 proposals.add(proposal); 277 } 278 } 279 } 280 281 private static void addNewFieldProposals(ICompilationUnit cu, CompilationUnit astRoot, ITypeBinding binding, ITypeBinding declaringTypeBinding, SimpleName simpleName, boolean isWriteAccess, Collection proposals) throws JavaModelException { 282 ICompilationUnit targetCU; 284 ITypeBinding senderDeclBinding; 285 if (binding != null) { 286 senderDeclBinding= binding.getTypeDeclaration(); 287 targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, senderDeclBinding); 288 } else { senderDeclBinding= declaringTypeBinding; 290 targetCU= cu; 291 } 292 293 if (!senderDeclBinding.isFromSource() || targetCU == null) { 294 return; 295 } 296 297 boolean mustBeConst= ASTResolving.isInsideModifiers(simpleName); 298 299 addNewFieldForType(targetCU, binding, senderDeclBinding, simpleName, isWriteAccess, mustBeConst, proposals); 300 301 if (binding == null && senderDeclBinding.isNested()) { 302 ASTNode anonymDecl= astRoot.findDeclaringNode(senderDeclBinding); 303 if (anonymDecl != null) { 304 ITypeBinding bind= Bindings.getBindingOfParentType(anonymDecl.getParent()); 305 if (!bind.isAnonymous()) { 306 addNewFieldForType(targetCU, bind, bind, simpleName, isWriteAccess, mustBeConst, proposals); 307 } 308 } 309 } 310 } 311 312 private static void addNewFieldForType(ICompilationUnit targetCU, ITypeBinding binding, ITypeBinding senderDeclBinding, SimpleName simpleName, boolean isWriteAccess, boolean mustBeConst, Collection proposals) { 313 String name= simpleName.getIdentifier(); 314 String label; 315 Image image; 316 if (senderDeclBinding.isEnum() && !isWriteAccess) { 317 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createenum_description, new Object [] { name, ASTResolving.getTypeSignature(senderDeclBinding) }); 318 image= JavaPluginImages.get(JavaPluginImages.IMG_FIELD_PUBLIC); 319 proposals.add(new NewVariableCompletionProposal(label, targetCU, NewVariableCompletionProposal.ENUM_CONST, simpleName, senderDeclBinding, 10, image)); 320 } else { 321 if (!mustBeConst) { 322 if (binding == null) { 323 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createfield_description, name); 324 image= JavaPluginImages.get(JavaPluginImages.IMG_FIELD_PRIVATE); 325 } else { 326 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createfield_other_description, new Object [] { name, ASTResolving.getTypeSignature(senderDeclBinding) } ); 327 image= JavaPluginImages.get(JavaPluginImages.IMG_FIELD_PUBLIC); 328 } 329 int fieldRelevance= StubUtility.hasFieldName(targetCU.getJavaProject(), name) ? 9 : 6; 330 proposals.add(new NewVariableCompletionProposal(label, targetCU, NewVariableCompletionProposal.FIELD, simpleName, senderDeclBinding, fieldRelevance, image)); 331 } 332 333 if (!isWriteAccess && !senderDeclBinding.isAnonymous()) { 334 if (binding == null) { 335 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createconst_description, name); 336 image= JavaPluginImages.get(JavaPluginImages.IMG_FIELD_PRIVATE); 337 } else { 338 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createconst_other_description, new Object [] { name, ASTResolving.getTypeSignature(senderDeclBinding) } ); 339 image= JavaPluginImages.get(JavaPluginImages.IMG_FIELD_PUBLIC); 340 } 341 int constRelevance= StubUtility.hasConstantName(name) ? 9 : 4; 342 proposals.add(new NewVariableCompletionProposal(label, targetCU, NewVariableCompletionProposal.CONST_FIELD, simpleName, senderDeclBinding, constRelevance, image)); 343 } 344 } 345 } 346 347 private static void addSimilarVariableProposals(ICompilationUnit cu, CompilationUnit astRoot, ITypeBinding binding, SimpleName node, boolean isWriteAccess, Collection proposals) { 348 int kind= ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY; 349 if (!isWriteAccess) { 350 kind |= ScopeAnalyzer.METHODS; } 352 353 IBinding[] varsAndMethodsInScope= (new ScopeAnalyzer(astRoot)).getDeclarationsInScope(node, kind); 354 if (varsAndMethodsInScope.length > 0) { 355 String otherNameInAssign= null; 357 358 String methodSenderName= null; 360 String fieldSenderName= null; 361 362 ASTNode parent= node.getParent(); 363 switch (parent.getNodeType()) { 364 case ASTNode.VARIABLE_DECLARATION_FRAGMENT: 365 otherNameInAssign= ((VariableDeclarationFragment) parent).getName().getIdentifier(); 367 break; 368 case ASTNode.ASSIGNMENT: 369 Assignment assignment= (Assignment) parent; 370 if (isWriteAccess && assignment.getRightHandSide() instanceof SimpleName) { 371 otherNameInAssign= ((SimpleName) assignment.getRightHandSide()).getIdentifier(); 372 } else if (!isWriteAccess && assignment.getLeftHandSide() instanceof SimpleName) { 373 otherNameInAssign= ((SimpleName) assignment.getLeftHandSide()).getIdentifier(); 374 } 375 break; 376 case ASTNode.METHOD_INVOCATION: 377 MethodInvocation inv= (MethodInvocation) parent; 378 if (inv.getExpression() == node) { 379 methodSenderName= inv.getName().getIdentifier(); 380 } 381 break; 382 case ASTNode.QUALIFIED_NAME: 383 QualifiedName qualName= (QualifiedName) parent; 384 if (qualName.getQualifier() == node) { 385 fieldSenderName= qualName.getName().getIdentifier(); 386 } 387 break; 388 } 389 390 391 ITypeBinding guessedType= ASTResolving.guessBindingForReference(node); 392 393 ITypeBinding objectBinding= astRoot.getAST().resolveWellKnownType("java.lang.Object"); String identifier= node.getIdentifier(); 395 boolean isInStaticContext= ASTResolving.isInStaticContext(node); 396 397 loop: for (int i= 0; i < varsAndMethodsInScope.length; i++) { 398 IBinding varOrMeth= varsAndMethodsInScope[i]; 399 if (varOrMeth instanceof IVariableBinding) { 400 IVariableBinding curr= (IVariableBinding) varOrMeth; 401 String currName= curr.getName(); 402 if (currName.equals(otherNameInAssign)) { 403 continue loop; 404 } 405 boolean isFinal= Modifier.isFinal(curr.getModifiers()); 406 if (isFinal && curr.isField() && isWriteAccess) { 407 continue loop; 408 } 409 if (isInStaticContext && !Modifier.isStatic(curr.getModifiers()) && curr.isField()) { 410 continue loop; 411 } 412 413 int relevance= 0; 414 if (NameMatcher.isSimilarName(currName, identifier)) { 415 relevance += 3; } 417 if (currName.equalsIgnoreCase(identifier)) { 418 relevance+= 5; 419 } 420 ITypeBinding varType= curr.getType(); 421 if (varType != null) { 422 if (guessedType != null && guessedType != objectBinding) { if (!isWriteAccess && canAssign(varType, guessedType) 425 || isWriteAccess && canAssign(guessedType, varType)) { 426 relevance += 2; } 428 } 429 if (methodSenderName != null && hasMethodWithName(varType, methodSenderName)) { 430 relevance += 2; 431 } 432 if (fieldSenderName != null && hasFieldWithName(varType, fieldSenderName)) { 433 relevance += 2; 434 } 435 } 436 437 if (relevance > 0) { 438 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changevariable_description, currName); 439 proposals.add(new RenameNodeCompletionProposal(label, cu, node.getStartPosition(), node.getLength(), currName, relevance)); 440 } 441 } else if (varOrMeth instanceof IMethodBinding) { 442 IMethodBinding curr= (IMethodBinding) varOrMeth; 443 if (!curr.isConstructor() && guessedType != null && canAssign(curr.getReturnType(), guessedType)) { 444 if (NameMatcher.isSimilarName(curr.getName(), identifier)) { 445 AST ast= astRoot.getAST(); 446 ASTRewrite rewrite= ASTRewrite.create(ast); 447 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changetomethod_description, ASTResolving.getMethodSignature(curr, false)); 448 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 449 LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 8, image); 450 proposals.add(proposal); 451 452 MethodInvocation newInv= ast.newMethodInvocation(); 453 newInv.setName(ast.newSimpleName(curr.getName())); 454 ITypeBinding[] parameterTypes= curr.getParameterTypes(); 455 for (int k= 0; k < parameterTypes.length; k++) { 456 ASTNode arg= ASTNodeFactory.newDefaultExpression(ast, parameterTypes[k]); 457 newInv.arguments().add(arg); 458 proposal.addLinkedPosition(rewrite.track(arg), false, null); 459 } 460 rewrite.replace(node, newInv, null); 461 } 462 } 463 } 464 } 465 } 466 if (binding != null && binding.isArray()) { 467 String idLength= "length"; String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changevariable_description, idLength); 469 proposals.add(new RenameNodeCompletionProposal(label, cu, node.getStartPosition(), node.getLength(), idLength, 8)); 470 } 471 } 472 473 private static boolean canAssign(ITypeBinding returnType, ITypeBinding guessedType) { 474 return returnType.isAssignmentCompatible(guessedType); 475 } 476 477 private static boolean hasMethodWithName(ITypeBinding typeBinding, String name) { 478 IVariableBinding[] fields= typeBinding.getDeclaredFields(); 479 for (int i= 0; i < fields.length; i++) { 480 if (fields[i].getName().equals(name)) { 481 return true; 482 } 483 } 484 ITypeBinding superclass= typeBinding.getSuperclass(); 485 if (superclass != null) { 486 return hasMethodWithName(superclass, name); 487 } 488 return false; 489 } 490 491 private static boolean hasFieldWithName(ITypeBinding typeBinding, String name) { 492 IMethodBinding[] methods= typeBinding.getDeclaredMethods(); 493 for (int i= 0; i < methods.length; i++) { 494 if (methods[i].getName().equals(name)) { 495 return true; 496 } 497 } 498 ITypeBinding superclass= typeBinding.getSuperclass(); 499 if (superclass != null) { 500 return hasMethodWithName(superclass, name); 501 } 502 return false; 503 } 504 505 private static int evauateTypeKind(ASTNode node, IJavaProject project) { 506 int kind= ASTResolving.getPossibleTypeKinds(node, JavaModelUtil.is50OrHigher(project)); 507 return kind; 508 } 509 510 511 public static void getTypeProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) throws CoreException { 512 ICompilationUnit cu= context.getCompilationUnit(); 513 514 ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); 515 if (selectedNode == null) { 516 return; 517 } 518 519 int kind= evauateTypeKind(selectedNode, cu.getJavaProject()); 520 521 while (selectedNode.getLocationInParent() == QualifiedName.NAME_PROPERTY) { 522 selectedNode= selectedNode.getParent(); 523 } 524 525 Name node= null; 526 if (selectedNode instanceof SimpleType) { 527 node= ((SimpleType) selectedNode).getName(); 528 } else if (selectedNode instanceof ArrayType) { 529 Type elementType= ((ArrayType) selectedNode).getElementType(); 530 if (elementType.isSimpleType()) { 531 node= ((SimpleType) elementType).getName(); 532 } else { 533 return; 534 } 535 } else if (selectedNode instanceof Name) { 536 node= (Name) selectedNode; 537 } else { 538 return; 539 } 540 541 addSimilarTypeProposals(kind, cu, node, 3, proposals); 543 544 while (node.getParent() instanceof QualifiedName) { 545 node= (Name) node.getParent(); 546 } 547 548 if (selectedNode != node) { 549 kind= evauateTypeKind(node, cu.getJavaProject()); 550 } 551 if ((kind & (SimilarElementsRequestor.CLASSES | SimilarElementsRequestor.INTERFACES)) != 0) { 552 kind &= ~SimilarElementsRequestor.ANNOTATIONS; } 554 addNewTypeProposals(cu, node, kind, 0, proposals); 555 } 556 557 private static void addSimilarTypeProposals(int kind, ICompilationUnit cu, Name node, int relevance, Collection proposals) throws CoreException { 558 SimilarElement[] elements= SimilarElementsRequestor.findSimilarElement(cu, node, kind); 559 560 String resolvedTypeName= null; 562 ITypeBinding binding= ASTResolving.guessBindingForTypeReference(node); 563 if (binding != null) { 564 ITypeBinding simpleBinding= binding; 565 if (simpleBinding.isArray()) { 566 simpleBinding= simpleBinding.getElementType(); 567 } 568 simpleBinding= simpleBinding.getTypeDeclaration(); 569 570 resolvedTypeName= simpleBinding.getQualifiedName(); 571 CUCorrectionProposal proposal= createTypeRefChangeProposal(cu, resolvedTypeName, node, relevance + 2, elements.length); 572 proposals.add(proposal); 573 if (proposal instanceof AddImportCorrectionProposal) 574 proposal.setRelevance(relevance + elements.length + 2); 575 576 if (binding.isParameterizedType() && node.getParent() instanceof SimpleType && !(node.getParent().getParent() instanceof Type)) { 577 proposals.add(createTypeRefChangeFullProposal(cu, binding, node, relevance + 2)); 578 } 579 } else { 580 ASTNode normalizedNode= ASTNodes.getNormalizedNode(node); 581 if (!(normalizedNode.getParent() instanceof Type) && node.getParent() != normalizedNode) { 582 ITypeBinding normBinding= ASTResolving.guessBindingForTypeReference(normalizedNode); 583 if (normBinding != null) { 584 proposals.add(createTypeRefChangeFullProposal(cu, normBinding, normalizedNode, relevance + 2)); 585 } 586 } 587 } 588 589 for (int i= 0; i < elements.length; i++) { 591 SimilarElement elem= elements[i]; 592 if ((elem.getKind() & SimilarElementsRequestor.ALL_TYPES) != 0) { 593 String fullName= elem.getName(); 594 if (!fullName.equals(resolvedTypeName)) { 595 proposals.add(createTypeRefChangeProposal(cu, fullName, node, relevance, elements.length)); 596 } 597 } 598 } 599 } 600 601 private static CUCorrectionProposal createTypeRefChangeProposal(ICompilationUnit cu, String fullName, Name node, int relevance, int maxProposals) throws CoreException { 602 ImportRewrite importRewrite= null; 603 String simpleName= fullName; 604 String packName= Signature.getQualifier(fullName); 605 if (packName.length() > 0) { importRewrite= StubUtility.createImportRewrite((CompilationUnit) node.getRoot(), true); 607 simpleName= importRewrite.addImport(fullName); 608 } 609 610 if (!isLikelyTypeName(simpleName)) { 611 relevance -= 2; 612 } 613 614 ASTRewriteCorrectionProposal proposal; 615 if (importRewrite != null && node.isSimpleName() && simpleName.equals(((SimpleName) node).getIdentifier())) { String [] arg= { simpleName, packName }; 618 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_importtype_description, arg); 619 Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_IMPDECL); 620 int boost= QualifiedTypeNameHistory.getBoost(fullName, 0, maxProposals); 621 proposal= new AddImportCorrectionProposal(label, cu, relevance + 100 + boost, image, packName, simpleName, (SimpleName)node); 622 proposal.setCommandId(ADD_IMPORT_ID); 623 } else { 624 String label; 625 if (packName.length() == 0) { 626 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changetype_nopack_description, simpleName); 627 } else { 628 String [] arg= { simpleName, packName }; 629 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changetype_description, arg); 630 } 631 ASTRewrite rewrite= ASTRewrite.create(node.getAST()); 632 rewrite.replace(node, rewrite.createStringPlaceholder(simpleName, ASTNode.SIMPLE_TYPE), null); 633 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 634 proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, relevance, image); 635 } 636 if (importRewrite != null) { 637 proposal.setImportRewrite(importRewrite); 638 } 639 return proposal; 640 } 641 642 private static CUCorrectionProposal createTypeRefChangeFullProposal(ICompilationUnit cu, ITypeBinding binding, ASTNode node, int relevance) throws CoreException { 643 ASTRewrite rewrite= ASTRewrite.create(node.getAST()); 644 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_change_full_type_description, BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_DEFAULT)); 645 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 646 647 648 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, relevance + 3, image); 649 650 ImportRewrite imports= proposal.createImportRewrite((CompilationUnit) node.getRoot()); 651 Type type= imports.addImport(binding, node.getAST()); 652 653 rewrite.replace(node, type, null); 654 return proposal; 655 } 656 657 private static boolean isLikelyTypeName(String name) { 658 return name.length() > 0 && Character.isUpperCase(name.charAt(0)); 659 } 660 661 private static boolean isLikelyPackageName(String name) { 662 if (name.length() != 0) { 663 int i= 0; 664 do { 665 if (Character.isUpperCase(name.charAt(i))) { 666 return false; 667 } 668 i= name.indexOf('.', i) + 1; 669 } while (i != 0 && i < name.length()); 670 } 671 return true; 672 } 673 674 private static boolean isLikelyTypeParameterName(String name) { 675 return name.length() == 1 && Character.isUpperCase(name.charAt(0)); 676 } 677 678 public static void addNewTypeProposals(ICompilationUnit cu, Name refNode, int kind, int relevance, Collection proposals) throws JavaModelException { 679 Name node= refNode; 680 do { 681 String typeName= ASTNodes.getSimpleNameIdentifier(node); 682 Name qualifier= null; 683 boolean isPossibleName= isLikelyTypeName(typeName) || (node == refNode); 685 if (isPossibleName) { 686 IPackageFragment enclosingPackage= null; 687 IType enclosingType= null; 688 if (node.isSimpleName()) { 689 enclosingPackage= (IPackageFragment) cu.getParent(); 690 } else { 692 Name qualifierName= ((QualifiedName) node).getQualifier(); 693 IBinding binding= qualifierName.resolveBinding(); 694 if (binding != null && binding.isRecovered()) { 695 binding= null; 696 } 697 if (binding instanceof ITypeBinding) { 698 enclosingType=(IType) binding.getJavaElement(); 699 } else if (binding instanceof IPackageBinding) { 700 qualifier= qualifierName; 701 enclosingPackage= (IPackageFragment) binding.getJavaElement(); 702 } else { 703 IJavaElement[] res= cu.codeSelect(qualifierName.getStartPosition(), qualifierName.getLength()); 704 if (res!= null && res.length > 0 && res[0] instanceof IType) { 705 enclosingType= (IType) res[0]; 706 } else { 707 qualifier= qualifierName; 708 enclosingPackage= JavaModelUtil.getPackageFragmentRoot(cu).getPackageFragment(ASTResolving.getFullName(qualifierName)); 709 } 710 } 711 } 712 int rel= relevance; 713 if (enclosingPackage != null && isLikelyPackageName(enclosingPackage.getElementName())) { 714 rel += 3; 715 } 716 717 if ((enclosingPackage != null && !enclosingPackage.getCompilationUnit(typeName + JavaModelUtil.DEFAULT_CU_SUFFIX).exists()) || (enclosingType != null && !enclosingType.isReadOnly() && !enclosingType.getType(typeName).exists())) { IJavaElement enclosing= enclosingPackage != null ? (IJavaElement) enclosingPackage : enclosingType; 720 721 if ((kind & SimilarElementsRequestor.CLASSES) != 0) { 722 proposals.add(new NewCUCompletionUsingWizardProposal(cu, node, NewCUCompletionUsingWizardProposal.K_CLASS, enclosing, rel+3)); 723 } 724 if ((kind & SimilarElementsRequestor.INTERFACES) != 0) { 725 proposals.add(new NewCUCompletionUsingWizardProposal(cu, node, NewCUCompletionUsingWizardProposal.K_INTERFACE, enclosing, rel+2)); 726 } 727 if ((kind & SimilarElementsRequestor.ENUMS) != 0) { 728 proposals.add(new NewCUCompletionUsingWizardProposal(cu, node, NewCUCompletionUsingWizardProposal.K_ENUM, enclosing, rel)); 729 } 730 if ((kind & SimilarElementsRequestor.ANNOTATIONS) != 0) { 731 proposals.add(new NewCUCompletionUsingWizardProposal(cu, node, NewCUCompletionUsingWizardProposal.K_ANNOTATION, enclosing, rel + 1)); 732 } 733 } 734 } 735 node= qualifier; 736 } while (node != null); 737 738 if (refNode.isSimpleName() && ((kind & SimilarElementsRequestor.VARIABLES) != 0)) { 740 CompilationUnit root= (CompilationUnit) refNode.getRoot(); 741 String name= ((SimpleName) refNode).getIdentifier(); 742 BodyDeclaration declaration= ASTResolving.findParentBodyDeclaration(refNode); 743 int baseRel= relevance; 744 if (isLikelyTypeParameterName(name)) { 745 baseRel += 4; 746 } 747 while (declaration != null) { 748 IBinding binding= null; 749 int rel= baseRel; 750 if (declaration instanceof MethodDeclaration) { 751 binding= ((MethodDeclaration) declaration).resolveBinding(); 752 } else if (declaration instanceof TypeDeclaration) { 753 binding= ((TypeDeclaration) declaration).resolveBinding(); 754 rel++; 755 } 756 if (binding != null) { 757 AddTypeParameterProposal proposal= new AddTypeParameterProposal(cu, binding, root, name, null, rel); 758 proposals.add(proposal); 759 } 760 if (!Modifier.isStatic(declaration.getModifiers())) { 761 declaration= ASTResolving.findParentBodyDeclaration(declaration.getParent()); 762 } else { 763 declaration= null; 764 } 765 } 766 } 767 } 768 769 public static void getMethodProposals(IInvocationContext context, IProblemLocation problem, boolean isOnlyParameterMismatch, Collection proposals) throws CoreException { 770 771 ICompilationUnit cu= context.getCompilationUnit(); 772 773 CompilationUnit astRoot= context.getASTRoot(); 774 ASTNode selectedNode= problem.getCoveringNode(astRoot); 775 776 if (!(selectedNode instanceof SimpleName)) { 777 return; 778 } 779 SimpleName nameNode= (SimpleName) selectedNode; 780 781 List arguments; 782 Expression sender; 783 boolean isSuperInvocation; 784 785 ASTNode invocationNode= nameNode.getParent(); 786 if (invocationNode instanceof MethodInvocation) { 787 MethodInvocation methodImpl= (MethodInvocation) invocationNode; 788 arguments= methodImpl.arguments(); 789 sender= methodImpl.getExpression(); 790 isSuperInvocation= false; 791 } else if (invocationNode instanceof SuperMethodInvocation) { 792 SuperMethodInvocation methodImpl= (SuperMethodInvocation) invocationNode; 793 arguments= methodImpl.arguments(); 794 sender= methodImpl.getQualifier(); 795 isSuperInvocation= true; 796 } else { 797 return; 798 } 799 800 String methodName= nameNode.getIdentifier(); 801 int nArguments= arguments.size(); 802 803 IBinding[] bindings= (new ScopeAnalyzer(astRoot)).getDeclarationsInScope(nameNode, ScopeAnalyzer.METHODS); 805 806 HashSet suggestedRenames= new HashSet (); 807 for (int i= 0; i < bindings.length; i++) { 808 IMethodBinding binding= (IMethodBinding) bindings[i]; 809 String curr= binding.getName(); 810 if (!curr.equals(methodName) && binding.getParameterTypes().length == nArguments && NameMatcher.isSimilarName(methodName, curr) && suggestedRenames.add(curr)) { 811 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changemethod_description, curr); 812 proposals.add(new RenameNodeCompletionProposal(label, context.getCompilationUnit(), problem.getOffset(), problem.getLength(), curr, 6)); 813 } 814 } 815 suggestedRenames= null; 816 817 if (isOnlyParameterMismatch) { 818 ArrayList parameterMismatchs= new ArrayList (); 819 for (int i= 0; i < bindings.length; i++) { 820 IMethodBinding binding= (IMethodBinding) bindings[i]; 821 if (binding.getName().equals(methodName)) { 822 parameterMismatchs.add(binding); 823 } 824 } 825 addParameterMissmatchProposals(context, problem, parameterMismatchs, invocationNode, arguments, proposals); 826 } 827 828 addNewMethodProposals(cu, astRoot, sender, arguments, isSuperInvocation, invocationNode, methodName, proposals); 830 831 if (!isOnlyParameterMismatch && !isSuperInvocation && sender != null) { 832 addMissingCastParentsProposal(cu, (MethodInvocation) invocationNode, proposals); 833 } 834 835 if (!isSuperInvocation && sender == null && invocationNode.getParent() instanceof ThrowStatement) { 836 String str= "new "; String label= CorrectionMessages.UnresolvedElementsSubProcessor_addnewkeyword_description; 838 int relevance= Character.isUpperCase(methodName.charAt(0)) ? 7 : 4; 839 ReplaceCorrectionProposal proposal= new ReplaceCorrectionProposal(label, cu, invocationNode.getStartPosition(), 0, str, relevance); 840 proposals.add(proposal); 841 } 842 843 } 844 845 private static void addNewMethodProposals(ICompilationUnit cu, CompilationUnit astRoot, Expression sender, List arguments, boolean isSuperInvocation, ASTNode invocationNode, String methodName, Collection proposals) throws JavaModelException { 846 ITypeBinding nodeParentType= Bindings.getBindingOfParentType(invocationNode); 847 ITypeBinding binding= null; 848 if (sender != null) { 849 binding= sender.resolveTypeBinding(); 850 } else { 851 binding= nodeParentType; 852 if (isSuperInvocation && binding != null) { 853 binding= binding.getSuperclass(); 854 } 855 } 856 if (binding != null && binding.isFromSource()) { 857 ITypeBinding senderDeclBinding= binding.getTypeDeclaration(); 858 859 ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, senderDeclBinding); 860 if (targetCU != null) { 861 String label; 862 Image image; 863 ITypeBinding[] parameterTypes= getParameterTypes(arguments); 864 if (parameterTypes != null) { 865 String sig= ASTResolving.getMethodSignature(methodName, parameterTypes, false); 866 867 if (ASTResolving.isUseableTypeInContext(parameterTypes, senderDeclBinding, false)) { 868 if (nodeParentType == senderDeclBinding) { 869 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createmethod_description, sig); 870 image= JavaPluginImages.get(JavaPluginImages.IMG_MISC_PRIVATE); 871 } else { 872 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createmethod_other_description, new Object [] { sig, senderDeclBinding.getName() } ); 873 image= JavaPluginImages.get(JavaPluginImages.IMG_MISC_PUBLIC); 874 } 875 proposals.add(new NewMethodCompletionProposal(label, targetCU, invocationNode, arguments, senderDeclBinding, 5, image)); 876 } 877 if (senderDeclBinding.isNested() && cu.equals(targetCU) && sender == null && Bindings.findMethodInHierarchy(senderDeclBinding, methodName, (ITypeBinding[]) null) == null) { ASTNode anonymDecl= astRoot.findDeclaringNode(senderDeclBinding); 879 if (anonymDecl != null) { 880 senderDeclBinding= Bindings.getBindingOfParentType(anonymDecl.getParent()); 881 if (!senderDeclBinding.isAnonymous() && ASTResolving.isUseableTypeInContext(parameterTypes, senderDeclBinding, false)) { 882 String [] args= new String [] { sig, ASTResolving.getTypeSignature(senderDeclBinding) }; 883 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createmethod_other_description, args); 884 image= JavaPluginImages.get(JavaPluginImages.IMG_MISC_PROTECTED); 885 proposals.add(new NewMethodCompletionProposal(label, targetCU, invocationNode, arguments, senderDeclBinding, 5, image)); 886 } 887 } 888 } 889 } 890 } 891 } 892 } 893 894 private static void addMissingCastParentsProposal(ICompilationUnit cu, MethodInvocation invocationNode, Collection proposals) { 895 Expression sender= invocationNode.getExpression(); 896 if (sender instanceof ThisExpression) { 897 return; 898 } 899 900 ITypeBinding senderBinding= sender.resolveTypeBinding(); 901 if (senderBinding == null || Modifier.isFinal(senderBinding.getModifiers())) { 902 return; 903 } 904 905 if (sender instanceof Name && ((Name) sender).resolveBinding() instanceof ITypeBinding) { 906 return; } 908 909 ASTNode parent= invocationNode.getParent(); 910 while (parent instanceof Expression && parent.getNodeType() != ASTNode.CAST_EXPRESSION) { 911 parent= parent.getParent(); 912 } 913 boolean hasCastProposal= false; 914 if (parent instanceof CastExpression) { 915 hasCastProposal= useExistingParentCastProposal(cu, (CastExpression) parent, sender, invocationNode.getName(), getArgumentTypes(invocationNode.arguments()), proposals); 917 } 918 if (!hasCastProposal) { 919 921 Expression target= sender; 922 while (target instanceof ParenthesizedExpression) { 923 target= ((ParenthesizedExpression) target).getExpression(); 924 } 925 926 String label; 927 if (target.getNodeType() != ASTNode.CAST_EXPRESSION) { 928 String targetName= null; 929 if (target.getLength() <= 18) { 930 targetName= ASTNodes.asString(target); 931 } 932 if (targetName == null) { 933 label= CorrectionMessages.UnresolvedElementsSubProcessor_methodtargetcast_description; 934 } else { 935 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_methodtargetcast2_description, targetName); 936 } 937 } else { 938 String targetName= null; 939 if (target.getLength() <= 18) { 940 targetName= ASTNodes.asString(((CastExpression)target).getExpression()); 941 } 942 if (targetName == null) { 943 label= CorrectionMessages.UnresolvedElementsSubProcessor_changemethodtargetcast_description; 944 } else { 945 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changemethodtargetcast2_description, targetName); 946 } 947 } 948 proposals.add(new CastCompletionProposal(label, cu, target, (ITypeBinding) null, 3)); 949 } 950 } 951 952 private static boolean useExistingParentCastProposal(ICompilationUnit cu, CastExpression expression, Expression accessExpression, SimpleName accessSelector, ITypeBinding[] paramTypes, Collection proposals) { 953 ITypeBinding castType= expression.getType().resolveBinding(); 954 if (castType == null) { 955 return false; 956 } 957 if (paramTypes != null) { 958 if (Bindings.findMethodInHierarchy(castType, accessSelector.getIdentifier(), paramTypes) == null) { 959 return false; 960 } 961 } else if (Bindings.findFieldInHierarchy(castType, accessSelector.getIdentifier()) == null) { 962 return false; 963 } 964 ITypeBinding bindingToCast= accessExpression.resolveTypeBinding(); 965 if (bindingToCast != null && !bindingToCast.isCastCompatible(castType)) { 966 return false; 967 } 968 969 IMethodBinding res= Bindings.findMethodInHierarchy(castType, accessSelector.getIdentifier(), paramTypes); 970 if (res != null) { 971 AST ast= expression.getAST(); 972 ASTRewrite rewrite= ASTRewrite.create(ast); 973 CastExpression newCast= ast.newCastExpression(); 974 newCast.setType((Type) ASTNode.copySubtree(ast, expression.getType())); 975 newCast.setExpression((Expression) rewrite.createCopyTarget(accessExpression)); 976 ParenthesizedExpression parents= ast.newParenthesizedExpression(); 977 parents.setExpression(newCast); 978 979 ASTNode node= rewrite.createCopyTarget(expression.getExpression()); 980 rewrite.replace(expression, node, null); 981 rewrite.replace(accessExpression, parents, null); 982 983 String label= CorrectionMessages.UnresolvedElementsSubProcessor_missingcastbrackets_description; 984 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CAST); 985 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 8, image); 986 proposals.add(proposal); 987 return true; 988 } 989 return false; 990 } 991 992 private static void addParameterMissmatchProposals(IInvocationContext context, IProblemLocation problem, List similarElements, ASTNode invocationNode, List arguments, Collection proposals) throws CoreException { 993 int nSimilarElements= similarElements.size(); 994 ITypeBinding[] argTypes= getArgumentTypes(arguments); 995 if (argTypes == null || nSimilarElements == 0) { 996 return; 997 } 998 999 for (int i= 0; i < nSimilarElements; i++) { 1000 IMethodBinding elem = (IMethodBinding) similarElements.get(i); 1001 int diff= elem.getParameterTypes().length - argTypes.length; 1002 if (diff == 0) { 1003 int nProposals= proposals.size(); 1004 doEqualNumberOfParameters(context, invocationNode, problem, arguments, argTypes, elem, proposals); 1005 if (nProposals != proposals.size()) { 1006 return; } 1008 } else if (diff > 0) { 1009 doMoreParameters(context, problem, invocationNode, arguments, argTypes, elem, proposals); 1010 } else { 1011 doMoreArguments(context, problem, invocationNode, arguments, argTypes, elem, proposals); 1012 } 1013 } 1014 } 1015 1016 private static void doMoreParameters(IInvocationContext context, IProblemLocation problem, ASTNode invocationNode, List arguments, ITypeBinding[] argTypes, IMethodBinding methodBinding, Collection proposals) throws CoreException { 1017 ITypeBinding[] paramTypes= methodBinding.getParameterTypes(); 1018 int k= 0, nSkipped= 0; 1019 int diff= paramTypes.length - argTypes.length; 1020 int[] indexSkipped= new int[diff]; 1021 for (int i= 0; i < paramTypes.length; i++) { 1022 if (k < argTypes.length && canAssign(argTypes[k], paramTypes[i])) { 1023 k++; } else { 1025 if (nSkipped >= diff) { 1026 return; } 1028 indexSkipped[nSkipped++]= i; 1029 } 1030 } 1031 ITypeBinding declaringType= methodBinding.getDeclaringClass(); 1032 ICompilationUnit cu= context.getCompilationUnit(); 1033 CompilationUnit astRoot= context.getASTRoot(); 1034 1035 { 1037 String [] arg= new String [] { ASTResolving.getMethodSignature(methodBinding, false) }; 1038 String label; 1039 if (diff == 1) { 1040 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addargument_description, arg); 1041 } else { 1042 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addarguments_description, arg); 1043 } 1044 AddArgumentCorrectionProposal proposal= new AddArgumentCorrectionProposal(label, context.getCompilationUnit(), invocationNode, indexSkipped, paramTypes, 8); 1045 proposal.setImage(JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_ADD)); 1046 proposals.add(proposal); 1047 } 1048 1049 if (!declaringType.isFromSource()) { 1051 return; 1052 } 1053 1054 ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringType); 1055 if (targetCU != null) { 1056 IMethodBinding methodDecl= methodBinding.getMethodDeclaration(); 1057 ITypeBinding[] declParameterTypes= methodDecl.getParameterTypes(); 1058 1059 ChangeDescription[] changeDesc= new ChangeDescription[declParameterTypes.length]; 1060 ITypeBinding[] changedTypes= new ITypeBinding[diff]; 1061 for (int i= diff - 1; i >= 0; i--) { 1062 int idx= indexSkipped[i]; 1063 changeDesc[idx]= new RemoveDescription(); 1064 changedTypes[i]= declParameterTypes[idx]; 1065 } 1066 String [] arg= new String [] { ASTResolving.getMethodSignature(methodDecl, !cu.equals(targetCU)), getTypeNames(changedTypes) }; 1067 String label; 1068 if (methodDecl.isConstructor()) { 1069 if (diff == 1) { 1070 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparam_constr_description, arg); 1071 } else { 1072 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparams_constr_description, arg); 1073 } 1074 } else { 1075 if (diff == 1) { 1076 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparam_description, arg); 1077 } else { 1078 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeparams_description, arg); 1079 } 1080 } 1081 1082 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_REMOVE); 1083 ChangeMethodSignatureProposal proposal= new ChangeMethodSignatureProposal(label, targetCU, invocationNode, methodDecl, changeDesc, null, 5, image); 1084 proposals.add(proposal); 1085 } 1086 } 1087 1088 private static String getTypeNames(ITypeBinding[] types) { 1089 StringBuffer buf= new StringBuffer (); 1090 for (int i= 0; i < types.length; i++) { 1091 if (i > 0) { 1092 buf.append(", "); } 1094 buf.append(ASTResolving.getTypeSignature(types[i])); 1095 } 1096 return buf.toString(); 1097 } 1098 1099 private static String getArgumentName(ICompilationUnit cu, List arguments, int index) { 1100 String def= String.valueOf(index + 1); 1101 1102 ASTNode expr= (ASTNode) arguments.get(index); 1103 if (expr.getLength() > 18) { 1104 return def; 1105 } 1106 ASTMatcher matcher= new ASTMatcher(); 1107 for (int i= 0; i < arguments.size(); i++) { 1108 if (i != index && matcher.safeSubtreeMatch(expr, arguments.get(i))) { 1109 return def; 1110 } 1111 } 1112 return '\'' + ASTNodes.asString(expr) + '\''; 1113 } 1114 1115 private static void doMoreArguments(IInvocationContext context, IProblemLocation problem, ASTNode invocationNode, List arguments, ITypeBinding[] argTypes, IMethodBinding methodRef, Collection proposals) throws CoreException { 1116 ITypeBinding[] paramTypes= methodRef.getParameterTypes(); 1117 int k= 0, nSkipped= 0; 1118 int diff= argTypes.length - paramTypes.length; 1119 int[] indexSkipped= new int[diff]; 1120 for (int i= 0; i < argTypes.length; i++) { 1121 if (k < paramTypes.length && canAssign(argTypes[i], paramTypes[k])) { 1122 k++; } else { 1124 if (nSkipped >= diff) { 1125 return; } 1127 indexSkipped[nSkipped++]= i; 1128 } 1129 } 1130 1131 ICompilationUnit cu= context.getCompilationUnit(); 1132 CompilationUnit astRoot= context.getASTRoot(); 1133 1134 { 1136 ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST()); 1137 1138 for (int i= diff - 1; i >= 0; i--) { 1139 rewrite.remove((Expression) arguments.get(indexSkipped[i]), null); 1140 } 1141 String [] arg= new String [] { ASTResolving.getMethodSignature(methodRef, false) }; 1142 String label; 1143 if (diff == 1) { 1144 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removeargument_description, arg); 1145 } else { 1146 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_removearguments_description, arg); 1147 } 1148 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_REMOVE); 1149 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 8, image); 1150 proposals.add(proposal); 1151 } 1152 1153 IMethodBinding methodDecl= methodRef.getMethodDeclaration(); 1154 ITypeBinding declaringType= methodDecl.getDeclaringClass(); 1155 1156 if (!declaringType.isFromSource()) { 1158 return; 1159 } 1160 ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringType); 1161 if (targetCU != null) { 1162 boolean isDifferentCU= !cu.equals(targetCU); 1163 1164 if (isImplicitConstructor(methodDecl, targetCU)) { 1165 return; 1166 } 1167 1168 ChangeDescription[] changeDesc= new ChangeDescription[argTypes.length]; 1169 ITypeBinding[] changeTypes= new ITypeBinding[diff]; 1170 for (int i= diff - 1; i >= 0; i--) { 1171 int idx= indexSkipped[i]; 1172 Expression arg= (Expression) arguments.get(idx); 1173 String name= arg instanceof SimpleName ? ((SimpleName) arg).getIdentifier() : null; 1174 ITypeBinding newType= Bindings.normalizeTypeBinding(argTypes[idx]); 1175 if (newType == null) { 1176 newType= astRoot.getAST().resolveWellKnownType("java.lang.Object"); } 1178 if (newType.isWildcardType()) { 1179 newType= ASTResolving.normalizeWildcardType(newType, true, astRoot.getAST()); 1180 } 1181 if (!ASTResolving.isUseableTypeInContext(newType, methodDecl, false)) { 1182 return; 1183 } 1184 changeDesc[idx]= new InsertDescription(newType, name); 1185 changeTypes[i]= newType; 1186 } 1187 String [] arg= new String [] { ASTResolving.getMethodSignature(methodDecl, isDifferentCU), getTypeNames(changeTypes) }; 1188 String label; 1189 if (methodDecl.isConstructor()) { 1190 if (diff == 1) { 1191 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addparam_constr_description, arg); 1192 } else { 1193 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addparams_constr_description, arg); 1194 } 1195 } else { 1196 if (diff == 1) { 1197 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addparam_description, arg); 1198 } else { 1199 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addparams_description, arg); 1200 } 1201 } 1202 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_ADD); 1203 ChangeMethodSignatureProposal proposal= new ChangeMethodSignatureProposal(label, targetCU, invocationNode, methodDecl, changeDesc, null, 5, image); 1204 proposals.add(proposal); 1205 } 1206 } 1207 1208 private static boolean isImplicitConstructor(IMethodBinding meth, ICompilationUnit targetCU) { 1209 return meth.isDefaultConstructor(); 1210 } 1211 1212 1213 1214 private static ITypeBinding[] getParameterTypes(List args) { 1215 ITypeBinding[] params= new ITypeBinding[args.size()]; 1216 for (int i= 0; i < args.size(); i++) { 1217 Expression expr= (Expression) args.get(i); 1218 ITypeBinding curr= Bindings.normalizeTypeBinding(expr.resolveTypeBinding()); 1219 if (curr != null && curr.isWildcardType()) { 1220 curr= ASTResolving.normalizeWildcardType(curr, true, expr.getAST()); 1221 } 1222 if (curr == null) { 1223 curr= expr.getAST().resolveWellKnownType("java.lang.Object"); } 1225 params[i]= curr; 1226 } 1227 return params; 1228 } 1229 1230 1231 1232 private static void doEqualNumberOfParameters(IInvocationContext context, ASTNode invocationNode, IProblemLocation problem, List arguments, ITypeBinding[] argTypes, IMethodBinding methodBinding, Collection proposals) throws CoreException { 1233 ITypeBinding[] paramTypes= methodBinding.getParameterTypes(); 1234 int[] indexOfDiff= new int[paramTypes.length]; 1235 int nDiffs= 0; 1236 for (int n= 0; n < argTypes.length; n++) { 1237 if (!canAssign(argTypes[n], paramTypes[n])) { 1238 indexOfDiff[nDiffs++]= n; 1239 } 1240 } 1241 ITypeBinding declaringTypeDecl= methodBinding.getDeclaringClass().getTypeDeclaration(); 1242 1243 ICompilationUnit cu= context.getCompilationUnit(); 1244 CompilationUnit astRoot= context.getASTRoot(); 1245 1246 ASTNode nameNode= problem.getCoveringNode(astRoot); 1247 if (nameNode == null) { 1248 return; 1249 } 1250 1251 if (nDiffs == 0) { 1252 if (nameNode.getParent() instanceof MethodInvocation) { 1253 MethodInvocation inv= (MethodInvocation) nameNode.getParent(); 1254 if (inv.getExpression() == null) { 1255 addQualifierToOuterProposal(context, inv, methodBinding, proposals); 1256 } 1257 } 1258 return; 1259 } 1260 1261 if (nDiffs == 1) { int idx= indexOfDiff[0]; 1263 Expression nodeToCast= (Expression) arguments.get(idx); 1264 ITypeBinding castType= paramTypes[idx]; 1265 castType= Bindings.normalizeTypeBinding(castType); 1266 if (castType.isWildcardType()) { 1267 castType= ASTResolving.normalizeWildcardType(castType, false, nodeToCast.getAST()); 1268 } 1269 if (castType != null) { 1270 ITypeBinding binding= nodeToCast.resolveTypeBinding(); 1271 if (binding == null || binding.isCastCompatible(castType)) { 1272 ASTRewriteCorrectionProposal proposal= TypeMismatchSubProcessor.createCastProposal(context, castType, nodeToCast, 6); 1273 String castTypeName= BindingLabelProvider.getBindingLabel(castType, JavaElementLabels.ALL_DEFAULT); 1274 String [] arg= new String [] { getArgumentName(cu, arguments, idx), castTypeName}; 1275 proposal.setDisplayName(Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_addargumentcast_description, arg)); 1276 proposals.add(proposal); 1277 } 1278 TypeMismatchSubProcessor.addChangeSenderTypeProposals(context, nodeToCast, castType, false, 5, proposals); 1279 } 1280 } 1281 if (nDiffs == 2) { int idx1= indexOfDiff[0]; 1283 int idx2= indexOfDiff[1]; 1284 boolean canSwap= canAssign(argTypes[idx1], paramTypes[idx2]) && canAssign(argTypes[idx2], paramTypes[idx1]); 1285 if (canSwap) { 1286 Expression arg1= (Expression) arguments.get(idx1); 1287 Expression arg2= (Expression) arguments.get(idx2); 1288 1289 ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST()); 1290 rewrite.replace(arg1, rewrite.createCopyTarget(arg2), null); 1291 rewrite.replace(arg2, rewrite.createCopyTarget(arg1), null); 1292 { 1293 String [] arg= new String [] { getArgumentName(cu, arguments, idx1), getArgumentName(cu, arguments, idx2) }; 1294 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_swaparguments_description, arg); 1295 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1296 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 8, image); 1297 proposals.add(proposal); 1298 } 1299 1300 if (declaringTypeDecl.isFromSource()) { 1301 ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringTypeDecl); 1302 if (targetCU != null) { 1303 ChangeDescription[] changeDesc= new ChangeDescription[paramTypes.length]; 1304 for (int i= 0; i < nDiffs; i++) { 1305 changeDesc[idx1]= new SwapDescription(idx2); 1306 } 1307 IMethodBinding methodDecl= methodBinding.getMethodDeclaration(); 1308 ITypeBinding[] declParamTypes= methodDecl.getParameterTypes(); 1309 1310 ITypeBinding[] swappedTypes= new ITypeBinding[] { declParamTypes[idx1], declParamTypes[idx2] }; 1311 String [] args= new String [] { ASTResolving.getMethodSignature(methodDecl, !targetCU.equals(cu)), getTypeNames(swappedTypes) }; 1312 String label; 1313 if (methodDecl.isConstructor()) { 1314 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_swapparams_constr_description, args); 1315 } else { 1316 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_swapparams_description, args); 1317 } 1318 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1319 ChangeMethodSignatureProposal proposal= new ChangeMethodSignatureProposal(label, targetCU, invocationNode, methodDecl, changeDesc, null, 5, image); 1320 proposals.add(proposal); 1321 } 1322 } 1323 return; 1324 } 1325 } 1326 1327 if (declaringTypeDecl.isFromSource()) { 1328 ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, declaringTypeDecl); 1329 if (targetCU != null) { 1330 ChangeDescription[] changeDesc= createSignatureChangeDescription(indexOfDiff, nDiffs, paramTypes, arguments, argTypes); 1331 if (changeDesc != null) { 1332 1333 IMethodBinding methodDecl= methodBinding.getMethodDeclaration(); 1334 ITypeBinding[] declParamTypes= methodDecl.getParameterTypes(); 1335 1336 ITypeBinding[] newParamTypes= new ITypeBinding[changeDesc.length]; 1337 for (int i= 0; i < newParamTypes.length; i++) { 1338 newParamTypes[i]= changeDesc[i] == null ? declParamTypes[i] : ((EditDescription) changeDesc[i]).type; 1339 } 1340 boolean isVarArgs= methodDecl.isVarargs() && newParamTypes.length > 0 && newParamTypes[newParamTypes.length - 1].isArray(); 1341 String [] args= new String [] { ASTResolving.getMethodSignature(methodDecl, !targetCU.equals(cu)), ASTResolving.getMethodSignature(methodDecl.getName(), newParamTypes, isVarArgs) }; 1342 String label; 1343 if (methodDecl.isConstructor()) { 1344 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changeparamsignature_constr_description, args); 1345 } else { 1346 label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changeparamsignature_description, args); 1347 } 1348 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1349 ChangeMethodSignatureProposal proposal= new ChangeMethodSignatureProposal(label, targetCU, invocationNode, methodDecl, changeDesc, null, 7, image); 1350 proposals.add(proposal); 1351 } 1352 } 1353 } 1354 } 1355 1356 private static ChangeDescription[] createSignatureChangeDescription(int[] indexOfDiff, int nDiffs, ITypeBinding[] paramTypes, List arguments, ITypeBinding[] argTypes) { 1357 ChangeDescription[] changeDesc= new ChangeDescription[paramTypes.length]; 1358 for (int i= 0; i < nDiffs; i++) { 1359 int diffIndex= indexOfDiff[i]; 1360 Expression arg= (Expression) arguments.get(diffIndex); 1361 String name= arg instanceof SimpleName ? ((SimpleName) arg).getIdentifier() : null; 1362 ITypeBinding argType= argTypes[diffIndex]; 1363 if (argType.isWildcardType()) { 1364 argType= ASTResolving.normalizeWildcardType(argType, true, arg.getAST()); 1365 if (argType== null) { 1366 return null; 1367 } 1368 } 1369 changeDesc[diffIndex]= new EditDescription(argType, name); 1370 } 1371 return changeDesc; 1372 } 1373 1374 private static ITypeBinding[] getArgumentTypes(List arguments) { 1375 ITypeBinding[] res= new ITypeBinding[arguments.size()]; 1376 for (int i= 0; i < res.length; i++) { 1377 Expression expression= (Expression) arguments.get(i); 1378 ITypeBinding curr= expression.resolveTypeBinding(); 1379 if (curr == null) { 1380 return null; 1381 } 1382 if (!curr.isNullType()) { curr= Bindings.normalizeTypeBinding(curr); 1384 if (curr == null) { 1385 curr= expression.getAST().resolveWellKnownType("java.lang.Object"); } 1387 } 1388 res[i]= curr; 1389 } 1390 return res; 1391 } 1392 1393 private static void addQualifierToOuterProposal(IInvocationContext context, MethodInvocation invocationNode, IMethodBinding binding, Collection proposals) throws CoreException { 1394 ITypeBinding declaringType= binding.getDeclaringClass(); 1395 ITypeBinding parentType= Bindings.getBindingOfParentType(invocationNode); 1396 ITypeBinding currType= parentType; 1397 1398 boolean isInstanceMethod= !Modifier.isStatic(binding.getModifiers()); 1399 1400 while (currType != null && !Bindings.isSuperType(declaringType, currType)) { 1401 if (isInstanceMethod && Modifier.isStatic(currType.getModifiers())) { 1402 return; 1403 } 1404 currType= currType.getDeclaringClass(); 1405 } 1406 if (currType == null || currType == parentType) { 1407 return; 1408 } 1409 1410 ASTRewrite rewrite= ASTRewrite.create(invocationNode.getAST()); 1411 1412 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changetoouter_description, ASTResolving.getTypeSignature(currType)); 1413 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1414 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 8, image); 1415 1416 ImportRewrite imports= proposal.createImportRewrite(context.getASTRoot()); 1417 AST ast= invocationNode.getAST(); 1418 1419 String qualifier= imports.addImport(currType); 1420 Name name= ASTNodeFactory.newName(ast, qualifier); 1421 1422 Expression newExpression; 1423 if (isInstanceMethod) { 1424 ThisExpression expr= ast.newThisExpression(); 1425 expr.setQualifier(name); 1426 newExpression= expr; 1427 } else { 1428 newExpression= name; 1429 } 1430 1431 rewrite.set(invocationNode, MethodInvocation.EXPRESSION_PROPERTY, newExpression, null); 1432 1433 proposals.add(proposal); 1434 } 1435 1436 1437 public static void getConstructorProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) throws CoreException { 1438 ICompilationUnit cu= context.getCompilationUnit(); 1439 1440 CompilationUnit astRoot= context.getASTRoot(); 1441 ASTNode selectedNode= problem.getCoveringNode(astRoot); 1442 if (selectedNode == null) { 1443 return; 1444 } 1445 1446 ITypeBinding targetBinding= null; 1447 List arguments= null; 1448 IMethodBinding recursiveConstructor= null; 1449 1450 int type= selectedNode.getNodeType(); 1451 if (type == ASTNode.CLASS_INSTANCE_CREATION) { 1452 ClassInstanceCreation creation= (ClassInstanceCreation) selectedNode; 1453 1454 IBinding binding= creation.getType().resolveBinding(); 1455 if (binding instanceof ITypeBinding) { 1456 targetBinding= (ITypeBinding) binding; 1457 arguments= creation.arguments(); 1458 } 1459 } else if (type == ASTNode.SUPER_CONSTRUCTOR_INVOCATION) { 1460 ITypeBinding typeBinding= Bindings.getBindingOfParentType(selectedNode); 1461 if (typeBinding != null && !typeBinding.isAnonymous()) { 1462 targetBinding= typeBinding.getSuperclass(); 1463 arguments= ((SuperConstructorInvocation) selectedNode).arguments(); 1464 } 1465 } else if (type == ASTNode.CONSTRUCTOR_INVOCATION) { 1466 ITypeBinding typeBinding= Bindings.getBindingOfParentType(selectedNode); 1467 if (typeBinding != null && !typeBinding.isAnonymous()) { 1468 targetBinding= typeBinding; 1469 arguments= ((ConstructorInvocation) selectedNode).arguments(); 1470 recursiveConstructor= ASTResolving.findParentMethodDeclaration(selectedNode).resolveBinding(); 1471 } 1472 } 1473 if (targetBinding == null) { 1474 return; 1475 } 1476 IMethodBinding[] methods= targetBinding.getDeclaredMethods(); 1477 ArrayList similarElements= new ArrayList (); 1478 for (int i= 0; i < methods.length; i++) { 1479 IMethodBinding curr= methods[i]; 1480 if (curr.isConstructor() && recursiveConstructor != curr) { 1481 similarElements.add(curr); } 1483 } 1484 1485 addParameterMissmatchProposals(context, problem, similarElements, selectedNode, arguments, proposals); 1486 1487 if (targetBinding.isFromSource()) { 1488 ITypeBinding targetDecl= targetBinding.getTypeDeclaration(); 1489 1490 ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, targetDecl); 1491 if (targetCU != null) { 1492 String [] args= new String [] { ASTResolving.getMethodSignature( ASTResolving.getTypeSignature(targetDecl), getParameterTypes(arguments), false) }; 1493 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_createconstructor_description, args); 1494 Image image= JavaElementImageProvider.getDecoratedImage(JavaPluginImages.DESC_MISC_PUBLIC, JavaElementImageDescriptor.CONSTRUCTOR, JavaElementImageProvider.SMALL_SIZE); 1495 proposals.add(new NewMethodCompletionProposal(label, targetCU, selectedNode, arguments, targetDecl, 5, image)); 1496 } 1497 } 1498 } 1499 1500 public static void getAmbiguosTypeReferenceProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) throws CoreException { 1501 final ICompilationUnit cu= context.getCompilationUnit(); 1502 int offset= problem.getOffset(); 1503 int len= problem.getLength(); 1504 1505 IJavaElement[] elements= cu.codeSelect(offset, len); 1506 for (int i= 0; i < elements.length; i++) { 1507 IJavaElement curr= elements[i]; 1508 if (curr instanceof IType && !TypeFilter.isFiltered((IType) curr)) { 1509 String qualifiedTypeName= JavaModelUtil.getFullyQualifiedName((IType) curr); 1510 1511 CompilationUnit root= context.getASTRoot(); 1512 1513 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_importexplicit_description, qualifiedTypeName); 1514 Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_IMPDECL); 1515 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, ASTRewrite.create(root.getAST()), 5, image); 1516 1517 ImportRewrite imports= proposal.createImportRewrite(root); 1518 imports.addImport(qualifiedTypeName); 1519 1520 proposals.add(proposal); 1521 } 1522 } 1523 } 1524 1525 public static void getArrayAccessProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) { 1526 1527 CompilationUnit root= context.getASTRoot(); 1528 ASTNode selectedNode= problem.getCoveringNode(root); 1529 if (!(selectedNode instanceof MethodInvocation)) { 1530 return; 1531 } 1532 1533 MethodInvocation decl= (MethodInvocation) selectedNode; 1534 SimpleName nameNode= decl.getName(); 1535 String methodName= nameNode.getIdentifier(); 1536 1537 IBinding[] bindings= (new ScopeAnalyzer(root)).getDeclarationsInScope(nameNode, ScopeAnalyzer.METHODS); 1538 for (int i= 0; i < bindings.length; i++) { 1539 String currName= bindings[i].getName(); 1540 if (NameMatcher.isSimilarName(methodName, currName)) { 1541 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_arraychangetomethod_description, currName); 1542 proposals.add(new RenameNodeCompletionProposal(label, context.getCompilationUnit(), nameNode.getStartPosition(), nameNode.getLength(), currName, 6)); 1543 } 1544 } 1545 String lengthId= "length"; String label= CorrectionMessages.UnresolvedElementsSubProcessor_arraychangetolength_description; 1548 int offset= nameNode.getStartPosition(); 1549 int length= decl.getStartPosition() + decl.getLength() - offset; 1550 proposals.add(new RenameNodeCompletionProposal(label, context.getCompilationUnit(), offset, length, lengthId, 7)); 1551 } 1552 1553 public static void getAnnotationMemberProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) throws CoreException { 1554 CompilationUnit astRoot= context.getASTRoot(); 1555 ICompilationUnit cu= context.getCompilationUnit(); 1556 ASTNode selectedNode= problem.getCoveringNode(astRoot); 1557 1558 Annotation annotation; 1559 String memberName; 1560 if (selectedNode.getLocationInParent() == MemberValuePair.NAME_PROPERTY) { 1561 if (selectedNode.getParent().getLocationInParent() != NormalAnnotation.VALUES_PROPERTY) { 1562 return; 1563 } 1564 annotation= (Annotation) selectedNode.getParent().getParent(); 1565 memberName= ((SimpleName) selectedNode).getIdentifier(); 1566 } else if (selectedNode.getLocationInParent() == SingleMemberAnnotation.VALUE_PROPERTY) { 1567 annotation= (Annotation) selectedNode.getParent(); 1568 memberName= "value"; } else { 1570 return; 1571 } 1572 1573 ITypeBinding annotBinding= annotation.resolveTypeBinding(); 1574 if (annotBinding == null) { 1575 return; 1576 } 1577 1578 1579 if (annotation instanceof NormalAnnotation) { 1580 IMethodBinding[] otherMembers= annotBinding.getDeclaredMethods(); 1582 for (int i= 0; i < otherMembers.length; i++) { 1583 IMethodBinding binding= otherMembers[i]; 1584 String curr= binding.getName(); 1585 int relevance= NameMatcher.isSimilarName(memberName, curr) ? 6 : 3; 1586 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_UnresolvedElementsSubProcessor_changetoattribute_description, curr); 1587 proposals.add(new RenameNodeCompletionProposal(label, cu, problem.getOffset(), problem.getLength(), curr, relevance)); 1588 } 1589 } 1590 1591 if (annotBinding.isFromSource()) { 1592 ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, astRoot, annotBinding); 1593 if (targetCU != null) { 1594 String label= Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_UnresolvedElementsSubProcessor_createattribute_description, memberName); 1595 Image image= JavaPluginImages.get(JavaPluginImages.IMG_MISC_PUBLIC); 1596 proposals.add(new NewAnnotationMemberProposal(label, targetCU, selectedNode, annotBinding, 5, image)); 1597 } 1598 } 1599 } 1600 1601 1602} 1603 | Popular Tags |