1 11 package org.eclipse.jdt.internal.ui.text.correction; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.util.Collection ; 15 import java.util.Hashtable ; 16 import java.util.List ; 17 import java.util.Map ; 18 19 import org.eclipse.text.edits.MultiTextEdit; 20 import org.eclipse.text.edits.ReplaceEdit; 21 import org.eclipse.text.edits.TextEdit; 22 23 import org.eclipse.core.runtime.Assert; 24 import org.eclipse.core.runtime.CoreException; 25 import org.eclipse.core.runtime.IStatus; 26 import org.eclipse.core.runtime.Status; 27 28 import org.eclipse.swt.graphics.Image; 29 import org.eclipse.swt.widgets.Display; 30 31 import org.eclipse.jface.text.BadLocationException; 32 import org.eclipse.jface.text.IDocument; 33 import org.eclipse.jface.text.link.LinkedModeModel; 34 import org.eclipse.jface.text.link.LinkedPosition; 35 36 import org.eclipse.ui.IWorkbenchWindow; 37 import org.eclipse.ui.PlatformUI; 38 39 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 40 41 import org.eclipse.jdt.core.Flags; 42 import org.eclipse.jdt.core.ICompilationUnit; 43 import org.eclipse.jdt.core.IField; 44 import org.eclipse.jdt.core.IJavaElement; 45 import org.eclipse.jdt.core.JavaModelException; 46 import org.eclipse.jdt.core.compiler.IProblem; 47 import org.eclipse.jdt.core.dom.AST; 48 import org.eclipse.jdt.core.dom.ASTNode; 49 import org.eclipse.jdt.core.dom.Annotation; 50 import org.eclipse.jdt.core.dom.Assignment; 51 import org.eclipse.jdt.core.dom.Block; 52 import org.eclipse.jdt.core.dom.CastExpression; 53 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 54 import org.eclipse.jdt.core.dom.CompilationUnit; 55 import org.eclipse.jdt.core.dom.Expression; 56 import org.eclipse.jdt.core.dom.FieldAccess; 57 import org.eclipse.jdt.core.dom.IBinding; 58 import org.eclipse.jdt.core.dom.IMethodBinding; 59 import org.eclipse.jdt.core.dom.ITypeBinding; 60 import org.eclipse.jdt.core.dom.IVariableBinding; 61 import org.eclipse.jdt.core.dom.InfixExpression; 62 import org.eclipse.jdt.core.dom.Javadoc; 63 import org.eclipse.jdt.core.dom.MethodDeclaration; 64 import org.eclipse.jdt.core.dom.MethodInvocation; 65 import org.eclipse.jdt.core.dom.Modifier; 66 import org.eclipse.jdt.core.dom.Name; 67 import org.eclipse.jdt.core.dom.NumberLiteral; 68 import org.eclipse.jdt.core.dom.ParenthesizedExpression; 69 import org.eclipse.jdt.core.dom.PostfixExpression; 70 import org.eclipse.jdt.core.dom.PrefixExpression; 71 import org.eclipse.jdt.core.dom.PrimitiveType; 72 import org.eclipse.jdt.core.dom.QualifiedName; 73 import org.eclipse.jdt.core.dom.ReturnStatement; 74 import org.eclipse.jdt.core.dom.SimpleName; 75 import org.eclipse.jdt.core.dom.SimpleType; 76 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 77 import org.eclipse.jdt.core.dom.SuperFieldAccess; 78 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 79 import org.eclipse.jdt.core.dom.TagElement; 80 import org.eclipse.jdt.core.dom.Type; 81 import org.eclipse.jdt.core.dom.TypeDeclaration; 82 import org.eclipse.jdt.core.dom.Assignment.Operator; 83 import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; 84 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 85 import org.eclipse.jdt.core.formatter.IndentManipulation; 86 87 import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil; 88 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 89 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 90 import org.eclipse.jdt.internal.corext.dom.Bindings; 91 import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; 92 import org.eclipse.jdt.internal.corext.fix.IFix; 93 import org.eclipse.jdt.internal.corext.fix.Java50Fix; 94 import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel; 95 import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup; 96 import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester; 97 import org.eclipse.jdt.internal.corext.refactoring.sef.SelfEncapsulateFieldRefactoring; 98 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 99 import org.eclipse.jdt.internal.corext.util.JdtFlags; 100 import org.eclipse.jdt.internal.corext.util.Messages; 101 102 import org.eclipse.jdt.ui.JavaUI; 103 import org.eclipse.jdt.ui.text.java.IInvocationContext; 104 import org.eclipse.jdt.ui.text.java.IProblemLocation; 105 106 import org.eclipse.jdt.internal.ui.JavaPlugin; 107 import org.eclipse.jdt.internal.ui.JavaPluginImages; 108 import org.eclipse.jdt.internal.ui.fix.Java50CleanUp; 109 import org.eclipse.jdt.internal.ui.refactoring.RefactoringExecutionHelper; 110 import org.eclipse.jdt.internal.ui.refactoring.RefactoringSaveHelper; 111 import org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter; 112 import org.eclipse.jdt.internal.ui.refactoring.sef.SelfEncapsulateFieldWizard; 113 import org.eclipse.jdt.internal.ui.util.ExceptionHandler; 114 115 117 public class ModifierCorrectionSubProcessor { 118 119 120 public static final int TO_STATIC= 1; 121 public static final int TO_VISIBLE= 2; 122 public static final int TO_NON_PRIVATE= 3; 123 public static final int TO_NON_STATIC= 4; 124 public static final int TO_NON_FINAL= 5; 125 126 public static void addNonAccessibleReferenceProposal(IInvocationContext context, IProblemLocation problem, Collection proposals, int kind, int relevance) throws CoreException { 127 ICompilationUnit cu= context.getCompilationUnit(); 128 129 ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); 130 if (selectedNode == null) { 131 return; 132 } 133 134 IBinding binding=null; 135 switch (selectedNode.getNodeType()) { 136 case ASTNode.SIMPLE_NAME: 137 binding= ((SimpleName) selectedNode).resolveBinding(); 138 break; 139 case ASTNode.QUALIFIED_NAME: 140 binding= ((QualifiedName) selectedNode).resolveBinding(); 141 break; 142 case ASTNode.SIMPLE_TYPE: 143 binding= ((SimpleType) selectedNode).resolveBinding(); 144 break; 145 case ASTNode.METHOD_INVOCATION: 146 binding= ((MethodInvocation) selectedNode).getName().resolveBinding(); 147 break; 148 case ASTNode.SUPER_METHOD_INVOCATION: 149 binding= ((SuperMethodInvocation) selectedNode).getName().resolveBinding(); 150 break; 151 case ASTNode.FIELD_ACCESS: 152 binding= ((FieldAccess) selectedNode).getName().resolveBinding(); 153 break; 154 case ASTNode.SUPER_FIELD_ACCESS: 155 binding= ((SuperFieldAccess) selectedNode).getName().resolveBinding(); 156 break; 157 case ASTNode.CLASS_INSTANCE_CREATION: 158 binding= ((ClassInstanceCreation) selectedNode).resolveConstructorBinding(); 159 break; 160 case ASTNode.SUPER_CONSTRUCTOR_INVOCATION: 161 binding= ((SuperConstructorInvocation) selectedNode).resolveConstructorBinding(); 162 break; 163 default: 164 return; 165 } 166 ITypeBinding typeBinding= null; 167 String name; 168 IBinding bindingDecl; 169 boolean isLocalVar= false; 170 if (binding instanceof IMethodBinding) { 171 IMethodBinding methodDecl= (IMethodBinding) binding; 172 bindingDecl= methodDecl.getMethodDeclaration(); 173 typeBinding= methodDecl.getDeclaringClass(); 174 name= methodDecl.getName() + "()"; } else if (binding instanceof IVariableBinding) { 176 IVariableBinding varDecl= (IVariableBinding) binding; 177 typeBinding= varDecl.getDeclaringClass(); 178 name= binding.getName(); 179 isLocalVar= !varDecl.isField(); 180 bindingDecl= varDecl.getVariableDeclaration(); 181 } else if (binding instanceof ITypeBinding) { 182 typeBinding= (ITypeBinding) binding; 183 bindingDecl= typeBinding.getTypeDeclaration(); 184 name= binding.getName(); 185 } else { 186 return; 187 } 188 if (typeBinding != null && typeBinding.isFromSource() || isLocalVar) { 189 int includedModifiers= 0; 190 int excludedModifiers= 0; 191 String label; 192 switch (kind) { 193 case TO_VISIBLE: 194 excludedModifiers= Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC; 195 includedModifiers= getNeededVisibility(selectedNode, typeBinding); 196 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changevisibility_description, new String [] { name, getVisibilityString(includedModifiers) }); 197 break; 198 case TO_STATIC: 199 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertostatic_description, name); 200 includedModifiers= Modifier.STATIC; 201 break; 202 case TO_NON_STATIC: 203 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertononstatic_description, name); 204 excludedModifiers= Modifier.STATIC; 205 break; 206 case TO_NON_PRIVATE: 207 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertodefault_description, name); 208 excludedModifiers= Modifier.PRIVATE; 209 break; 210 case TO_NON_FINAL: 211 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertononfinal_description, name); 212 excludedModifiers= Modifier.FINAL; 213 break; 214 default: 215 throw new IllegalArgumentException ("not supported"); } 217 ICompilationUnit targetCU= isLocalVar ? cu : ASTResolving.findCompilationUnitForBinding(cu, context.getASTRoot(), typeBinding.getTypeDeclaration()); 218 if (targetCU != null) { 219 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 220 proposals.add(new ModifierChangeCompletionProposal(label, targetCU, bindingDecl, selectedNode, includedModifiers, excludedModifiers, relevance, image)); 221 } 222 } 223 if (kind == TO_VISIBLE && bindingDecl.getKind() == IBinding.VARIABLE) { 224 UnresolvedElementsSubProcessor.getVariableProposals(context, problem, (IVariableBinding) bindingDecl, proposals); 225 } 226 } 227 228 public static void addChangeOverriddenModfierProposal(IInvocationContext context, IProblemLocation problem, Collection proposals, int kind) throws JavaModelException { 229 ICompilationUnit cu= context.getCompilationUnit(); 230 231 ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); 232 if (!(selectedNode instanceof MethodDeclaration)) { 233 return; 234 } 235 236 IMethodBinding method= ((MethodDeclaration) selectedNode).resolveBinding(); 237 ITypeBinding curr= method.getDeclaringClass(); 238 239 240 if (kind == TO_VISIBLE && problem.getProblemId() != IProblem.OverridingNonVisibleMethod) { 241 IMethodBinding defining= Bindings.findOverriddenMethod(method, false); 242 if (defining != null) { 243 int excludedModifiers= Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC; 244 int includedModifiers= JdtFlags.getVisibilityCode(defining); 245 String label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemethodvisibility_description, new String [] { getVisibilityString(includedModifiers) }); 246 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 247 proposals.add(new ModifierChangeCompletionProposal(label, cu, method, selectedNode, includedModifiers, excludedModifiers, 8, image)); 248 } 249 } 250 251 IMethodBinding overriddenInClass= null; 252 while (overriddenInClass == null && curr.getSuperclass() != null) { 253 curr= curr.getSuperclass(); 254 overriddenInClass= Bindings.findOverriddenMethodInType(curr, method); 255 } 256 if (overriddenInClass != null) { 257 IMethodBinding overriddenDecl= overriddenInClass.getMethodDeclaration(); 258 ICompilationUnit targetCU= ASTResolving.findCompilationUnitForBinding(cu, context.getASTRoot(), overriddenDecl.getDeclaringClass()); 259 if (targetCU != null) { 260 String methodName= curr.getName() + '.' + overriddenInClass.getName(); 261 String label; 262 int excludedModifiers; 263 int includedModifiers; 264 switch (kind) { 265 case TO_VISIBLE: 266 excludedModifiers= Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC; 267 includedModifiers= JdtFlags.getVisibilityCode(method); 268 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changeoverriddenvisibility_description, new String [] { methodName, getVisibilityString(includedModifiers) }); 269 break; 270 case TO_NON_FINAL: 271 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemethodtononfinal_description, methodName); 272 excludedModifiers= Modifier.FINAL; 273 includedModifiers= 0; 274 break; 275 case TO_NON_STATIC: 276 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemethodtononstatic_description, methodName); 277 excludedModifiers= Modifier.STATIC; 278 includedModifiers= 0; 279 break; 280 default: 281 Assert.isTrue(false, "not supported"); return; 283 } 284 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 285 proposals.add(new ModifierChangeCompletionProposal(label, targetCU, overriddenDecl, selectedNode, includedModifiers, excludedModifiers, 7, image)); 286 } 287 } 288 } 289 290 public static void addNonFinalLocalProposal(IInvocationContext context, IProblemLocation problem, Collection proposals) { 291 ICompilationUnit cu= context.getCompilationUnit(); 292 293 ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); 294 if (!(selectedNode instanceof SimpleName)) { 295 return; 296 } 297 298 IBinding binding= ((SimpleName) selectedNode).resolveBinding(); 299 if (binding instanceof IVariableBinding) { 300 binding= ((IVariableBinding) binding).getVariableDeclaration(); 301 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 302 String label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertofinal_description, binding.getName()); 303 proposals.add(new ModifierChangeCompletionProposal(label, cu, binding, selectedNode, Modifier.FINAL, 0, 5, image)); 304 } 305 } 306 307 308 309 public static void addRemoveInvalidModfiersProposal(IInvocationContext context, IProblemLocation problem, Collection proposals, int relevance) { 310 ICompilationUnit cu= context.getCompilationUnit(); 311 312 ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); 313 if (selectedNode instanceof MethodDeclaration) { 314 selectedNode= ((MethodDeclaration) selectedNode).getName(); 315 } 316 317 if (!(selectedNode instanceof SimpleName)) { 318 return; 319 } 320 321 IBinding binding= ((SimpleName) selectedNode).resolveBinding(); 322 if (binding != null) { 323 String methodName= binding.getName(); 324 String label= null; 325 int problemId= problem.getProblemId(); 326 327 328 int excludedModifiers= 0; 329 int includedModifiers= 0; 330 331 switch (problemId) { 332 case IProblem.CannotHideAnInstanceMethodWithAStaticMethod: 333 case IProblem.UnexpectedStaticModifierForMethod: 334 excludedModifiers= Modifier.STATIC; 335 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemethodtononstatic_description, methodName); 336 break; 337 case IProblem.UnexpectedStaticModifierForField: 338 excludedModifiers= Modifier.STATIC; 339 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changefieldmodifiertononstatic_description, methodName); 340 break; 341 case IProblem.IllegalModifierCombinationFinalVolatileForField: 342 excludedModifiers= Modifier.VOLATILE; 343 label= CorrectionMessages.ModifierCorrectionSubProcessor_removevolatile_description; 344 break; 345 case IProblem.IllegalModifierForInterfaceMethod: 346 excludedModifiers= ~(Modifier.PUBLIC | Modifier.ABSTRACT); 347 break; 348 case IProblem.IllegalModifierForInterface: 349 excludedModifiers= ~(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STRICTFP); 350 break; 351 case IProblem.IllegalModifierForClass: 352 excludedModifiers= ~(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.FINAL | Modifier.STRICTFP); 353 break; 354 case IProblem.IllegalModifierForInterfaceField: 355 excludedModifiers= ~(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.FINAL); 356 break; 357 case IProblem.IllegalModifierForMemberInterface: 358 case IProblem.IllegalVisibilityModifierForInterfaceMemberType: 359 excludedModifiers= ~(Modifier.PUBLIC | Modifier.STATIC | Modifier.STRICTFP); 360 break; 361 case IProblem.IllegalModifierForMemberClass: 362 excludedModifiers= ~(Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | Modifier.STATIC | Modifier.ABSTRACT | Modifier.FINAL | Modifier.STRICTFP); 363 break; 364 case IProblem.IllegalModifierForLocalClass: 365 excludedModifiers= ~(Modifier.ABSTRACT | Modifier.FINAL | Modifier.STRICTFP); 366 break; 367 case IProblem.IllegalModifierForArgument: 368 excludedModifiers= ~Modifier.FINAL; 369 break; 370 case IProblem.IllegalModifierForField: 371 excludedModifiers= ~(Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE | Modifier.TRANSIENT); 372 break; 373 case IProblem.IllegalModifierForMethod: 374 excludedModifiers= ~(Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | Modifier.STATIC | Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE | Modifier.STRICTFP); 375 if (((IMethodBinding) binding).isConstructor()) { 376 excludedModifiers |= Modifier.STATIC; 377 } 378 break; 379 case IProblem.IllegalModifierForVariable: 380 excludedModifiers= ~Modifier.FINAL; 381 break; 382 default: 383 Assert.isTrue(false, "not supported"); return; 385 } 386 387 if (label == null) 388 label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_removeinvalidmodifiers_description, methodName); 389 390 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 391 proposals.add(new ModifierChangeCompletionProposal(label, cu, binding, selectedNode, includedModifiers, excludedModifiers, relevance, image)); 392 393 if (problemId == IProblem.IllegalModifierCombinationFinalVolatileForField) { 394 proposals.add(new ModifierChangeCompletionProposal(CorrectionMessages.ModifierCorrectionSubProcessor_removefinal_description, cu, binding, selectedNode, 0, Modifier.FINAL, relevance + 1, image)); 395 } 396 397 if (problemId == IProblem.UnexpectedStaticModifierForField && binding instanceof IVariableBinding) { 398 ITypeBinding declClass= ((IVariableBinding) binding).getDeclaringClass(); 399 if (declClass.isMember()) { 400 proposals.add(new ModifierChangeCompletionProposal(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertostaticfinal_description, cu, binding, selectedNode, Modifier.FINAL, Modifier.VOLATILE, relevance + 1, image)); 401 ASTNode parentType= context.getASTRoot().findDeclaringNode(declClass); 402 if (parentType != null) { 403 proposals.add(new ModifierChangeCompletionProposal(CorrectionMessages.ModifierCorrectionSubProcessor_addstatictoparenttype_description, cu, declClass, parentType, Modifier.STATIC, 0, relevance - 1, image)); 404 } 405 } 406 } 407 if (problemId == IProblem.UnexpectedStaticModifierForMethod && binding instanceof IMethodBinding) { 408 ITypeBinding declClass= ((IMethodBinding) binding).getDeclaringClass(); 409 if (declClass.isMember()) { 410 ASTNode parentType= context.getASTRoot().findDeclaringNode(declClass); 411 if (parentType != null) { 412 proposals.add(new ModifierChangeCompletionProposal(CorrectionMessages.ModifierCorrectionSubProcessor_addstatictoparenttype_description, cu, declClass, parentType, Modifier.STATIC, 0, relevance - 1, image)); 413 } 414 } 415 } 416 } 417 } 418 419 private static String getVisibilityString(int code) { 420 if (Modifier.isPublic(code)) { 421 return "public"; } else if (Modifier.isProtected(code)) { 423 return "protected"; } else if (Modifier.isPrivate(code)) { 425 return "private"; } 427 return CorrectionMessages.ModifierCorrectionSubProcessor_default; 428 } 429 430 431 private static int getNeededVisibility(ASTNode currNode, ITypeBinding targetType) { 432 ITypeBinding currNodeBinding= Bindings.getBindingOfParentType(currNode); 433 if (currNodeBinding == null) { return Modifier.PUBLIC; 435 } 436 437 if (Bindings.isSuperType(targetType, currNodeBinding)) { 438 return Modifier.PROTECTED; 439 } 440 441 if (currNodeBinding.getPackage().getKey().equals(targetType.getPackage().getKey())) { 442 return 0; 443 } 444 return Modifier.PUBLIC; 445 } 446 447 public static void addAbstractMethodProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) { 448 ICompilationUnit cu= context.getCompilationUnit(); 449 450 CompilationUnit astRoot= context.getASTRoot(); 451 452 ASTNode selectedNode= problem.getCoveringNode(astRoot); 453 if (selectedNode == null) { 454 return; 455 } 456 MethodDeclaration decl; 457 if (selectedNode instanceof SimpleName) { 458 decl= (MethodDeclaration) selectedNode.getParent(); 459 } else if (selectedNode instanceof MethodDeclaration) { 460 decl= (MethodDeclaration) selectedNode; 461 } else { 462 return; 463 } 464 465 ASTNode parentType= ASTResolving.findParentType(decl); 466 TypeDeclaration parentTypeDecl= null; 467 boolean parentIsAbstractClass= false; 468 if (parentType instanceof TypeDeclaration) { 469 parentTypeDecl= (TypeDeclaration) parentType; 470 parentIsAbstractClass= !parentTypeDecl.isInterface() && Modifier.isAbstract(parentTypeDecl.getModifiers()); 471 } 472 boolean hasNoBody= (decl.getBody() == null); 473 474 if (problem.getProblemId() == IProblem.AbstractMethodInAbstractClass || parentIsAbstractClass) { 475 AST ast= astRoot.getAST(); 476 ASTRewrite rewrite= ASTRewrite.create(ast); 477 478 Modifier modifierNode= ASTNodes.findModifierNode(Modifier.ABSTRACT, decl.modifiers()); 479 if (modifierNode != null) { 480 rewrite.remove(modifierNode, null); 481 } 482 483 if (hasNoBody) { 484 Block newBody= ast.newBlock(); 485 rewrite.set(decl, MethodDeclaration.BODY_PROPERTY, newBody, null); 486 487 Expression expr= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions()); 488 if (expr != null) { 489 ReturnStatement returnStatement= ast.newReturnStatement(); 490 returnStatement.setExpression(expr); 491 newBody.statements().add(returnStatement); 492 } 493 } 494 495 String label= CorrectionMessages.ModifierCorrectionSubProcessor_removeabstract_description; 496 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 497 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 6, image); 498 proposals.add(proposal); 499 } 500 501 if (!hasNoBody && problem.getProblemId() == IProblem.BodyForAbstractMethod) { 502 ASTRewrite rewrite= ASTRewrite.create(decl.getAST()); 503 rewrite.remove(decl.getBody(), null); 504 505 String label= CorrectionMessages.ModifierCorrectionSubProcessor_removebody_description; 506 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 507 ASTRewriteCorrectionProposal proposal2= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image); 508 proposals.add(proposal2); 509 } 510 511 if (problem.getProblemId() == IProblem.AbstractMethodInAbstractClass && (parentTypeDecl != null)) { 512 ASTRewriteCorrectionProposal proposal= getMakeTypeAbstractProposal(cu, parentTypeDecl, 5); 513 proposals.add(proposal); 514 } 515 516 } 517 518 public static void addNativeMethodProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) { 519 ICompilationUnit cu= context.getCompilationUnit(); 520 521 CompilationUnit astRoot= context.getASTRoot(); 522 523 ASTNode selectedNode= problem.getCoveringNode(astRoot); 524 if (selectedNode == null) { 525 return; 526 } 527 MethodDeclaration decl; 528 if (selectedNode instanceof SimpleName) { 529 decl= (MethodDeclaration) selectedNode.getParent(); 530 } else if (selectedNode instanceof MethodDeclaration) { 531 decl= (MethodDeclaration) selectedNode; 532 } else { 533 return; 534 } 535 536 { 537 AST ast= astRoot.getAST(); 538 ASTRewrite rewrite= ASTRewrite.create(ast); 539 540 Modifier modifierNode= ASTNodes.findModifierNode(Modifier.NATIVE, decl.modifiers()); 541 if (modifierNode != null) { 542 rewrite.remove(modifierNode, null); 543 } 544 545 Block newBody= ast.newBlock(); 546 rewrite.set(decl, MethodDeclaration.BODY_PROPERTY, newBody, null); 547 548 Expression expr= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions()); 549 if (expr != null) { 550 ReturnStatement returnStatement= ast.newReturnStatement(); 551 returnStatement.setExpression(expr); 552 newBody.statements().add(returnStatement); 553 } 554 555 String label= CorrectionMessages.ModifierCorrectionSubProcessor_removenative_description; 556 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 557 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 6, image); 558 proposals.add(proposal); 559 } 560 561 if (decl.getBody() != null) { 562 ASTRewrite rewrite= ASTRewrite.create(decl.getAST()); 563 rewrite.remove(decl.getBody(), null); 564 565 String label= CorrectionMessages.ModifierCorrectionSubProcessor_removebody_description; 566 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 567 ASTRewriteCorrectionProposal proposal2= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image); 568 proposals.add(proposal2); 569 } 570 571 } 572 573 574 575 public static ASTRewriteCorrectionProposal getMakeTypeAbstractProposal(ICompilationUnit cu, TypeDeclaration typeDeclaration, int relevance) { 576 AST ast= typeDeclaration.getAST(); 577 ASTRewrite rewrite= ASTRewrite.create(ast); 578 Modifier newModifier= ast.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD); 579 rewrite.getListRewrite(typeDeclaration, TypeDeclaration.MODIFIERS2_PROPERTY).insertLast(newModifier, null); 580 581 String label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_addabstract_description, typeDeclaration.getName().getIdentifier()); 582 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 583 LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, relevance, image); 584 proposal.addLinkedPosition(rewrite.track(newModifier), true, "modifier"); return proposal; 586 } 587 588 public static void addMethodRequiresBodyProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) { 589 ICompilationUnit cu= context.getCompilationUnit(); 590 AST ast= context.getASTRoot().getAST(); 591 592 ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); 593 if (!(selectedNode instanceof MethodDeclaration)) { 594 return; 595 } 596 MethodDeclaration decl= (MethodDeclaration) selectedNode; 597 { 598 ASTRewrite rewrite= ASTRewrite.create(ast); 599 600 Modifier modifierNode= ASTNodes.findModifierNode(Modifier.ABSTRACT, decl.modifiers()); 601 if (modifierNode != null) { 602 rewrite.remove(modifierNode, null); 603 } 604 605 Block body= ast.newBlock(); 606 rewrite.set(decl, MethodDeclaration.BODY_PROPERTY, body, null); 607 608 609 if (!decl.isConstructor()) { 610 Type returnType= decl.getReturnType2(); 611 Expression expression= ASTNodeFactory.newDefaultExpression(ast, returnType, decl.getExtraDimensions()); 612 if (expression != null) { 613 ReturnStatement returnStatement= ast.newReturnStatement(); 614 returnStatement.setExpression(expression); 615 body.statements().add(returnStatement); 616 } 617 } 618 619 String label= CorrectionMessages.ModifierCorrectionSubProcessor_addmissingbody_description; 620 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 621 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 9, image); 622 623 proposals.add(proposal); 624 } 625 { 626 ASTRewrite rewrite= ASTRewrite.create(ast); 627 628 Modifier newModifier= ast.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD); 629 rewrite.getListRewrite(decl, MethodDeclaration.MODIFIERS2_PROPERTY).insertLast(newModifier, null); 630 631 String label= CorrectionMessages.ModifierCorrectionSubProcessor_setmethodabstract_description; 632 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 633 LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 8, image); 634 proposal.addLinkedPosition(rewrite.track(newModifier), true, "modifier"); 636 proposals.add(proposal); 637 } 638 639 } 640 641 642 public static void addNeedToEmulateProposal(IInvocationContext context, IProblemLocation problem, Collection proposals) { 643 ICompilationUnit cu= context.getCompilationUnit(); 644 645 ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); 646 if (!(selectedNode instanceof SimpleName)) { 647 return; 648 } 649 650 IBinding binding= ((SimpleName) selectedNode).resolveBinding(); 651 if (binding instanceof IVariableBinding) { 652 binding= ((IVariableBinding) binding).getVariableDeclaration(); 653 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 654 String label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifiertofinal_description, binding.getName()); 655 proposals.add(new ModifierChangeCompletionProposal(label, cu, binding, selectedNode, Modifier.FINAL, 0, 5, image)); 656 } 657 } 658 659 public static void addOverrideAnnotationProposal(IInvocationContext context, IProblemLocation problem, Collection proposals) throws CoreException { 660 IFix fix= Java50Fix.createAddOverrideAnnotationFix(context.getASTRoot(), problem); 661 if (fix != null) { 662 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 663 Map options= new Hashtable (); 664 options.put(CleanUpConstants.ADD_MISSING_ANNOTATIONS, CleanUpConstants.TRUE); 665 options.put(CleanUpConstants.ADD_MISSING_ANNOTATIONS_OVERRIDE, CleanUpConstants.TRUE); 666 FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new Java50CleanUp(options), 5, image, context); 667 proposals.add(proposal); 668 } 669 } 670 671 public static void addDeprecatedAnnotationProposal(IInvocationContext context, IProblemLocation problem, Collection proposals) throws CoreException { 672 IFix fix= Java50Fix.createAddDeprectatedAnnotation(context.getASTRoot(), problem); 673 if (fix != null) { 674 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 675 Map options= new Hashtable (); 676 options.put(CleanUpConstants.ADD_MISSING_ANNOTATIONS, CleanUpConstants.TRUE); 677 options.put(CleanUpConstants.ADD_MISSING_ANNOTATIONS_DEPRECATED, CleanUpConstants.TRUE); 678 FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new Java50CleanUp(options), 5, image, context); 679 proposals.add(proposal); 680 } 681 } 682 683 public static void addOverridingDeprecatedMethodProposal(IInvocationContext context, IProblemLocation problem, Collection proposals) throws CoreException { 684 685 ICompilationUnit cu= context.getCompilationUnit(); 686 687 ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); 688 if (!(selectedNode instanceof MethodDeclaration)) { 689 return; 690 } 691 boolean is50OrHigher= JavaModelUtil.is50OrHigher(cu.getJavaProject()); 692 MethodDeclaration methodDecl= (MethodDeclaration) selectedNode; 693 AST ast= methodDecl.getAST(); 694 ASTRewrite rewrite= ASTRewrite.create(ast); 695 if (is50OrHigher) { 696 Annotation annot= ast.newMarkerAnnotation(); 697 annot.setTypeName(ast.newName("Deprecated")); rewrite.getListRewrite(methodDecl, methodDecl.getModifiersProperty()).insertFirst(annot, null); 699 } 700 Javadoc javadoc= methodDecl.getJavadoc(); 701 if (javadoc != null || !is50OrHigher) { 702 if (!is50OrHigher) { 703 javadoc= ast.newJavadoc(); 704 rewrite.set(methodDecl, MethodDeclaration.JAVADOC_PROPERTY, javadoc, null); 705 } 706 TagElement newTag= ast.newTagElement(); 707 newTag.setTagName(TagElement.TAG_DEPRECATED); 708 JavadocTagsSubProcessor.insertTag(rewrite.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY), newTag, null); 709 } 710 711 String label= CorrectionMessages.ModifierCorrectionSubProcessor_overrides_deprecated_description; 712 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 713 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 15, image); 714 proposals.add(proposal); 715 } 716 717 public static void removeOverrideAnnotationProposal(IInvocationContext context, IProblemLocation problem, Collection proposals) throws CoreException { 718 ICompilationUnit cu= context.getCompilationUnit(); 719 720 ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot()); 721 if (!(selectedNode instanceof MethodDeclaration)) { 722 return; 723 } 724 MethodDeclaration methodDecl= (MethodDeclaration) selectedNode; 725 Annotation annot= findAnnotation("java.lang.Override", methodDecl.modifiers()); if (annot != null) { 727 ASTRewrite rewrite= ASTRewrite.create(annot.getAST()); 728 rewrite.remove(annot, null); 729 String label= CorrectionMessages.ModifierCorrectionSubProcessor_remove_override; 730 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 731 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 6, image); 732 proposals.add(proposal); 733 734 QuickAssistProcessor.getCreateInSuperClassProposals(context, methodDecl.getName(), proposals); 735 } 736 } 737 738 private static final String KEY_MODIFIER= "modifier"; 740 private static class ModifierLinkedModeProposal extends LinkedProposalPositionGroup.Proposal { 741 742 private final int fModifier; 743 744 public ModifierLinkedModeProposal(int modifier, int relevance) { 745 super(null, null, relevance); 746 fModifier= modifier; 747 } 748 749 public String getAdditionalProposalInfo() { 750 return getDisplayString(); 751 } 752 753 public String getDisplayString() { 754 if (fModifier == 0) { 755 return CorrectionMessages.ModifierCorrectionSubProcessor_default_visibility_label; 756 } else { 757 return ModifierKeyword.fromFlagValue(fModifier).toString(); 758 } 759 } 760 761 764 public TextEdit computeEdits(int offset, LinkedPosition currentPosition, char trigger, int stateMask, LinkedModeModel model) throws CoreException { 765 try { 766 IDocument document= currentPosition.getDocument(); 767 MultiTextEdit edit= new MultiTextEdit(); 768 int documentLen= document.getLength(); 769 if (fModifier == 0) { 770 int end= currentPosition.offset + currentPosition.length; int k= end; 772 while (k < documentLen && IndentManipulation.isIndentChar(document.getChar(k))) { 773 k++; 774 } 775 edit.addChild(new ReplaceEdit(end, k - end, new String ())); edit.addChild(new ReplaceEdit(currentPosition.offset, currentPosition.length, new String ())); 778 } else { 779 edit.addChild(new ReplaceEdit(currentPosition.offset, currentPosition.length, ModifierKeyword.fromFlagValue(fModifier).toString())); 781 int end= currentPosition.offset + currentPosition.length; if (end < documentLen && !Character.isWhitespace(document.getChar(end))) { 783 edit.addChild(new ReplaceEdit(end, 0, String.valueOf(' '))); } 785 } 786 return edit; 787 } catch (BadLocationException e) { 788 throw new CoreException(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, e.getMessage(), e)); 789 } 790 } 791 } 792 793 public static void installLinkedVisibilityProposals(LinkedProposalModel linkedProposalModel, ASTRewrite rewrite, List modifiers, boolean inInterface) { 794 ASTNode modifier= findVisibilityModifier(modifiers); 795 if (modifier != null) { 796 int selected= ((Modifier) modifier).getKeyword().toFlagValue(); 797 798 LinkedProposalPositionGroup positionGroup= linkedProposalModel.getPositionGroup(KEY_MODIFIER, true); 799 positionGroup.addPosition(rewrite.track(modifier), false); 800 positionGroup.addProposal(new ModifierLinkedModeProposal(selected, 10)); 801 802 int[] flagValues= inInterface ? new int[] { Modifier.PUBLIC, 0 } : new int[] { Modifier.PUBLIC, 0, Modifier.PROTECTED, Modifier.PRIVATE }; 804 for (int i= 0; i < flagValues.length; i++) { 805 if (flagValues[i] != selected) { 806 positionGroup.addProposal(new ModifierLinkedModeProposal(flagValues[i], 9 - i)); 807 } 808 } 809 } 810 } 811 812 private static Modifier findVisibilityModifier(List modifiers) { 813 for (int i= 0; i < modifiers.size(); i++) { 814 Object curr= modifiers.get(i); 815 if (curr instanceof Modifier) { 816 Modifier modifier= (Modifier) curr; 817 ModifierKeyword keyword= modifier.getKeyword(); 818 if (keyword == ModifierKeyword.PUBLIC_KEYWORD || keyword == ModifierKeyword.PROTECTED_KEYWORD || keyword == ModifierKeyword.PRIVATE_KEYWORD) { 819 return modifier; 820 } 821 } 822 } 823 return null; 824 } 825 826 private static Annotation findAnnotation(String qualifiedTypeName, List modifiers) { 827 for (int i= 0; i < modifiers.size(); i++) { 828 Object curr= modifiers.get(i); 829 if (curr instanceof Annotation) { 830 Annotation annot= (Annotation) curr; 831 ITypeBinding binding= annot.getTypeName().resolveTypeBinding(); 832 if (binding != null && qualifiedTypeName.equals(binding.getQualifiedName())) { 833 return annot; 834 } 835 } 836 } 837 return null; 838 } 839 840 private static class ProposalParameter { 841 public final boolean useSuper; 842 public final ICompilationUnit compilationUnit; 843 public final ASTRewrite astRewrite; 844 public final Expression accessNode; 845 public final Expression qualifier; 846 public final IVariableBinding variableBinding; 847 848 public ProposalParameter(boolean useSuper, ICompilationUnit compilationUnit, ASTRewrite rewrite, Expression accessNode, Expression qualifier, IVariableBinding variableBinding) { 849 this.useSuper= useSuper; 850 this.compilationUnit= compilationUnit; 851 this.astRewrite= rewrite; 852 this.accessNode= accessNode; 853 this.qualifier= qualifier; 854 this.variableBinding= variableBinding; 855 } 856 } 857 858 public static class SelfEncapsulateFieldProposal extends ChangeCorrectionProposal { 859 860 private IField fField; 861 private boolean fNoDialog; 862 863 public SelfEncapsulateFieldProposal(int relevance, IField field, boolean isReadAccess) { 864 super(getDescription(isReadAccess), null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE)); 865 fField= field; 866 fNoDialog= false; 867 } 868 869 public void setNoDialog(boolean noDialog) { 870 fNoDialog= noDialog; 871 } 872 873 private static String getDescription(boolean getter) { 874 if (getter) 875 return CorrectionMessages.ModifierCorrectionSubProcessor_creategetterunsingencapsulatefield_description; 876 else 877 return CorrectionMessages.ModifierCorrectionSubProcessor_createsetterusingencapsulatefield_description; 878 } 879 880 public void apply(IDocument document) { 881 try { 882 final SelfEncapsulateFieldRefactoring refactoring= new SelfEncapsulateFieldRefactoring(fField); 883 refactoring.setVisibility(Flags.AccPublic); 884 refactoring.setConsiderVisibility(false); if (fNoDialog) { 886 IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 887 final RefactoringExecutionHelper helper= new RefactoringExecutionHelper(refactoring, RefactoringStatus.ERROR, RefactoringSaveHelper.SAVE_JAVA_ONLY_UPDATES, JavaPlugin.getActiveWorkbenchShell(), window); 888 if (Display.getCurrent() != null) { 889 try { 890 helper.perform(false, false); 891 } catch (InterruptedException e) { 892 JavaPlugin.log(e); 893 } catch (InvocationTargetException e) { 894 JavaPlugin.log(e); 895 } 896 } else { 897 Display.getDefault().syncExec(new Runnable () { 898 public void run() { 899 try { 900 helper.perform(false, false); 901 } catch (InterruptedException e) { 902 JavaPlugin.log(e); 903 } catch (InvocationTargetException e) { 904 JavaPlugin.log(e); 905 } 906 } 907 }); 908 } 909 } else { 910 new RefactoringStarter().activate(refactoring, new SelfEncapsulateFieldWizard(refactoring), JavaPlugin.getActiveWorkbenchShell(), "", RefactoringSaveHelper.SAVE_JAVA_ONLY_UPDATES); } 912 } catch (JavaModelException e) { 913 ExceptionHandler.handle(e, CorrectionMessages.ModifierCorrectionSubProcessor_encapsulate_field_error_title, CorrectionMessages.ModifierCorrectionSubProcessor_encapsulate_field_error_message); 914 } 915 } 916 } 917 918 public static void addGetterSetterProposal(IInvocationContext context, IProblemLocation problem, Collection proposals, int relevance) { 919 ASTNode coveringNode= problem.getCoveringNode(context.getASTRoot()); 920 ICompilationUnit compilationUnit= context.getCompilationUnit(); 921 if (coveringNode instanceof SimpleName) { 922 SimpleName sn= (SimpleName) coveringNode; 923 if (sn.isDeclaration()) 924 return; 925 IVariableBinding variableBinding= (IVariableBinding) sn.resolveBinding(); 926 if (variableBinding == null || !variableBinding.isField()) 927 return; 928 ChangeCorrectionProposal proposal= getProposal(compilationUnit, sn, variableBinding, relevance); 929 if (proposal != null) 930 proposals.add(proposal); 931 } 932 } 933 934 private static ChangeCorrectionProposal getProposal(ICompilationUnit cu, SimpleName sn, IVariableBinding variableBinding, int relevance) { 935 Expression accessNode= sn; 936 Expression qualifier= null; 937 AST ast= sn.getAST(); 938 ASTRewrite rewrite= ASTRewrite.create(ast); 939 boolean useSuper= false; 940 boolean writeAccess= ASTResolving.isWriteAccess(sn); 941 ASTNode parent= sn.getParent(); 942 switch (parent.getNodeType()) { 943 case ASTNode.QUALIFIED_NAME: 944 accessNode= (Expression) parent; 945 qualifier= ((QualifiedName) parent).getQualifier(); 946 break; 947 case ASTNode.SUPER_FIELD_ACCESS: 948 accessNode= (Expression) parent; 949 qualifier= ((SuperFieldAccess) parent).getQualifier(); 950 useSuper= true; 951 break; 952 } 953 ProposalParameter gspc= new ProposalParameter(useSuper, cu, rewrite, accessNode, qualifier, variableBinding); 954 if (writeAccess) 955 return addSetterProposal(gspc, relevance); 956 else 957 return addGetterProposal(gspc, relevance); 958 } 959 960 966 private static ChangeCorrectionProposal addGetterProposal(ProposalParameter context, int relevance) { 967 IMethodBinding method= findGetter(context); 968 if (method != null) { 969 Expression mi= createMethodInvocation(context, method, null); 970 context.astRewrite.replace(context.accessNode, mi, null); 971 972 String label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_replacewithgetter_description, context.accessNode); 973 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 974 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.compilationUnit, context.astRewrite, relevance, image); 975 return proposal; 976 } else { 977 IJavaElement element= context.variableBinding.getJavaElement(); 978 if (element instanceof IField) { 979 IField field= (IField) element; 980 try { 981 if (RefactoringAvailabilityTester.isSelfEncapsulateAvailable(field)) 982 return new SelfEncapsulateFieldProposal(relevance, field, true); 983 } catch (JavaModelException e) { 984 JavaPlugin.log(e); 985 } 986 } 987 } 988 return null; 989 } 990 991 private static IMethodBinding findGetter(ProposalParameter context) { 992 ITypeBinding returnType= context.variableBinding.getType(); 993 String getterName= GetterSetterUtil.getGetterName(context.variableBinding, context.compilationUnit.getJavaProject(), null, isBoolean(context)); 994 ITypeBinding declaringType= context.variableBinding.getDeclaringClass(); 995 IMethodBinding getter= Bindings.findMethodInHierarchy(declaringType, getterName, new ITypeBinding[0]); 996 if (getter != null && getter.getReturnType().isAssignmentCompatible(returnType) && Modifier.isStatic(getter.getModifiers()) == Modifier.isStatic(context.variableBinding.getModifiers())) 997 return getter; 998 return null; 999 } 1000 1001 private static Expression createMethodInvocation(ProposalParameter context, IMethodBinding method, Expression argument) { 1002 AST ast= context.astRewrite.getAST(); 1003 Expression qualifier= context.qualifier; 1004 if (context.useSuper) { 1005 SuperMethodInvocation invocation= ast.newSuperMethodInvocation(); 1006 invocation.setName(ast.newSimpleName(method.getName())); 1007 if (qualifier != null) 1008 invocation.setQualifier((Name) context.astRewrite.createCopyTarget(qualifier)); 1009 if (argument != null) 1010 invocation.arguments().add(argument); 1011 return invocation; 1012 } else { 1013 MethodInvocation invocation= ast.newMethodInvocation(); 1014 invocation.setName(ast.newSimpleName(method.getName())); 1015 if (qualifier != null) 1016 invocation.setExpression((Expression) context.astRewrite.createCopyTarget(qualifier)); 1017 if (argument != null) 1018 invocation.arguments().add(argument); 1019 return invocation; 1020 } 1021 } 1022 1023 1029 private static ChangeCorrectionProposal addSetterProposal(ProposalParameter context, int relevance) { 1030 boolean isBoolean= isBoolean(context); 1031 String setterName= GetterSetterUtil.getSetterName(context.variableBinding, context.compilationUnit.getJavaProject(), null, isBoolean); 1032 ITypeBinding declaringType= context.variableBinding.getDeclaringClass(); 1033 IMethodBinding method= Bindings.findMethodInHierarchy(declaringType, setterName, new ITypeBinding[] { context.variableBinding.getType() }); 1034 if (method != null && Bindings.isVoidType(method.getReturnType()) && (Modifier.isStatic(method.getModifiers()) == Modifier.isStatic(context.variableBinding.getModifiers()))) { 1035 Expression assignedValue= getAssignedValue(context); 1036 if (assignedValue == null) 1037 return null; Expression mi= createMethodInvocation(context, method, assignedValue); 1039 context.astRewrite.replace(context.accessNode.getParent(), mi, null); 1040 1041 String label= Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_replacewithsetter_description, context.accessNode); 1042 Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); 1043 ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.compilationUnit, context.astRewrite, relevance, image); 1044 return proposal; 1045 } else { 1046 IJavaElement element= context.variableBinding.getJavaElement(); 1047 if (element instanceof IField) { 1048 IField field= (IField) element; 1049 try { 1050 if (RefactoringAvailabilityTester.isSelfEncapsulateAvailable(field)) 1051 return new SelfEncapsulateFieldProposal(relevance, field, false); 1052 } catch (JavaModelException e) { 1053 JavaPlugin.log(e); 1054 } 1055 } 1056 } 1057 return null; 1058 } 1059 1060 private static boolean isBoolean(ProposalParameter context) { 1061 AST ast= context.astRewrite.getAST(); 1062 boolean isBoolean= ast.resolveWellKnownType("boolean") == context.variableBinding.getType(); if (!isBoolean) 1064 isBoolean= ast.resolveWellKnownType("java.lang.Boolean") == context.variableBinding.getType(); return isBoolean; 1066 } 1067 1068 private static Expression getAssignedValue(ProposalParameter context) { 1069 ASTNode parent= context.accessNode.getParent(); 1070 AST ast= context.astRewrite.getAST(); 1071 switch (parent.getNodeType()) { 1072 case ASTNode.ASSIGNMENT: 1073 Assignment assignment= ((Assignment) parent); 1074 Expression rightHandSide= assignment.getRightHandSide(); 1075 Expression copiedRightOp= (Expression) context.astRewrite.createCopyTarget(rightHandSide); 1076 if (isNotInBlock(parent)) 1077 break; 1078 if (assignment.getOperator() == Operator.ASSIGN) { 1079 ITypeBinding rightHandSideType= rightHandSide.resolveTypeBinding(); 1080 copiedRightOp= checkForNarrowCast(context, copiedRightOp, true, rightHandSideType); 1081 return copiedRightOp; 1082 } 1083 IMethodBinding getter= findGetter(context); 1084 if (getter != null) { 1085 InfixExpression infix= ast.newInfixExpression(); 1086 infix.setLeftOperand(createMethodInvocation(context, getter, null)); 1087 infix.setOperator(ASTNodes.convertToInfixOperator(assignment.getOperator())); 1088 infix.setRightOperand(copiedRightOp); 1089 ITypeBinding infixType= infix.resolveTypeBinding(); 1090 return checkForNarrowCast(context, infix, true, infixType); 1091 } 1092 break; 1093 case ASTNode.POSTFIX_EXPRESSION: 1094 PostfixExpression po= (PostfixExpression) parent; 1095 if (isNotInBlock(parent)) 1096 break; 1097 InfixExpression.Operator postfixOp= null; 1098 if (po.getOperator() == PostfixExpression.Operator.INCREMENT) 1099 postfixOp= InfixExpression.Operator.PLUS; 1100 if (po.getOperator() == PostfixExpression.Operator.DECREMENT) 1101 postfixOp= InfixExpression.Operator.MINUS; 1102 if (postfixOp == null) 1103 break; 1104 return createInfixInvocationFromPostPrefixExpression(context, postfixOp); 1105 case ASTNode.PREFIX_EXPRESSION: 1106 PrefixExpression pe= (PrefixExpression) parent; 1107 if (isNotInBlock(parent)) 1108 break; 1109 InfixExpression.Operator prefixOp= null; 1110 if (pe.getOperator() == PrefixExpression.Operator.INCREMENT) 1111 prefixOp= InfixExpression.Operator.PLUS; 1112 if (pe.getOperator() == PrefixExpression.Operator.DECREMENT) 1113 prefixOp= InfixExpression.Operator.MINUS; 1114 if (prefixOp == null) 1115 break; 1116 return createInfixInvocationFromPostPrefixExpression(context, prefixOp); 1117 } 1118 1119 return null; 1120 } 1121 1122 private static boolean isNotInBlock(ASTNode parent) { 1123 ASTNode grandParent= parent.getParent(); 1124 return (grandParent.getNodeType() != ASTNode.EXPRESSION_STATEMENT) || (grandParent.getParent().getNodeType() != ASTNode.BLOCK); 1125 } 1126 1127 private static Expression createInfixInvocationFromPostPrefixExpression(ProposalParameter context, InfixExpression.Operator operator) { 1128 AST ast= context.astRewrite.getAST(); 1129 IMethodBinding getter= findGetter(context); 1130 if (getter != null) { 1131 InfixExpression infix= ast.newInfixExpression(); 1132 infix.setLeftOperand(createMethodInvocation(context, getter, null)); 1133 infix.setOperator(operator); 1134 NumberLiteral number= ast.newNumberLiteral(); 1135 number.setToken("1"); infix.setRightOperand(number); 1137 ITypeBinding infixType= infix.resolveTypeBinding(); 1138 return checkForNarrowCast(context, infix, true, infixType); 1139 } 1140 return null; 1141 } 1142 1143 1151 private static Expression checkForNarrowCast(ProposalParameter context, Expression expression, boolean parenthesize, ITypeBinding expressionType) { 1152 PrimitiveType castTo= null; 1153 ITypeBinding type= context.variableBinding.getType(); 1154 if (type.isEqualTo(expressionType)) 1155 return expression; AST ast= context.astRewrite.getAST(); 1157 if (JavaModelUtil.is50OrHigher(context.compilationUnit.getJavaProject())) { 1158 if (ast.resolveWellKnownType("java.lang.Character").isEqualTo(type)) castTo= ast.newPrimitiveType(PrimitiveType.CHAR); 1160 if (ast.resolveWellKnownType("java.lang.Byte").isEqualTo(type)) castTo= ast.newPrimitiveType(PrimitiveType.BYTE); 1162 if (ast.resolveWellKnownType("java.lang.Short").isEqualTo(type)) castTo= ast.newPrimitiveType(PrimitiveType.SHORT); 1164 } 1165 if (ast.resolveWellKnownType("char").isEqualTo(type)) castTo= ast.newPrimitiveType(PrimitiveType.CHAR); 1167 if (ast.resolveWellKnownType("byte").isEqualTo(type)) castTo= ast.newPrimitiveType(PrimitiveType.BYTE); 1169 if (ast.resolveWellKnownType("short").isEqualTo(type)) castTo= ast.newPrimitiveType(PrimitiveType.SHORT); 1171 if (castTo != null) { 1172 CastExpression cast= ast.newCastExpression(); 1173 if (parenthesize) { 1174 ParenthesizedExpression parenthesized= ast.newParenthesizedExpression(); 1175 parenthesized.setExpression(expression); 1176 cast.setExpression(parenthesized); 1177 } else 1178 cast.setExpression(expression); 1179 cast.setType(castTo); 1180 return cast; 1181 } 1182 return expression; 1183 } 1184 1185} 1186 | Popular Tags |