1 11 package org.eclipse.jdt.internal.corext.fix; 12 13 import java.util.ArrayList ; 14 import java.util.Hashtable ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 18 import org.eclipse.text.edits.TextEditGroup; 19 20 import org.eclipse.core.runtime.CoreException; 21 22 import org.eclipse.jdt.core.IJavaElement; 23 import org.eclipse.jdt.core.IType; 24 import org.eclipse.jdt.core.compiler.IProblem; 25 import org.eclipse.jdt.core.dom.ASTNode; 26 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; 27 import org.eclipse.jdt.core.dom.Assignment; 28 import org.eclipse.jdt.core.dom.CompilationUnit; 29 import org.eclipse.jdt.core.dom.Expression; 30 import org.eclipse.jdt.core.dom.FieldAccess; 31 import org.eclipse.jdt.core.dom.IBinding; 32 import org.eclipse.jdt.core.dom.IMethodBinding; 33 import org.eclipse.jdt.core.dom.ITypeBinding; 34 import org.eclipse.jdt.core.dom.IVariableBinding; 35 import org.eclipse.jdt.core.dom.Initializer; 36 import org.eclipse.jdt.core.dom.MethodInvocation; 37 import org.eclipse.jdt.core.dom.Modifier; 38 import org.eclipse.jdt.core.dom.Name; 39 import org.eclipse.jdt.core.dom.QualifiedName; 40 import org.eclipse.jdt.core.dom.SimpleName; 41 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; 42 import org.eclipse.jdt.core.dom.SuperFieldAccess; 43 import org.eclipse.jdt.core.dom.SwitchCase; 44 import org.eclipse.jdt.core.dom.ThisExpression; 45 import org.eclipse.jdt.core.dom.Type; 46 import org.eclipse.jdt.core.dom.TypeDeclaration; 47 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 48 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 49 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 50 51 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 52 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 53 import org.eclipse.jdt.internal.corext.dom.Bindings; 54 import org.eclipse.jdt.internal.corext.dom.GenericVisitor; 55 import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; 56 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; 57 import org.eclipse.jdt.internal.corext.util.Messages; 58 59 import org.eclipse.jdt.ui.text.java.IProblemLocation; 60 61 import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation; 62 63 66 public class CodeStyleFix extends AbstractFix { 67 68 private final static class CodeStyleVisitor extends GenericVisitor { 69 70 private final List fResult; 71 private final ImportRewrite fImportRewrite; 72 private final boolean fFindUnqualifiedAccesses; 73 private final boolean fFindUnqualifiedStaticAccesses; 74 private final boolean fFindUnqualifiedMethodAccesses; 75 private final boolean fFindUnqualifiedStaticMethodAccesses; 76 77 public CodeStyleVisitor(CompilationUnit compilationUnit, 78 boolean findUnqualifiedAccesses, 79 boolean findUnqualifiedStaticAccesses, 80 boolean findUnqualifiedMethodAccesses, 81 boolean findUnqualifiedStaticMethodAccesses, 82 List resultingCollection) throws CoreException { 83 84 fFindUnqualifiedAccesses= findUnqualifiedAccesses; 85 fFindUnqualifiedStaticAccesses= findUnqualifiedStaticAccesses; 86 fFindUnqualifiedMethodAccesses= findUnqualifiedMethodAccesses; 87 fFindUnqualifiedStaticMethodAccesses= findUnqualifiedStaticMethodAccesses; 88 fImportRewrite= StubUtility.createImportRewrite(compilationUnit, true); 89 fResult= resultingCollection; 90 } 91 92 95 public boolean visit(TypeDeclaration node) { 96 if (!fFindUnqualifiedStaticAccesses && !fFindUnqualifiedStaticMethodAccesses && node.isInterface()) 97 return false; 98 99 return super.visit(node); 100 } 101 102 public boolean visit(QualifiedName node) { 103 if (fFindUnqualifiedAccesses || fFindUnqualifiedStaticAccesses) { 104 ASTNode simpleName= node; 105 while (simpleName instanceof QualifiedName) { 106 simpleName= ((QualifiedName) simpleName).getQualifier(); 107 } 108 if (simpleName instanceof SimpleName) { 109 handleSimpleName((SimpleName)simpleName); 110 } 111 } 112 return false; 113 } 114 115 public boolean visit(SimpleName node) { 116 if (fFindUnqualifiedAccesses || fFindUnqualifiedStaticAccesses) { 117 handleSimpleName(node); 118 } 119 return false; 120 } 121 122 125 public boolean visit(MethodInvocation node) { 126 if (!fFindUnqualifiedMethodAccesses && !fFindUnqualifiedStaticMethodAccesses) 127 return true; 128 129 if (node.getExpression() != null) 130 return true; 131 132 IBinding binding= node.getName().resolveBinding(); 133 if (!(binding instanceof IMethodBinding)) 134 return true; 135 136 handleMethod(node.getName(), (IMethodBinding)binding); 137 return true; 138 } 139 140 private void handleSimpleName(SimpleName node) { 141 ASTNode firstExpression= node.getParent(); 142 if (firstExpression instanceof FieldAccess) { 143 while (firstExpression instanceof FieldAccess) { 144 firstExpression= ((FieldAccess)firstExpression).getExpression(); 145 } 146 if (!(firstExpression instanceof SimpleName)) 147 return; 148 149 node= (SimpleName)firstExpression; 150 } else if (firstExpression instanceof SuperFieldAccess) 151 return; 152 153 StructuralPropertyDescriptor parentDescription= node.getLocationInParent(); 154 if (parentDescription == VariableDeclarationFragment.NAME_PROPERTY || parentDescription == SwitchCase.EXPRESSION_PROPERTY) 155 return; 156 157 IBinding binding= node.resolveBinding(); 158 if (!(binding instanceof IVariableBinding)) 159 return; 160 161 handleVariable(node, (IVariableBinding) binding); 162 } 163 164 private void handleVariable(SimpleName node, IVariableBinding varbinding) { 165 if (!varbinding.isField()) 166 return; 167 168 if (varbinding.isEnumConstant()) 169 return; 170 171 ITypeBinding declaringClass= varbinding.getDeclaringClass(); 172 if (Modifier.isStatic(varbinding.getModifiers())) { 173 if (fFindUnqualifiedStaticAccesses) { 174 Initializer initializer= (Initializer) ASTNodes.getParent(node, Initializer.class); 175 StructuralPropertyDescriptor parentDescription= node.getLocationInParent(); 177 if (initializer != null && Modifier.isStatic(initializer.getModifiers()) 178 && Modifier.isFinal(varbinding.getModifiers()) && parentDescription == Assignment.LEFT_HAND_SIDE_PROPERTY) 179 return; 180 181 if (declaringClass.isAnonymous()) 183 return; 184 185 fResult.add(new AddStaticQualifierOperation(declaringClass, node)); 186 } 187 } else if (fFindUnqualifiedAccesses){ 188 String qualifier= getNonStaticQualifier(declaringClass, fImportRewrite, node); 189 if (qualifier == null) 190 return; 191 192 fResult.add(new AddThisQualifierOperation(qualifier, node)); 193 } 194 } 195 196 private void handleMethod(SimpleName node, IMethodBinding binding) { 197 ITypeBinding declaringClass= binding.getDeclaringClass(); 198 if (Modifier.isStatic(binding.getModifiers())) { 199 if (fFindUnqualifiedStaticMethodAccesses) { 200 if (declaringClass.isAnonymous()) 202 return; 203 204 fResult.add(new AddStaticQualifierOperation(declaringClass, node)); 205 } 206 } else { 207 if (fFindUnqualifiedMethodAccesses) { 208 String qualifier= getNonStaticQualifier(declaringClass, fImportRewrite, node); 209 if (qualifier == null) 210 return; 211 212 fResult.add(new AddThisQualifierOperation(qualifier, node)); 213 } 214 } 215 } 216 } 217 218 private static class ThisQualifierVisitor extends GenericVisitor { 219 220 private final CompilationUnit fCompilationUnit; 221 private final List fOperations; 222 private final boolean fRemoveFieldQualifiers; 223 private final boolean fRemoveMethodQualifiers; 224 225 public ThisQualifierVisitor(boolean removeFieldQualifiers, 226 boolean removeMethodQualifiers, 227 CompilationUnit compilationUnit, 228 List result) { 229 fRemoveFieldQualifiers= removeFieldQualifiers; 230 fRemoveMethodQualifiers= removeMethodQualifiers; 231 fCompilationUnit= compilationUnit; 232 fOperations= result; 233 } 234 235 238 public boolean visit(final FieldAccess node) { 239 if (!fRemoveFieldQualifiers) 240 return true; 241 242 Expression expression= node.getExpression(); 243 if (!(expression instanceof ThisExpression)) 244 return true; 245 246 final SimpleName name= node.getName(); 247 if (hasConflict(expression.getStartPosition(), name, ScopeAnalyzer.VARIABLES)) 248 return true; 249 250 fOperations.add(new AbstractFixRewriteOperation() { 251 public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException { 252 ASTRewrite rewrite= cuRewrite.getASTRewrite(); 253 254 TextEditGroup group= createTextEditGroup(FixMessages.CodeStyleFix_removeThis_groupDescription); 255 textEditGroups.add(group); 256 257 rewrite.replace(node, rewrite.createCopyTarget(name), group); 258 } 259 }); 260 return super.visit(node); 261 } 262 263 266 public boolean visit(final MethodInvocation node) { 267 if (!fRemoveMethodQualifiers) 268 return true; 269 270 Expression expression= node.getExpression(); 271 if (!(expression instanceof ThisExpression)) 272 return true; 273 274 final SimpleName name= node.getName(); 275 if (name.resolveBinding() == null) 276 return true; 277 278 if (hasConflict(expression.getStartPosition(), name, ScopeAnalyzer.METHODS)) 279 return true; 280 281 Name qualifier= ((ThisExpression)expression).getQualifier(); 282 if (qualifier != null) { 283 ITypeBinding declaringClass= ((IMethodBinding)name.resolveBinding()).getDeclaringClass(); 284 if (declaringClass == null) 285 return true; 286 287 ITypeBinding caller= getDeclaringType(node); 288 if (caller == null) 289 return true; 290 291 ITypeBinding callee= (ITypeBinding)qualifier.resolveBinding(); 292 if (callee == null) 293 return true; 294 295 if (callee.isAssignmentCompatible(declaringClass) && caller.isAssignmentCompatible(declaringClass)) 296 return true; 297 } 298 299 fOperations.add(new AbstractFixRewriteOperation() { 300 public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException { 301 ASTRewrite rewrite= cuRewrite.getASTRewrite(); 302 303 TextEditGroup group= createTextEditGroup(FixMessages.CodeStyleFix_removeThis_groupDescription); 304 textEditGroups.add(group); 305 306 rewrite.remove(node.getExpression(), group); 307 } 308 }); 309 return super.visit(node); 310 } 311 312 private ITypeBinding getDeclaringType(MethodInvocation node) { 313 ASTNode p= node; 314 while (p != null) { 315 p= p.getParent(); 316 if (p instanceof AbstractTypeDeclaration) { 317 return ((AbstractTypeDeclaration)p).resolveBinding(); 318 } 319 } 320 return null; 321 } 322 323 private boolean hasConflict(int startPosition, SimpleName name, int flag) { 324 ScopeAnalyzer analyzer= new ScopeAnalyzer(fCompilationUnit); 325 IBinding[] declarationsInScope= analyzer.getDeclarationsInScope(startPosition, flag); 326 for (int i= 0; i < declarationsInScope.length; i++) { 327 IBinding decl= declarationsInScope[i]; 328 if (decl.getName().equals(name.getIdentifier()) && name.resolveBinding() != decl) 329 return true; 330 } 331 return false; 332 } 333 } 334 335 private final static class AddThisQualifierOperation extends AbstractFixRewriteOperation { 336 337 private final String fQualifier; 338 private final SimpleName fName; 339 340 public AddThisQualifierOperation(String qualifier, SimpleName name) { 341 fQualifier= qualifier; 342 fName= name; 343 } 344 345 public String getDescription() { 346 return Messages.format(FixMessages.CodeStyleFix_QualifyWithThis_description, new Object [] {fName.getIdentifier(), fQualifier}); 347 } 348 349 352 public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException { 353 ASTRewrite rewrite= cuRewrite.getASTRewrite(); 354 TextEditGroup group; 355 if (fName.resolveBinding() instanceof IMethodBinding) { 356 group= createTextEditGroup(FixMessages.CodeStyleFix_QualifyMethodWithThis_description); 357 } else { 358 group= createTextEditGroup(FixMessages.CodeStyleFix_QualifyFieldWithThis_description); 359 } 360 textEditGroups.add(group); 361 rewrite.replace(fName, rewrite.createStringPlaceholder(fQualifier + '.' + fName.getIdentifier(), ASTNode.SIMPLE_NAME), group); 362 } 363 } 364 365 private final static class AddStaticQualifierOperation extends AbstractFixRewriteOperation { 366 367 private final SimpleName fName; 368 private final ITypeBinding fDeclaringClass; 369 370 public AddStaticQualifierOperation(ITypeBinding declaringClass, SimpleName name) { 371 super(); 372 fDeclaringClass= declaringClass; 373 fName= name; 374 } 375 376 379 public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException { 380 ASTRewrite rewrite= cuRewrite.getASTRewrite(); 381 CompilationUnit compilationUnit= cuRewrite.getRoot(); 382 importType(fDeclaringClass, fName, cuRewrite.getImportRewrite(), compilationUnit); 383 TextEditGroup group; 384 if (fName.resolveBinding() instanceof IMethodBinding) { 385 group= createTextEditGroup(FixMessages.CodeStyleFix_QualifyMethodWithDeclClass_description); 386 } else { 387 group= createTextEditGroup(FixMessages.CodeStyleFix_QualifyFieldWithDeclClass_description); 388 } 389 textEditGroups.add(group); 390 IJavaElement javaElement= fDeclaringClass.getJavaElement(); 391 if (javaElement instanceof IType) { 392 Name qualifierName= compilationUnit.getAST().newName(((IType)javaElement).getElementName()); 393 SimpleName simpleName= (SimpleName)rewrite.createMoveTarget(fName); 394 QualifiedName qualifiedName= compilationUnit.getAST().newQualifiedName(qualifierName, simpleName); 395 rewrite.replace(fName, qualifiedName, group); 396 } 397 } 398 399 } 400 401 private final static class ToStaticAccessOperation extends AbstractFixRewriteOperation { 402 403 private final ITypeBinding fDeclaringTypeBinding; 404 private final Expression fQualifier; 405 406 public ToStaticAccessOperation(ITypeBinding declaringTypeBinding, Expression qualifier) { 407 super(); 408 fDeclaringTypeBinding= declaringTypeBinding; 409 fQualifier= qualifier; 410 } 411 412 public String getAccessorName() { 413 return fDeclaringTypeBinding.getName(); 414 } 415 416 419 public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException { 420 Type type= importType(fDeclaringTypeBinding, fQualifier, cuRewrite.getImportRewrite(), cuRewrite.getRoot()); 421 TextEditGroup group= createTextEditGroup(FixMessages.CodeStyleFix_ChangeAccessUsingDeclaring_description); 422 textEditGroups.add(group); 423 cuRewrite.getASTRewrite().replace(fQualifier, type, group); 424 } 425 } 426 427 public static CodeStyleFix[] createNonStaticAccessFixes(CompilationUnit compilationUnit, IProblemLocation problem) throws CoreException { 428 if (!isNonStaticAccess(problem)) 429 return null; 430 431 ToStaticAccessOperation operations[]= createToStaticAccessOperations(compilationUnit, problem); 432 if (operations == null) 433 return null; 434 435 String label1= Messages.format(FixMessages.CodeStyleFix_ChangeAccessToStatic_description, operations[0].getAccessorName()); 436 CodeStyleFix fix1= new CodeStyleFix(label1, compilationUnit, new IFixRewriteOperation[] {operations[0]}); 437 438 if (operations.length > 1) { 439 String label2= Messages.format(FixMessages.CodeStyleFix_ChangeAccessToStaticUsingInstanceType_description, operations[1].getAccessorName()); 440 CodeStyleFix fix2= new CodeStyleFix(label2, compilationUnit, new IFixRewriteOperation[] {operations[1]}); 441 return new CodeStyleFix[] {fix1, fix2}; 442 } 443 return new CodeStyleFix[] {fix1}; 444 } 445 446 public static CodeStyleFix createAddFieldQualifierFix(CompilationUnit compilationUnit, IProblemLocation problem) throws CoreException { 447 if (IProblem.UnqualifiedFieldAccess != problem.getProblemId()) 448 return null; 449 450 AddThisQualifierOperation operation= getUnqualifiedFieldAccessResolveOperation(compilationUnit, problem); 451 if (operation == null) 452 return null; 453 454 String groupName= operation.getDescription(); 455 return new CodeStyleFix(groupName, compilationUnit, new IFixRewriteOperation[] {operation}); 456 } 457 458 public static CodeStyleFix createIndirectAccessToStaticFix(CompilationUnit compilationUnit, IProblemLocation problem) throws CoreException { 459 if (!isIndirectStaticAccess(problem)) 460 return null; 461 462 ToStaticAccessOperation operations[]= createToStaticAccessOperations(compilationUnit, problem); 463 if (operations == null) 464 return null; 465 466 String label= Messages.format(FixMessages.CodeStyleFix_ChangeStaticAccess_description, operations[0].getAccessorName()); 467 return new CodeStyleFix(label, compilationUnit, new IFixRewriteOperation[] {operations[0]}); 468 } 469 470 public static CodeStyleFix createCleanUp(CompilationUnit compilationUnit, 471 boolean addThisQualifier, 472 boolean changeNonStaticAccessToStatic, 473 boolean qualifyStaticFieldAccess, 474 boolean changeIndirectStaticAccessToDirect, 475 boolean qualifyMethodAccess, 476 boolean qualifyStaticMethodAccess, 477 boolean removeFieldQualifier, 478 boolean removeMethodQualifier) throws CoreException { 479 480 if (!addThisQualifier && !changeNonStaticAccessToStatic && !qualifyStaticFieldAccess && !changeIndirectStaticAccessToDirect && !qualifyMethodAccess && !qualifyStaticMethodAccess && !removeFieldQualifier && !removeMethodQualifier) 481 return null; 482 483 List operations= new ArrayList (); 484 if (addThisQualifier || qualifyStaticFieldAccess || qualifyMethodAccess || qualifyStaticMethodAccess) { 485 CodeStyleVisitor codeStyleVisitor= new CodeStyleVisitor(compilationUnit, addThisQualifier, qualifyStaticFieldAccess, qualifyMethodAccess, qualifyStaticMethodAccess, operations); 486 compilationUnit.accept(codeStyleVisitor); 487 } 488 489 IProblem[] problems= compilationUnit.getProblems(); 490 IProblemLocation[] locations= new IProblemLocation[problems.length]; 491 for (int i= 0; i < problems.length; i++) { 492 locations[i]= new ProblemLocation(problems[i]); 493 } 494 addToStaticAccessOperations(compilationUnit, locations, changeNonStaticAccessToStatic, changeIndirectStaticAccessToDirect, operations); 495 496 if (removeFieldQualifier || removeMethodQualifier) { 497 ThisQualifierVisitor visitor= new ThisQualifierVisitor(removeFieldQualifier, removeMethodQualifier, compilationUnit, operations); 498 compilationUnit.accept(visitor); 499 } 500 501 if (operations.isEmpty()) 502 return null; 503 504 IFixRewriteOperation[] operationsArray= (IFixRewriteOperation[])operations.toArray(new IFixRewriteOperation[operations.size()]); 505 return new CodeStyleFix(FixMessages.CodeStyleFix_change_name, compilationUnit, operationsArray); 506 } 507 508 public static CodeStyleFix createCleanUp(CompilationUnit compilationUnit, IProblemLocation[] problems, 509 boolean addThisQualifier, 510 boolean changeNonStaticAccessToStatic, 511 boolean changeIndirectStaticAccessToDirect) throws CoreException { 512 513 if (!addThisQualifier && !changeNonStaticAccessToStatic && !changeIndirectStaticAccessToDirect) 514 return null; 515 516 List operations= new ArrayList (); 517 if (addThisQualifier) { 518 for (int i= 0; i < problems.length; i++) { 519 IProblemLocation problem= problems[i]; 520 if (problem.getProblemId() == IProblem.UnqualifiedFieldAccess) { 521 AddThisQualifierOperation operation= getUnqualifiedFieldAccessResolveOperation(compilationUnit, problem); 522 if (operation != null) 523 operations.add(operation); 524 } 525 } 526 } 527 528 addToStaticAccessOperations(compilationUnit, problems, changeNonStaticAccessToStatic, changeIndirectStaticAccessToDirect, operations); 529 530 if (operations.isEmpty()) 531 return null; 532 533 IFixRewriteOperation[] operationsArray= (IFixRewriteOperation[])operations.toArray(new IFixRewriteOperation[operations.size()]); 534 return new CodeStyleFix(FixMessages.CodeStyleFix_change_name, compilationUnit, operationsArray); 535 } 536 537 private static void addToStaticAccessOperations(CompilationUnit compilationUnit, IProblemLocation[] problems, boolean changeNonStaticAccessToStatic, boolean changeIndirectStaticAccessToDirect, List result) { 538 Hashtable nonStaticAccessOps= new Hashtable (); 539 if (changeNonStaticAccessToStatic || changeIndirectStaticAccessToDirect) { 540 for (int i= 0; i < problems.length; i++) { 541 IProblemLocation problem= problems[i]; 542 boolean isNonStaticAccess= changeNonStaticAccessToStatic && isNonStaticAccess(problem); 543 boolean isIndirectStaticAccess= changeIndirectStaticAccessToDirect && isIndirectStaticAccess(problem); 544 if (isNonStaticAccess || isIndirectStaticAccess) { 545 ToStaticAccessOperation[] nonStaticAccessInformation= createToStaticAccessOperations(compilationUnit, problem); 546 if (nonStaticAccessInformation != null) { 547 ToStaticAccessOperation op= nonStaticAccessInformation[0]; 548 nonStaticAccessOps.put(op.fQualifier, op); 549 } 550 } 551 } 552 } 553 for (Iterator iter= nonStaticAccessOps.values().iterator(); iter.hasNext();) { 554 ToStaticAccessOperation op= (ToStaticAccessOperation)iter.next(); 555 if (!nonStaticAccessOps.containsKey(op.fQualifier.getParent())) 556 result.add(op); 557 } 558 } 559 560 private static boolean isIndirectStaticAccess(IProblemLocation problem) { 561 return (problem.getProblemId() == IProblem.IndirectAccessToStaticField 562 || problem.getProblemId() == IProblem.IndirectAccessToStaticMethod); 563 } 564 565 private static boolean isNonStaticAccess(IProblemLocation problem) { 566 return (problem.getProblemId() == IProblem.NonStaticAccessToStaticField 567 || problem.getProblemId() == IProblem.NonStaticAccessToStaticMethod); 568 } 569 570 private static ToStaticAccessOperation[] createToStaticAccessOperations(CompilationUnit astRoot, IProblemLocation problem) { 571 ASTNode selectedNode= problem.getCoveringNode(astRoot); 572 if (selectedNode == null) { 573 return null; 574 } 575 576 Expression qualifier= null; 577 IBinding accessBinding= null; 578 579 if (selectedNode instanceof QualifiedName) { 580 QualifiedName name= (QualifiedName) selectedNode; 581 qualifier= name.getQualifier(); 582 accessBinding= name.resolveBinding(); 583 } else if (selectedNode instanceof SimpleName) { 584 ASTNode parent= selectedNode.getParent(); 585 if (parent instanceof FieldAccess) { 586 FieldAccess fieldAccess= (FieldAccess) parent; 587 qualifier= fieldAccess.getExpression(); 588 accessBinding= fieldAccess.getName().resolveBinding(); 589 } else if (parent instanceof QualifiedName) { 590 QualifiedName qualifiedName= (QualifiedName) parent; 591 qualifier= qualifiedName.getQualifier(); 592 accessBinding= qualifiedName.getName().resolveBinding(); 593 } 594 } else if (selectedNode instanceof MethodInvocation) { 595 MethodInvocation methodInvocation= (MethodInvocation) selectedNode; 596 qualifier= methodInvocation.getExpression(); 597 accessBinding= methodInvocation.getName().resolveBinding(); 598 } else if (selectedNode instanceof FieldAccess) { 599 FieldAccess fieldAccess= (FieldAccess) selectedNode; 600 qualifier= fieldAccess.getExpression(); 601 accessBinding= fieldAccess.getName().resolveBinding(); 602 } 603 604 if (accessBinding != null && qualifier != null) { 605 ToStaticAccessOperation declaring= null; 606 ITypeBinding declaringTypeBinding= getDeclaringTypeBinding(accessBinding); 607 if (declaringTypeBinding != null) { 608 declaringTypeBinding= declaringTypeBinding.getTypeDeclaration(); 610 declaring= new ToStaticAccessOperation(declaringTypeBinding, qualifier); 611 } 612 ToStaticAccessOperation instance= null; 613 ITypeBinding instanceTypeBinding= Bindings.normalizeTypeBinding(qualifier.resolveTypeBinding()); 614 if (instanceTypeBinding != null) { 615 instanceTypeBinding= instanceTypeBinding.getTypeDeclaration(); if (instanceTypeBinding.getTypeDeclaration() != declaringTypeBinding) { 617 instance= new ToStaticAccessOperation(instanceTypeBinding, qualifier); 618 } 619 } 620 if (declaring != null && instance != null) { 621 return new ToStaticAccessOperation[] {declaring, instance}; 622 } else { 623 return new ToStaticAccessOperation[] {declaring}; 624 } 625 } 626 return null; 627 } 628 629 private static ITypeBinding getDeclaringTypeBinding(IBinding accessBinding) { 630 if (accessBinding instanceof IMethodBinding) { 631 return ((IMethodBinding) accessBinding).getDeclaringClass(); 632 } else if (accessBinding instanceof IVariableBinding) { 633 return ((IVariableBinding) accessBinding).getDeclaringClass(); 634 } 635 return null; 636 } 637 638 private static AddThisQualifierOperation getUnqualifiedFieldAccessResolveOperation(CompilationUnit compilationUnit, IProblemLocation problem) throws CoreException { 639 SimpleName name= getName(compilationUnit, problem); 640 if (name == null) 641 return null; 642 643 IBinding binding= name.resolveBinding(); 644 if (binding == null || binding.getKind() != IBinding.VARIABLE) 645 return null; 646 647 ImportRewrite imports= StubUtility.createImportRewrite(compilationUnit, true); 648 649 String replacement= getQualifier((IVariableBinding)binding, imports, name); 650 if (replacement == null) 651 return null; 652 653 return new AddThisQualifierOperation(replacement, name); 654 } 655 656 private static String getQualifier(IVariableBinding binding, ImportRewrite imports, SimpleName name) { 657 ITypeBinding declaringClass= binding.getDeclaringClass(); 658 if (Modifier.isStatic(binding.getModifiers())) { 659 IJavaElement javaElement= declaringClass.getJavaElement(); 660 if (javaElement instanceof IType) { 661 return ((IType)javaElement).getElementName(); 662 } 663 } else { 664 return getNonStaticQualifier(declaringClass, imports, name); 665 } 666 667 return null; 668 } 669 670 private static String getNonStaticQualifier(ITypeBinding declaringClass, ImportRewrite imports, SimpleName name) { 671 ITypeBinding parentType= Bindings.getBindingOfParentType(name); 672 ITypeBinding currType= parentType; 673 while (currType != null && !Bindings.isSuperType(declaringClass, currType)) { 674 currType= currType.getDeclaringClass(); 675 } 676 if (currType == null) { 677 declaringClass= declaringClass.getTypeDeclaration(); 678 currType= parentType; 679 while (currType != null && !Bindings.isSuperType(declaringClass, currType)) { 680 currType= currType.getDeclaringClass(); 681 } 682 } 683 if (currType != parentType) { 684 if (currType == null) 685 return null; 686 687 if (currType.isAnonymous()) 688 return null; 692 693 String outer= imports.addImport(currType); 694 return outer + ".this"; } else { 696 return "this"; } 698 } 699 700 private static SimpleName getName(CompilationUnit compilationUnit, IProblemLocation problem) { 701 ASTNode selectedNode= problem.getCoveringNode(compilationUnit); 702 703 while (selectedNode instanceof QualifiedName) { 704 selectedNode= ((QualifiedName) selectedNode).getQualifier(); 705 } 706 if (!(selectedNode instanceof SimpleName)) { 707 return null; 708 } 709 return (SimpleName) selectedNode; 710 } 711 712 private CodeStyleFix(String name, CompilationUnit compilationUnit, IFixRewriteOperation[] fixRewriteOperations) { 713 super(name, compilationUnit, fixRewriteOperations); 714 } 715 } 716 | Popular Tags |