1 16 package org.eclipse.jdt.internal.corext.refactoring.code; 17 18 import java.util.ArrayList ; 19 import java.util.HashMap ; 20 import java.util.List ; 21 import java.util.Map ; 22 23 import org.eclipse.text.edits.MultiTextEdit; 24 import org.eclipse.text.edits.TextEdit; 25 import org.eclipse.text.edits.TextEditGroup; 26 27 import org.eclipse.core.runtime.Assert; 28 import org.eclipse.core.runtime.CoreException; 29 import org.eclipse.core.runtime.IProgressMonitor; 30 import org.eclipse.core.runtime.OperationCanceledException; 31 import org.eclipse.core.runtime.SubProgressMonitor; 32 33 import org.eclipse.core.resources.IFile; 34 import org.eclipse.core.resources.IResource; 35 36 import org.eclipse.ltk.core.refactoring.Change; 37 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; 38 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 39 import org.eclipse.ltk.core.refactoring.TextChange; 40 import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments; 41 import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker; 42 43 import org.eclipse.jdt.core.Flags; 44 import org.eclipse.jdt.core.IClassFile; 45 import org.eclipse.jdt.core.ICompilationUnit; 46 import org.eclipse.jdt.core.IJavaElement; 47 import org.eclipse.jdt.core.IJavaProject; 48 import org.eclipse.jdt.core.IMethod; 49 import org.eclipse.jdt.core.IType; 50 import org.eclipse.jdt.core.ITypeHierarchy; 51 import org.eclipse.jdt.core.ITypeRoot; 52 import org.eclipse.jdt.core.JavaModelException; 53 import org.eclipse.jdt.core.dom.AST; 54 import org.eclipse.jdt.core.dom.ASTNode; 55 import org.eclipse.jdt.core.dom.BodyDeclaration; 56 import org.eclipse.jdt.core.dom.CompilationUnit; 57 import org.eclipse.jdt.core.dom.ConstructorInvocation; 58 import org.eclipse.jdt.core.dom.ExpressionStatement; 59 import org.eclipse.jdt.core.dom.IMethodBinding; 60 import org.eclipse.jdt.core.dom.ITypeBinding; 61 import org.eclipse.jdt.core.dom.MethodDeclaration; 62 import org.eclipse.jdt.core.dom.MethodInvocation; 63 import org.eclipse.jdt.core.dom.Modifier; 64 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 65 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 66 import org.eclipse.jdt.core.refactoring.IJavaRefactorings; 67 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor; 68 69 import org.eclipse.jdt.internal.corext.dom.NodeFinder; 70 import org.eclipse.jdt.internal.corext.refactoring.Checks; 71 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptor; 72 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; 73 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments; 74 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 75 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext; 76 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange; 77 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange; 78 import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility; 79 import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil; 80 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; 81 import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager; 82 import org.eclipse.jdt.internal.corext.util.Messages; 83 84 import org.eclipse.jdt.ui.JavaElementLabels; 85 86 import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider; 87 88 97 public class InlineMethodRefactoring extends ScriptableRefactoring { 98 99 private static final String ATTRIBUTE_MODE= "mode"; private static final String ATTRIBUTE_DELETE= "delete"; 102 public static class Mode { 103 private Mode() { 104 } 105 public static final Mode INLINE_ALL= new Mode(); 106 public static final Mode INLINE_SINGLE= new Mode(); 107 } 108 109 private ITypeRoot fInitialTypeRoot; 110 private ASTNode fInitialNode; 111 private TextChangeManager fChangeManager; 112 private SourceProvider fSourceProvider; 113 private TargetProvider fTargetProvider; 114 117 private boolean fDeleteSource; 118 private Mode fCurrentMode; 119 private Mode fInitialMode; 120 private int fSelectionStart; 121 private int fSelectionLength; 122 123 private InlineMethodRefactoring(ITypeRoot typeRoot, ASTNode node, int offset, int length) { 124 Assert.isNotNull(typeRoot); 125 Assert.isTrue(JavaElementUtil.isSourceAvailable(typeRoot)); 126 Assert.isNotNull(node); 127 fInitialTypeRoot= typeRoot; 128 fInitialNode= node; 129 fSelectionStart= offset; 130 fSelectionLength= length; 131 } 132 133 private InlineMethodRefactoring(ICompilationUnit unit, MethodInvocation node, int offset, int length) { 134 this(unit, (ASTNode)node, offset, length); 135 fTargetProvider= TargetProvider.create(unit, node); 136 fInitialMode= fCurrentMode= Mode.INLINE_SINGLE; 137 fDeleteSource= false; 138 } 139 140 private InlineMethodRefactoring(ICompilationUnit unit, SuperMethodInvocation node, int offset, int length) { 141 this(unit, (ASTNode)node, offset, length); 142 fTargetProvider= TargetProvider.create(unit, node); 143 fInitialMode= fCurrentMode= Mode.INLINE_SINGLE; 144 fDeleteSource= false; 145 } 146 147 private InlineMethodRefactoring(ICompilationUnit unit, ConstructorInvocation node, int offset, int length) { 148 this(unit, (ASTNode)node, offset, length); 149 fTargetProvider= TargetProvider.create(unit, node); 150 fInitialMode= fCurrentMode= Mode.INLINE_SINGLE; 151 fDeleteSource= false; 152 } 153 154 private InlineMethodRefactoring(ITypeRoot typeRoot, MethodDeclaration node, int offset, int length) { 155 this(typeRoot, (ASTNode)node, offset, length); 156 fSourceProvider= new SourceProvider(typeRoot, node); 157 fTargetProvider= TargetProvider.create(node); 158 fInitialMode= fCurrentMode= Mode.INLINE_ALL; 159 fDeleteSource= canEnableDeleteSource(); 160 } 161 162 169 public static InlineMethodRefactoring create(ITypeRoot unit, CompilationUnit node, int selectionStart, int selectionLength) { 170 ASTNode target= getTargetNode(unit, node, selectionStart, selectionLength); 171 if (target == null) 172 return null; 173 if (target.getNodeType() == ASTNode.METHOD_DECLARATION) { 174 175 return new InlineMethodRefactoring(unit, (MethodDeclaration)target, selectionStart, selectionLength); 176 } else { 177 ICompilationUnit cu= (ICompilationUnit) unit; 178 if (target.getNodeType() == ASTNode.METHOD_INVOCATION) { 179 return new InlineMethodRefactoring(cu, (MethodInvocation)target, selectionStart, selectionLength); 180 } else if (target.getNodeType() == ASTNode.SUPER_METHOD_INVOCATION) { 181 return new InlineMethodRefactoring(cu, (SuperMethodInvocation)target, selectionStart, selectionLength); 182 } else if (target.getNodeType() == ASTNode.CONSTRUCTOR_INVOCATION) { 183 return new InlineMethodRefactoring(cu, (ConstructorInvocation)target, selectionStart, selectionLength); 184 } 185 } 186 return null; 187 } 188 189 public String getName() { 190 return RefactoringCoreMessages.InlineMethodRefactoring_name; 191 } 192 193 public boolean canEnableDeleteSource() { 194 return ! (fSourceProvider.getTypeRoot() instanceof IClassFile); 195 } 196 197 public boolean getDeleteSource() { 198 return fDeleteSource; 199 } 200 201 public void setDeleteSource(boolean remove) { 202 if (remove) 203 Assert.isTrue(canEnableDeleteSource()); 204 fDeleteSource= remove; 205 } 206 207 public Mode getInitialMode() { 208 return fInitialMode; 209 } 210 211 public RefactoringStatus setCurrentMode(Mode mode) throws JavaModelException { 212 if (fCurrentMode == mode) 213 return new RefactoringStatus(); 214 Assert.isTrue(getInitialMode() == Mode.INLINE_SINGLE); 215 fCurrentMode= mode; 216 if (mode == Mode.INLINE_SINGLE) { 217 if (fInitialNode instanceof MethodInvocation) 218 fTargetProvider= TargetProvider.create((ICompilationUnit) fInitialTypeRoot, (MethodInvocation)fInitialNode); 219 else if (fInitialNode instanceof SuperMethodInvocation) 220 fTargetProvider= TargetProvider.create((ICompilationUnit) fInitialTypeRoot, (SuperMethodInvocation)fInitialNode); 221 else if (fInitialNode instanceof ConstructorInvocation) 222 fTargetProvider= TargetProvider.create((ICompilationUnit) fInitialTypeRoot, (ConstructorInvocation)fInitialNode); 223 else 224 throw new IllegalStateException (String.valueOf(fInitialNode)); 225 } else { 226 fTargetProvider= TargetProvider.create(fSourceProvider.getDeclaration()); 227 } 228 return fTargetProvider.checkActivation(); 229 } 230 231 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { 232 RefactoringStatus result= new RefactoringStatus(); 233 if (fSourceProvider == null && Invocations.isInvocation(fInitialNode)) { 234 fSourceProvider= resolveSourceProvider(result, fInitialTypeRoot, fInitialNode); 235 if (result.hasFatalError()) 236 return result; 237 } 238 fTargetProvider.setSourceProvider(fSourceProvider); 239 result.merge(fSourceProvider.checkActivation()); 240 result.merge(fTargetProvider.checkActivation()); 241 return result; 242 } 243 244 public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException { 245 pm.beginTask("", 20); fChangeManager= new TextChangeManager(); 247 RefactoringStatus result= new RefactoringStatus(); 248 fSourceProvider.initialize(); 249 fTargetProvider.initialize(); 250 pm.setTaskName(RefactoringCoreMessages.InlineMethodRefactoring_searching); 251 RefactoringStatus searchStatus= new RefactoringStatus(); 252 ICompilationUnit[] units= fTargetProvider.getAffectedCompilationUnits(searchStatus, new SubProgressMonitor(pm, 1)); 253 if (searchStatus.hasFatalError()) { 254 result.merge(searchStatus); 255 return result; 256 } 257 IFile[] filesToBeModified= getFilesToBeModified(units); 258 result.merge(Checks.validateModifiesFiles(filesToBeModified, getValidationContext())); 259 if (result.hasFatalError()) 260 return result; 261 result.merge(ResourceChangeChecker.checkFilesToBeChanged(filesToBeModified, new SubProgressMonitor(pm, 1))); 262 checkOverridden(result, new SubProgressMonitor(pm, 4)); 263 IProgressMonitor sub= new SubProgressMonitor(pm, 15); 264 sub.beginTask("", units.length * 3); for (int c= 0; c < units.length; c++) { 266 ICompilationUnit unit= units[c]; 267 sub.subTask(Messages.format(RefactoringCoreMessages.InlineMethodRefactoring_processing, unit.getElementName())); 268 CallInliner inliner= null; 269 try { 270 boolean added= false; 271 MultiTextEdit root= new MultiTextEdit(); 272 CompilationUnitChange change= (CompilationUnitChange)fChangeManager.get(unit); 273 change.setEdit(root); 274 BodyDeclaration[] bodies= fTargetProvider.getAffectedBodyDeclarations(unit, new SubProgressMonitor(pm, 1)); 275 if (bodies.length == 0) 276 continue; 277 inliner= new CallInliner(unit, (CompilationUnit) bodies[0].getRoot(), fSourceProvider); 278 for (int b= 0; b < bodies.length; b++) { 279 BodyDeclaration body= bodies[b]; 280 inliner.initialize(body); 281 RefactoringStatus nestedInvocations= new RefactoringStatus(); 282 ASTNode[] invocations= removeNestedCalls(nestedInvocations, unit, 283 fTargetProvider.getInvocations(body, new SubProgressMonitor(sub, 2))); 284 for (int i= 0; i < invocations.length; i++) { 285 ASTNode invocation= invocations[i]; 286 result.merge(inliner.initialize(invocation, fTargetProvider.getStatusSeverity())); 287 if (result.hasFatalError()) 288 break; 289 if (result.getSeverity() < fTargetProvider.getStatusSeverity()) { 290 added= true; 291 TextEditGroup group= new TextEditGroup(RefactoringCoreMessages.InlineMethodRefactoring_edit_inline); 292 change.addTextEditGroup(group); 293 result.merge(inliner.perform(group)); 294 } else { 295 fDeleteSource= false; 296 } 297 } 298 if (!nestedInvocations.isOK()) { 301 result.merge(nestedInvocations); 302 fDeleteSource= false; 303 } 304 } 305 if (!added) { 306 fChangeManager.remove(unit); 307 } else { 308 root.addChild(inliner.getModifications()); 309 ImportRewrite rewrite= inliner.getImportEdit(); 310 if (rewrite.hasRecordedChanges()) { 311 TextEdit edit= rewrite.rewriteImports(null); 312 if (edit instanceof MultiTextEdit ? ((MultiTextEdit)edit).getChildrenSize() > 0 : true) { 313 root.addChild(edit); 314 change.addTextEditGroup( 315 new TextEditGroup(RefactoringCoreMessages.InlineMethodRefactoring_edit_import, new TextEdit[] {edit})); 316 } 317 } 318 } 319 } finally { 320 if (inliner != null) 321 inliner.dispose(); 322 } 323 sub.worked(1); 324 if (sub.isCanceled()) 325 throw new OperationCanceledException(); 326 } 327 result.merge(searchStatus); 328 sub.done(); 329 pm.done(); 330 return result; 331 } 332 333 public Change createChange(IProgressMonitor pm) throws CoreException { 334 if (fDeleteSource && fCurrentMode == Mode.INLINE_ALL) { 335 TextChange change= fChangeManager.get((ICompilationUnit) fSourceProvider.getTypeRoot()); 336 TextEdit delete= fSourceProvider.getDeleteEdit(); 337 TextEditGroup description= new TextEditGroup( 338 RefactoringCoreMessages.InlineMethodRefactoring_edit_delete, new TextEdit[] { delete }); 339 TextEdit root= change.getEdit(); 340 if (root != null) { 341 TextChangeCompatibility.insert(root, delete); 347 } else { 348 change.setEdit(delete); 349 } 350 change.addTextEditGroup(description); 351 } 352 final Map arguments= new HashMap (); 353 String project= null; 354 IJavaProject javaProject= fInitialTypeRoot.getJavaProject(); 355 if (javaProject != null) 356 project= javaProject.getElementName(); 357 int flags= RefactoringDescriptor.STRUCTURAL_CHANGE | JavaRefactoringDescriptor.JAR_REFACTORING | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT; 358 final IMethodBinding binding= fSourceProvider.getDeclaration().resolveBinding(); 359 final ITypeBinding declaring= binding.getDeclaringClass(); 360 if (!Modifier.isPrivate(binding.getModifiers())) 361 flags|= RefactoringDescriptor.MULTI_CHANGE; 362 final String description= Messages.format(RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description_short, binding.getName()); 363 final String header= Messages.format(RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description, new String [] { BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED), BindingLabelProvider.getBindingLabel(declaring, JavaElementLabels.ALL_FULLY_QUALIFIED)}); 364 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header); 365 comment.addSetting(Messages.format(RefactoringCoreMessages.InlineMethodRefactoring_original_pattern, BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED))); 366 if (fDeleteSource) 367 comment.addSetting(RefactoringCoreMessages.InlineMethodRefactoring_remove_method); 368 if (fCurrentMode == Mode.INLINE_ALL) 369 comment.addSetting(RefactoringCoreMessages.InlineMethodRefactoring_replace_references); 370 final JDTRefactoringDescriptor descriptor= new JDTRefactoringDescriptor(IJavaRefactorings.INLINE_METHOD, project, description, comment.asString(), arguments, flags); 371 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_INPUT, descriptor.elementToHandle(fInitialTypeRoot)); 372 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_SELECTION, new Integer (fSelectionStart).toString() + " " + new Integer (fSelectionLength).toString()); arguments.put(ATTRIBUTE_DELETE, Boolean.valueOf(fDeleteSource).toString()); 374 arguments.put(ATTRIBUTE_MODE, new Integer (fCurrentMode == Mode.INLINE_ALL ? 1 : 0).toString()); 375 return new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.InlineMethodRefactoring_edit_inlineCall, fChangeManager.getAllChanges()); 376 } 377 378 private static SourceProvider resolveSourceProvider(RefactoringStatus status, ITypeRoot typeRoot, ASTNode invocation) throws JavaModelException { 379 CompilationUnit root= (CompilationUnit)invocation.getRoot(); 380 IMethodBinding methodBinding= Invocations.resolveBinding(invocation); 381 if (methodBinding == null) { 382 status.addFatalError(RefactoringCoreMessages.InlineMethodRefactoring_error_noMethodDeclaration); 383 return null; 384 } 385 MethodDeclaration declaration= (MethodDeclaration)root.findDeclaringNode(methodBinding); 386 if (declaration != null) { 387 return new SourceProvider(typeRoot, declaration); 388 } 389 IMethod method= (IMethod)methodBinding.getJavaElement(); 390 if (method != null) { 391 CompilationUnit methodDeclarationAstRoot; 392 ICompilationUnit methodCu= method.getCompilationUnit(); 393 if (methodCu != null) { 394 methodDeclarationAstRoot= new RefactoringASTParser(AST.JLS3).parse(methodCu, true); 395 } else { 396 IClassFile classFile= method.getClassFile(); 397 if (! JavaElementUtil.isSourceAvailable(classFile)) { 398 String methodLabel= JavaElementLabels.getTextLabel(method, JavaElementLabels.M_FULLY_QUALIFIED | JavaElementLabels.M_PARAMETER_TYPES); 399 status.addFatalError(Messages.format(RefactoringCoreMessages.InlineMethodRefactoring_error_classFile, methodLabel)); 400 return null; 401 } 402 methodDeclarationAstRoot= new RefactoringASTParser(AST.JLS3).parse(classFile, true); 403 } 404 ASTNode node= methodDeclarationAstRoot.findDeclaringNode(methodBinding.getMethodDeclaration().getKey()); 405 if (node instanceof MethodDeclaration) { 406 return new SourceProvider(methodDeclarationAstRoot.getTypeRoot(), (MethodDeclaration) node); 407 } 408 } 409 status.addFatalError(RefactoringCoreMessages.InlineMethodRefactoring_error_noMethodDeclaration); 410 return null; 411 } 412 413 private static ASTNode getTargetNode(ITypeRoot typeRoot, CompilationUnit root, int offset, int length) { 414 ASTNode node= null; 415 try { 416 node= checkNode(NodeFinder.perform(root, offset, length, typeRoot), typeRoot); 417 } catch(JavaModelException e) { 418 } 420 if (node != null) 421 return node; 422 return checkNode(NodeFinder.perform(root, offset, length), typeRoot); 423 } 424 425 private static ASTNode checkNode(ASTNode node, IJavaElement unit) { 426 if (node == null) 427 return null; 428 if (node.getNodeType() == ASTNode.SIMPLE_NAME) { 429 node= node.getParent(); 430 } else if (node.getNodeType() == ASTNode.EXPRESSION_STATEMENT) { 431 node= ((ExpressionStatement)node).getExpression(); 432 } 433 switch(node.getNodeType()) { 434 case ASTNode.METHOD_DECLARATION: 435 return node; 436 case ASTNode.METHOD_INVOCATION: 437 case ASTNode.SUPER_METHOD_INVOCATION: 438 case ASTNode.CONSTRUCTOR_INVOCATION: 439 return unit instanceof ICompilationUnit ? node : null; } 441 return null; 442 } 443 444 private IFile[] getFilesToBeModified(ICompilationUnit[] units) { 445 List result= new ArrayList (units.length + 1); 446 IFile file; 447 for (int i= 0; i < units.length; i++) { 448 file= getFile(units[i]); 449 if (file != null) 450 result.add(file); 451 } 452 if (fDeleteSource) { 453 file= getFile((ICompilationUnit) fSourceProvider.getTypeRoot()); 454 if (file != null && !result.contains(file)) 455 result.add(file); 456 } 457 return (IFile[])result.toArray(new IFile[result.size()]); 458 } 459 460 private IFile getFile(ICompilationUnit unit) { 461 unit= unit.getPrimary(); 462 IResource resource= unit.getResource(); 463 if (resource != null && resource.getType() == IResource.FILE) 464 return (IFile)resource; 465 return null; 466 } 467 468 private void checkOverridden(RefactoringStatus status, IProgressMonitor pm) throws JavaModelException { 469 pm.beginTask("", 9); pm.setTaskName(RefactoringCoreMessages.InlineMethodRefactoring_checking_overridden); 471 MethodDeclaration decl= fSourceProvider.getDeclaration(); 472 IMethod method= (IMethod) decl.resolveBinding().getJavaElement(); 473 if (method == null || Flags.isPrivate(method.getFlags())) { 474 pm.worked(8); 475 return; 476 } 477 IType type= method.getDeclaringType(); 478 ITypeHierarchy hierarchy= type.newTypeHierarchy(new SubProgressMonitor(pm, 6)); 479 checkSubTypes(status, method, hierarchy.getAllSubtypes(type), new SubProgressMonitor(pm, 1)); 480 checkSuperClasses(status, method, hierarchy.getAllSuperclasses(type), new SubProgressMonitor(pm, 1)); 481 checkSuperInterfaces(status, method, hierarchy.getAllSuperInterfaces(type), new SubProgressMonitor(pm, 1)); 482 pm.setTaskName(""); } 484 485 private void checkSubTypes(RefactoringStatus result, IMethod method, IType[] types, IProgressMonitor pm) { 486 checkTypes( 487 result, method, types, 488 RefactoringCoreMessages.InlineMethodRefactoring_checking_overridden_error, 489 pm); 490 } 491 492 private void checkSuperClasses(RefactoringStatus result, IMethod method, IType[] types, IProgressMonitor pm) { 493 checkTypes( 494 result, method, types, 495 RefactoringCoreMessages.InlineMethodRefactoring_checking_overrides_error, 496 pm); 497 } 498 499 private void checkSuperInterfaces(RefactoringStatus result, IMethod method, IType[] types, IProgressMonitor pm) { 500 checkTypes( 501 result, method, types, 502 RefactoringCoreMessages.InlineMethodRefactoring_checking_implements_error, 503 pm); 504 } 505 private void checkTypes(RefactoringStatus result, IMethod method, IType[] types, String key, IProgressMonitor pm) { 506 pm.beginTask("", types.length); for (int i= 0; i < types.length; i++) { 508 pm.worked(1); 509 IMethod[] overridden= types[i].findMethods(method); 510 if (overridden != null && overridden.length > 0) { 511 result.addError( 512 Messages.format(key, types[i].getElementName()), 513 JavaStatusContext.create(overridden[0])); 514 } 515 } 516 } 517 518 private ASTNode[] removeNestedCalls(RefactoringStatus status, ICompilationUnit unit, ASTNode[] invocations) { 519 if (invocations.length <= 1) 520 return invocations; 521 ASTNode[] parents= new ASTNode[invocations.length]; 522 for (int i= 0; i < invocations.length; i++) { 523 parents[i]= invocations[i].getParent(); 524 } 525 for (int i= 0; i < invocations.length; i++) { 526 removeNestedCalls(status, unit, parents, invocations, i); 527 } 528 List result= new ArrayList (); 529 for (int i= 0; i < invocations.length; i++) { 530 if (invocations[i] != null) 531 result.add(invocations[i]); 532 } 533 return (ASTNode[])result.toArray(new ASTNode[result.size()]); 534 } 535 536 private void removeNestedCalls(RefactoringStatus status, ICompilationUnit unit, ASTNode[] parents, ASTNode[] invocations, int index) { 537 ASTNode invocation= invocations[index]; 538 for (int i= 0; i < parents.length; i++) { 539 ASTNode parent= parents[i]; 540 while (parent != null) { 541 if (parent == invocation) { 542 status.addError(RefactoringCoreMessages.InlineMethodRefactoring_nestedInvocation, 543 JavaStatusContext.create(unit, parent)); 544 invocations[index]= null; 545 } 546 parent= parent.getParent(); 547 } 548 } 549 } 550 551 public RefactoringStatus initialize(final RefactoringArguments arguments) { 552 if (arguments instanceof JavaRefactoringArguments) { 553 final JavaRefactoringArguments generic= (JavaRefactoringArguments) arguments; 554 final String delete= generic.getAttribute(ATTRIBUTE_DELETE); 555 if (delete != null) { 556 fDeleteSource= Boolean.valueOf(delete).booleanValue(); 557 } else 558 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DELETE)); 559 final String value= generic.getAttribute(ATTRIBUTE_MODE); 560 if (value != null && !"".equals(value)) { int mode= 0; 562 try { 563 mode= Integer.parseInt(value); 564 } catch (NumberFormatException exception) { 565 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_MODE)); 566 } 567 try { 568 setCurrentMode(mode == 1 ? Mode.INLINE_ALL : Mode.INLINE_SINGLE); 569 } catch (JavaModelException exception) { 570 return RefactoringStatus.createFatalErrorStatus(exception.getLocalizedMessage()); 571 } 572 } 573 } else 574 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments); 575 return new RefactoringStatus(); 576 } 577 } 578 | Popular Tags |