1 11 package org.eclipse.jdt.internal.corext.refactoring.structure; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 20 import org.eclipse.text.edits.MalformedTreeException; 21 import org.eclipse.text.edits.TextEdit; 22 23 import org.eclipse.core.runtime.IProgressMonitor; 24 import org.eclipse.core.runtime.SubProgressMonitor; 25 26 import org.eclipse.jface.text.BadLocationException; 27 import org.eclipse.jface.text.Document; 28 import org.eclipse.jface.text.IDocument; 29 import org.eclipse.jface.text.TextUtilities; 30 31 import org.eclipse.ltk.core.refactoring.Refactoring; 32 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 33 import org.eclipse.ltk.core.refactoring.RefactoringStatusContext; 34 35 import org.eclipse.jdt.core.Flags; 36 import org.eclipse.jdt.core.ICompilationUnit; 37 import org.eclipse.jdt.core.IField; 38 import org.eclipse.jdt.core.IInitializer; 39 import org.eclipse.jdt.core.IMember; 40 import org.eclipse.jdt.core.IMethod; 41 import org.eclipse.jdt.core.ISourceRange; 42 import org.eclipse.jdt.core.IType; 43 import org.eclipse.jdt.core.ITypeHierarchy; 44 import org.eclipse.jdt.core.JavaModelException; 45 import org.eclipse.jdt.core.dom.AST; 46 import org.eclipse.jdt.core.dom.ASTNode; 47 import org.eclipse.jdt.core.dom.ASTVisitor; 48 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; 49 import org.eclipse.jdt.core.dom.BodyDeclaration; 50 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 51 import org.eclipse.jdt.core.dom.CompilationUnit; 52 import org.eclipse.jdt.core.dom.EnumDeclaration; 53 import org.eclipse.jdt.core.dom.Expression; 54 import org.eclipse.jdt.core.dom.FieldDeclaration; 55 import org.eclipse.jdt.core.dom.ITypeBinding; 56 import org.eclipse.jdt.core.dom.Javadoc; 57 import org.eclipse.jdt.core.dom.MethodDeclaration; 58 import org.eclipse.jdt.core.dom.Modifier; 59 import org.eclipse.jdt.core.dom.Name; 60 import org.eclipse.jdt.core.dom.SimpleName; 61 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 62 import org.eclipse.jdt.core.dom.Type; 63 import org.eclipse.jdt.core.dom.TypeDeclaration; 64 import org.eclipse.jdt.core.dom.TypeParameter; 65 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 66 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 67 import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition; 68 import org.eclipse.jdt.core.search.IJavaSearchConstants; 69 import org.eclipse.jdt.core.search.SearchMatch; 70 import org.eclipse.jdt.core.search.SearchPattern; 71 72 import org.eclipse.jdt.internal.corext.Assert; 73 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 74 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 75 import org.eclipse.jdt.internal.corext.dom.ModifierRewrite; 76 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 77 import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory; 78 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2; 79 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; 80 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext; 81 import org.eclipse.jdt.internal.corext.refactoring.reorg.SourceReferenceUtil; 82 import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil; 83 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; 84 import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager; 85 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 86 import org.eclipse.jdt.internal.corext.util.JdtFlags; 87 import org.eclipse.jdt.internal.corext.util.Messages; 88 import org.eclipse.jdt.internal.corext.util.SearchUtils; 89 import org.eclipse.jdt.internal.corext.util.Strings; 90 import org.eclipse.jdt.internal.corext.util.WorkingCopyUtil; 91 92 import org.eclipse.jdt.internal.ui.JavaPlugin; 93 94 97 public abstract class HierarchyRefactoring extends Refactoring { 98 99 102 public static class TypeVariableMapper extends ASTVisitor { 103 104 105 protected final TypeVariableMaplet[] fMapping; 106 107 108 protected final ASTRewrite fRewrite; 109 110 116 public TypeVariableMapper(final ASTRewrite rewrite, final TypeVariableMaplet[] mapping) { 117 Assert.isNotNull(rewrite); 118 Assert.isNotNull(mapping); 119 fRewrite= rewrite; 120 fMapping= mapping; 121 } 122 123 public final boolean visit(final SimpleName node) { 124 final ITypeBinding binding= node.resolveTypeBinding(); 125 if (binding != null && binding.isTypeVariable()) { 126 String name= null; 127 for (int index= 0; index < fMapping.length; index++) { 128 name= binding.getName(); 129 if (fMapping[index].getSourceName().equals(name) && node.getIdentifier().equals(name)) 130 fRewrite.set(node, SimpleName.IDENTIFIER_PROPERTY, fMapping[index].getTargetName(), null); 131 } 132 } 133 return true; 134 } 135 } 136 137 protected static boolean areAllFragmentsDeleted(final FieldDeclaration declaration, final List declarationNodes) { 138 for (final Iterator iterator= declaration.fragments().iterator(); iterator.hasNext();) { 139 if (!declarationNodes.contains(iterator.next())) 140 return false; 141 } 142 return true; 143 } 144 145 protected static RefactoringStatus checkCallsToClassConstructors(final IType type, final IProgressMonitor monitor) throws JavaModelException { 146 final RefactoringStatus result= new RefactoringStatus(); 147 final SearchResultGroup[] groups= ConstructorReferenceFinder.getConstructorReferences(type, monitor, result); 148 final String message= Messages.format(RefactoringCoreMessages.HierarchyRefactoring_gets_instantiated, new Object [] { createTypeLabel(type)}); 149 150 ICompilationUnit unit= null; 151 for (int index= 0; index < groups.length; index++) { 152 unit= groups[index].getCompilationUnit(); 153 if (unit != null) { 154 final CompilationUnit cuNode= new RefactoringASTParser(AST.JLS3).parse(unit, false); 155 final ASTNode[] references= ASTNodeSearchUtil.getAstNodes(groups[index].getSearchResults(), cuNode); 156 ASTNode node= null; 157 for (int offset= 0; offset < references.length; offset++) { 158 node= references[offset]; 159 if ((node instanceof ClassInstanceCreation) || ConstructorReferenceFinder.isImplicitConstructorReferenceNodeInClassCreations(node)) { 160 RefactoringStatusContext context= JavaStatusContext.create(unit, node); 161 result.addError(message, context); 162 } 163 } 164 } 165 } 166 monitor.done(); 167 return result; 168 } 169 170 protected static void copyJavadocNode(final ASTRewrite rewrite, final IMember member, final BodyDeclaration oldDeclaration, final BodyDeclaration newDeclaration) throws JavaModelException { 171 final Javadoc predecessor= oldDeclaration.getJavadoc(); 172 if (predecessor != null) { 173 final IDocument buffer= new Document(member.getCompilationUnit().getBuffer().getContents()); 174 try { 175 final String [] lines= Strings.convertIntoLines(buffer.get(predecessor.getStartPosition(), predecessor.getLength())); 176 Strings.trimIndentation(lines, member.getJavaProject(), false); 177 final Javadoc successor= (Javadoc) rewrite.createStringPlaceholder(Strings.concatenate(lines, TextUtilities.getDefaultLineDelimiter(buffer)), ASTNode.JAVADOC); 178 newDeclaration.setJavadoc(successor); 179 } catch (BadLocationException exception) { 180 JavaPlugin.log(exception); 181 } 182 } 183 } 184 185 protected static void copyThrownExceptions(MethodDeclaration oldMethod, MethodDeclaration newMethod) { 186 final AST ast= newMethod.getAST(); 187 for (int index= 0, n= oldMethod.thrownExceptions().size(); index < n; index++) 188 newMethod.thrownExceptions().add(index, ASTNode.copySubtree(ast, (Name) oldMethod.thrownExceptions().get(index))); 189 } 190 191 protected static void copyTypeParameters(MethodDeclaration oldMethod, MethodDeclaration newMethod) { 192 final AST ast= newMethod.getAST(); 193 for (int index= 0, n= oldMethod.typeParameters().size(); index < n; index++) 194 newMethod.typeParameters().add(index, ASTNode.copySubtree(ast, (TypeParameter) oldMethod.typeParameters().get(index))); 195 } 196 197 protected static String createFieldLabel(final IField field) { 198 return field.getElementName(); 199 } 200 201 protected static String createLabel(final IMember member) { 202 if (member instanceof IType) 203 return createTypeLabel((IType) member); 204 else if (member instanceof IMethod) 205 return createMethodLabel((IMethod) member); 206 else if (member instanceof IField) 207 return createFieldLabel((IField) member); 208 else if (member instanceof IInitializer) 209 return RefactoringCoreMessages.HierarchyRefactoring_initializer; 210 Assert.isTrue(false); 211 return null; 212 } 213 214 protected static String createMethodLabel(final IMethod method) { 215 return JavaElementUtil.createMethodSignature(method); 216 } 217 218 protected static FieldDeclaration createNewFieldDeclarationNode(final ASTRewrite rewrite, final CompilationUnit unit, final IField field, final VariableDeclarationFragment oldFieldFragment, final TypeVariableMaplet[] mapping, final IProgressMonitor monitor, final RefactoringStatus status, final int modifiers) throws JavaModelException { 219 final VariableDeclarationFragment newFragment= rewrite.getAST().newVariableDeclarationFragment(); 220 newFragment.setExtraDimensions(oldFieldFragment.getExtraDimensions()); 221 if (oldFieldFragment.getInitializer() != null) { 222 Expression newInitializer= null; 223 if (mapping.length > 0) 224 newInitializer= createPlaceholderForExpression(oldFieldFragment.getInitializer(), field.getCompilationUnit(), mapping, rewrite); 225 else 226 newInitializer= createPlaceholderForExpression(oldFieldFragment.getInitializer(), field.getCompilationUnit(), rewrite); 227 newFragment.setInitializer(newInitializer); 228 } 229 newFragment.setName(((SimpleName) ASTNode.copySubtree(rewrite.getAST(), oldFieldFragment.getName()))); 230 final FieldDeclaration newField= rewrite.getAST().newFieldDeclaration(newFragment); 231 final FieldDeclaration oldField= ASTNodeSearchUtil.getFieldDeclarationNode(field, unit); 232 copyJavadocNode(rewrite, field, oldField, newField); 233 newField.modifiers().addAll(ASTNodeFactory.newModifiers(rewrite.getAST(), modifiers)); 234 Type oldType= oldField.getType(); 235 Type newType= null; 236 if (mapping.length > 0) { 237 newType= createPlaceholderForType(oldType, field.getCompilationUnit(), mapping, rewrite); 238 } else 239 newType= createPlaceholderForType(oldType, field.getCompilationUnit(), rewrite); 240 newField.setType(newType); 241 return newField; 242 } 243 244 protected static Expression createPlaceholderForExpression(final Expression expression, final ICompilationUnit declaringCu, final ASTRewrite rewrite) throws JavaModelException { 245 return (Expression) rewrite.createStringPlaceholder(declaringCu.getBuffer().getText(expression.getStartPosition(), expression.getLength()), ASTNode.METHOD_INVOCATION); 246 } 247 248 protected static Expression createPlaceholderForExpression(final Expression expression, final ICompilationUnit declaringCu, final TypeVariableMaplet[] mapping, final ASTRewrite rewrite) throws JavaModelException { 249 Expression result= null; 250 try { 251 final IDocument document= new Document(declaringCu.getBuffer().getContents()); 252 final ASTRewrite rewriter= ASTRewrite.create(expression.getAST()); 253 final ITrackedNodePosition position= rewriter.track(expression); 254 expression.accept(new TypeVariableMapper(rewriter, mapping)); 255 rewriter.rewriteAST(document, declaringCu.getJavaProject().getOptions(true)).apply(document, TextEdit.NONE); 256 result= (Expression) rewrite.createStringPlaceholder(document.get(position.getStartPosition(), position.getLength()), ASTNode.METHOD_INVOCATION); 257 } catch (MalformedTreeException exception) { 258 JavaPlugin.log(exception); 259 } catch (BadLocationException exception) { 260 JavaPlugin.log(exception); 261 } 262 return result; 263 } 264 265 protected static BodyDeclaration createPlaceholderForProtectedTypeDeclaration(final BodyDeclaration bodyDeclaration, final CompilationUnit declaringCuNode, final ICompilationUnit declaringCu, final ASTRewrite rewrite, final boolean removeIndentation) throws JavaModelException { 266 String text= null; 267 try { 268 final ASTRewrite rewriter= ASTRewrite.create(bodyDeclaration.getAST()); 269 ModifierRewrite.create(rewriter, bodyDeclaration).setVisibility(Modifier.PROTECTED, null); 270 final ITrackedNodePosition position= rewriter.track(bodyDeclaration); 271 final IDocument document= new Document(declaringCu.getBuffer().getText(declaringCuNode.getStartPosition(), declaringCuNode.getLength())); 272 rewriter.rewriteAST(document, declaringCu.getJavaProject().getOptions(true)).apply(document, TextEdit.UPDATE_REGIONS); 273 text= document.get(position.getStartPosition(), position.getLength()); 274 } catch (BadLocationException exception) { 275 text= getNewText(bodyDeclaration, declaringCu, removeIndentation); 276 } 277 return (BodyDeclaration) rewrite.createStringPlaceholder(text, ASTNode.TYPE_DECLARATION); 278 } 279 280 protected static BodyDeclaration createPlaceholderForProtectedTypeDeclaration(final BodyDeclaration bodyDeclaration, final CompilationUnit declaringCuNode, final ICompilationUnit declaringCu, final TypeVariableMaplet[] mapping, final ASTRewrite rewrite, final boolean removeIndentation) throws JavaModelException { 281 BodyDeclaration result= null; 282 try { 283 final IDocument document= new Document(declaringCu.getBuffer().getContents()); 284 final ASTRewrite rewriter= ASTRewrite.create(bodyDeclaration.getAST()); 285 final ITrackedNodePosition position= rewriter.track(bodyDeclaration); 286 bodyDeclaration.accept(new TypeVariableMapper(rewriter, mapping) { 287 288 public final boolean visit(final AnnotationTypeDeclaration node) { 289 ModifierRewrite.create(fRewrite, bodyDeclaration).setVisibility(Modifier.PROTECTED, null); 290 return true; 291 } 292 293 public final boolean visit(final EnumDeclaration node) { 294 ModifierRewrite.create(fRewrite, bodyDeclaration).setVisibility(Modifier.PROTECTED, null); 295 return true; 296 } 297 298 public final boolean visit(final TypeDeclaration node) { 299 ModifierRewrite.create(fRewrite, bodyDeclaration).setVisibility(Modifier.PROTECTED, null); 300 return true; 301 } 302 }); 303 rewriter.rewriteAST(document, declaringCu.getJavaProject().getOptions(true)).apply(document, TextEdit.NONE); 304 result= (BodyDeclaration) rewrite.createStringPlaceholder(document.get(position.getStartPosition(), position.getLength()), ASTNode.TYPE_DECLARATION); 305 } catch (MalformedTreeException exception) { 306 JavaPlugin.log(exception); 307 } catch (BadLocationException exception) { 308 JavaPlugin.log(exception); 309 } 310 return result; 311 } 312 313 protected static SingleVariableDeclaration createPlaceholderForSingleVariableDeclaration(final SingleVariableDeclaration declaration, final ICompilationUnit declaringCu, final ASTRewrite rewrite) throws JavaModelException { 314 return (SingleVariableDeclaration) rewrite.createStringPlaceholder(declaringCu.getBuffer().getText(declaration.getStartPosition(), declaration.getLength()), ASTNode.SINGLE_VARIABLE_DECLARATION); 315 } 316 317 protected static SingleVariableDeclaration createPlaceholderForSingleVariableDeclaration(final SingleVariableDeclaration declaration, final ICompilationUnit declaringCu, final TypeVariableMaplet[] mapping, final ASTRewrite rewrite) throws JavaModelException { 318 SingleVariableDeclaration result= null; 319 try { 320 final IDocument document= new Document(declaringCu.getBuffer().getContents()); 321 final ASTRewrite rewriter= ASTRewrite.create(declaration.getAST()); 322 final ITrackedNodePosition position= rewriter.track(declaration); 323 declaration.accept(new TypeVariableMapper(rewriter, mapping)); 324 rewriter.rewriteAST(document, declaringCu.getJavaProject().getOptions(true)).apply(document, TextEdit.NONE); 325 result= (SingleVariableDeclaration) rewrite.createStringPlaceholder(document.get(position.getStartPosition(), position.getLength()), ASTNode.SINGLE_VARIABLE_DECLARATION); 326 } catch (MalformedTreeException exception) { 327 JavaPlugin.log(exception); 328 } catch (BadLocationException exception) { 329 JavaPlugin.log(exception); 330 } 331 return result; 332 } 333 334 protected static Type createPlaceholderForType(final Type type, final ICompilationUnit declaringCu, final ASTRewrite rewrite) throws JavaModelException { 335 return (Type) rewrite.createStringPlaceholder(declaringCu.getBuffer().getText(type.getStartPosition(), type.getLength()), ASTNode.SIMPLE_TYPE); 336 } 337 338 protected static Type createPlaceholderForType(final Type type, final ICompilationUnit declaringCu, final TypeVariableMaplet[] mapping, final ASTRewrite rewrite) throws JavaModelException { 339 Type result= null; 340 try { 341 final IDocument document= new Document(declaringCu.getBuffer().getContents()); 342 final ASTRewrite rewriter= ASTRewrite.create(type.getAST()); 343 final ITrackedNodePosition position= rewriter.track(type); 344 type.accept(new TypeVariableMapper(rewriter, mapping)); 345 rewriter.rewriteAST(document, declaringCu.getJavaProject().getOptions(true)).apply(document, TextEdit.NONE); 346 result= (Type) rewrite.createStringPlaceholder(document.get(position.getStartPosition(), position.getLength()), ASTNode.SIMPLE_TYPE); 347 } catch (MalformedTreeException exception) { 348 JavaPlugin.log(exception); 349 } catch (BadLocationException exception) { 350 JavaPlugin.log(exception); 351 } 352 return result; 353 } 354 355 protected static BodyDeclaration createPlaceholderForTypeDeclaration(final BodyDeclaration bodyDeclaration, final ICompilationUnit declaringCu, final ASTRewrite rewrite, final boolean removeIndentation) throws JavaModelException { 356 return (BodyDeclaration) rewrite.createStringPlaceholder(getNewText(bodyDeclaration, declaringCu, removeIndentation), ASTNode.TYPE_DECLARATION); 357 } 358 359 protected static BodyDeclaration createPlaceholderForTypeDeclaration(final BodyDeclaration bodyDeclaration, final ICompilationUnit declaringCu, final TypeVariableMaplet[] mapping, final ASTRewrite rewrite, final boolean removeIndentation) throws JavaModelException { 360 BodyDeclaration result= null; 361 try { 362 final IDocument document= new Document(declaringCu.getBuffer().getContents()); 363 final ASTRewrite rewriter= ASTRewrite.create(bodyDeclaration.getAST()); 364 final ITrackedNodePosition position= rewriter.track(bodyDeclaration); 365 bodyDeclaration.accept(new TypeVariableMapper(rewriter, mapping)); 366 rewriter.rewriteAST(document, declaringCu.getJavaProject().getOptions(true)).apply(document, TextEdit.NONE); 367 result= (BodyDeclaration) rewrite.createStringPlaceholder(document.get(position.getStartPosition(), position.getLength()), ASTNode.TYPE_DECLARATION); 368 } catch (MalformedTreeException exception) { 369 JavaPlugin.log(exception); 370 } catch (BadLocationException exception) { 371 JavaPlugin.log(exception); 372 } 373 return result; 374 } 375 376 protected static String createTypeLabel(final IType type) { 377 return JavaModelUtil.getFullyQualifiedName(type); 378 } 379 380 protected static void deleteDeclarationNodes(final CompilationUnitRewrite sourceRewriter, final boolean sameCu, final CompilationUnitRewrite unitRewriter, final List members) throws JavaModelException { 381 final List declarationNodes= getDeclarationNodes(unitRewriter.getRoot(), members); 382 for (final Iterator iterator= declarationNodes.iterator(); iterator.hasNext();) { 383 final ASTNode node= (ASTNode) iterator.next(); 384 final ASTRewrite rewriter= unitRewriter.getASTRewrite(); 385 final ImportRemover remover= unitRewriter.getImportRemover(); 386 if (node instanceof VariableDeclarationFragment) { 387 if (node.getParent() instanceof FieldDeclaration) { 388 final FieldDeclaration declaration= (FieldDeclaration) node.getParent(); 389 if (areAllFragmentsDeleted(declaration, declarationNodes)) { 390 rewriter.remove(declaration, unitRewriter.createGroupDescription(RefactoringCoreMessages.HierarchyRefactoring_remove_member)); 391 if (!sameCu) 392 remover.registerRemovedNode(declaration); 393 } else { 394 rewriter.remove(node, unitRewriter.createGroupDescription(RefactoringCoreMessages.HierarchyRefactoring_remove_member)); 395 if (!sameCu) 396 remover.registerRemovedNode(node); 397 } 398 } 399 } else { 400 rewriter.remove(node, unitRewriter.createGroupDescription(RefactoringCoreMessages.HierarchyRefactoring_remove_member)); 401 if (!sameCu) 402 remover.registerRemovedNode(node); 403 } 404 } 405 } 406 407 protected static List getDeclarationNodes(final CompilationUnit cuNode, final List members) throws JavaModelException { 408 final List result= new ArrayList (members.size()); 409 for (final Iterator iterator= members.iterator(); iterator.hasNext();) { 410 final IMember member= (IMember) iterator.next(); 411 ASTNode node= null; 412 if (member instanceof IField) { 413 if (Flags.isEnum(member.getFlags())) 414 node= ASTNodeSearchUtil.getEnumConstantDeclaration((IField) member, cuNode); 415 else 416 node= ASTNodeSearchUtil.getFieldDeclarationFragmentNode((IField) member, cuNode); 417 } else if (member instanceof IType) 418 node= ASTNodeSearchUtil.getAbstractTypeDeclarationNode((IType) member, cuNode); 419 else if (member instanceof IMethod) 420 node= ASTNodeSearchUtil.getMethodDeclarationNode((IMethod) member, cuNode); 421 if (node != null) 422 result.add(node); 423 } 424 return result; 425 } 426 427 protected static String getNewText(final ASTNode node, final ICompilationUnit declaringCu, final boolean removeIndentation) throws JavaModelException { 428 final String result= declaringCu.getBuffer().getText(node.getStartPosition(), node.getLength()); 429 if (removeIndentation) 430 return getUnindentedText(result, declaringCu); 431 432 return result; 433 } 434 435 protected static String getUnindentedText(final String text, final ICompilationUnit declaringCu) throws JavaModelException { 436 final String [] lines= Strings.convertIntoLines(text); 437 Strings.trimIndentation(lines, declaringCu.getJavaProject(), false); 438 return Strings.concatenate(lines, StubUtility.getLineDelimiterUsed(declaringCu)); 439 } 440 441 protected final Map fCachedMembersReferences= new HashMap (2); 442 443 protected IType[] fCachedReferencedTypes; 444 445 protected TextChangeManager fChangeManager; 446 447 protected IType fDeclaringType; 448 449 protected IMember[] fMembersToMove; 450 451 protected HierarchyRefactoring(final IMember[] members) { 452 Assert.isNotNull(members); 453 fMembersToMove= (IMember[]) SourceReferenceUtil.sortByOffset(members); 454 } 455 456 protected boolean canBeAccessedFrom(final IMember member, final IType target, final ITypeHierarchy hierarchy) throws JavaModelException { 457 Assert.isTrue(!(member instanceof IInitializer)); 458 459 return member.exists(); 460 } 461 462 protected RefactoringStatus checkDeclaringType(final IProgressMonitor monitor) throws JavaModelException { 463 final IType type= getDeclaringType(); 464 if (type.isEnum()) 465 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.HierarchyRefactoring_enum_members); 466 if (type.isAnnotation()) 467 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.HierarchyRefactoring_annotation_members); 468 if (type.isInterface()) 469 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.HierarchyRefactoring_interface_members); 470 if (type.isBinary()) 471 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.HierarchyRefactoring_members_of_binary); 472 if (type.isReadOnly()) 473 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.HierarchyRefactoring_members_of_read_only); 474 return new RefactoringStatus(); 475 } 476 477 protected RefactoringStatus checkIfMembersExist() { 478 RefactoringStatus result= new RefactoringStatus(); 479 IMember member= null; 480 for (int index= 0; index < fMembersToMove.length; index++) { 481 member= fMembersToMove[index]; 482 if (member == null || !member.exists()) 483 result.addFatalError(RefactoringCoreMessages.HierarchyRefactoring_does_not_exist); 484 } 485 return result; 486 } 487 488 protected void clearCaches() { 489 fCachedReferencedTypes= null; 490 } 491 492 protected void copyParameters(final ASTRewrite rewrite, final ICompilationUnit unit, final MethodDeclaration oldMethod, final MethodDeclaration newMethod, final TypeVariableMaplet[] mapping) throws JavaModelException { 493 SingleVariableDeclaration newDeclaration= null; 494 for (int index= 0, size= oldMethod.parameters().size(); index < size; index++) { 495 SingleVariableDeclaration oldDeclaration= (SingleVariableDeclaration) oldMethod.parameters().get(index); 496 if (mapping.length > 0) 497 newDeclaration= createPlaceholderForSingleVariableDeclaration(oldDeclaration, unit, mapping, rewrite); 498 else 499 newDeclaration= createPlaceholderForSingleVariableDeclaration(oldDeclaration, unit, rewrite); 500 newMethod.parameters().add(index, newDeclaration); 501 } 502 } 503 504 protected void copyReturnType(final ASTRewrite rewrite, final ICompilationUnit unit, final MethodDeclaration oldMethod, final MethodDeclaration newMethod, final TypeVariableMaplet[] mapping) throws JavaModelException { 505 Type newReturnType= null; 506 if (mapping.length > 0) 507 newReturnType= createPlaceholderForType(oldMethod.getReturnType2(), unit, mapping, rewrite); 508 else 509 newReturnType= createPlaceholderForType(oldMethod.getReturnType2(), unit, rewrite); 510 newMethod.setReturnType2(newReturnType); 511 } 512 513 public IType getDeclaringType() { 514 if (fDeclaringType != null) 515 return fDeclaringType; 516 fDeclaringType= (IType) WorkingCopyUtil.getOriginal(fMembersToMove[0].getDeclaringType()); 517 return fDeclaringType; 518 } 519 520 public IMember[] getMembersToMove() { 521 return fMembersToMove; 522 } 523 524 protected IType[] getTypesReferencedInMovedMembers(final IProgressMonitor monitor) throws JavaModelException { 525 if (fCachedReferencedTypes == null) { 526 final IType[] types= ReferenceFinderUtil.getTypesReferencedIn(fMembersToMove, monitor); 527 final List result= new ArrayList (types.length); 528 final List members= Arrays.asList(fMembersToMove); 529 for (int index= 0; index < types.length; index++) { 530 if (!members.contains(types[index]) && types[index] != getDeclaringType()) 531 result.add(types[index]); 532 } 533 fCachedReferencedTypes= new IType[result.size()]; 534 result.toArray(fCachedReferencedTypes); 535 } 536 return fCachedReferencedTypes; 537 } 538 539 protected boolean hasNonMovedReferences(final IMember member, final IProgressMonitor monitor, final RefactoringStatus status) throws JavaModelException { 540 if (!fCachedMembersReferences.containsKey(member)) { 541 final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE)); 542 engine.setFiltering(true, true); 543 engine.setStatus(status); 544 engine.setScope(RefactoringScopeFactory.create(member)); 545 engine.searchPattern(new SubProgressMonitor(monitor, 1)); 546 fCachedMembersReferences.put(member, engine.getResults()); 547 } 548 final SearchResultGroup[] groups= (SearchResultGroup[]) fCachedMembersReferences.get(member); 549 if (groups.length == 0) 550 return false; 551 else if (groups.length > 1) 552 return true; 553 final ICompilationUnit unit= groups[0].getCompilationUnit(); 554 if (!getDeclaringType().getCompilationUnit().equals(unit)) 555 return true; 556 final SearchMatch[] matches= groups[0].getSearchResults(); 557 for (int index= 0; index < matches.length; index++) { 558 if (!isMovedReference(matches[index])) 559 return true; 560 } 561 return false; 562 } 563 564 protected boolean isMovedReference(final SearchMatch match) throws JavaModelException { 565 ISourceRange range= null; 566 for (int index= 0; index < fMembersToMove.length; index++) { 567 range= fMembersToMove[index].getSourceRange(); 568 if (range.getOffset() <= match.getOffset() && range.getOffset() + range.getLength() >= match.getOffset()) 569 return true; 570 } 571 return false; 572 } 573 574 protected boolean needsVisibilityAdjustment(final IMember member, final boolean references, final IProgressMonitor monitor, RefactoringStatus status) throws JavaModelException { 575 if (JdtFlags.isPublic(member) || JdtFlags.isProtected(member)) 576 return false; 577 if (!references) 578 return true; 579 return hasNonMovedReferences(member, monitor, status); 580 } 581 } 582 | Popular Tags |