1 11 12 package org.eclipse.jdt.internal.corext.refactoring.generics; 13 14 import java.util.ArrayList ; 15 import java.util.Arrays ; 16 import java.util.HashMap ; 17 import java.util.HashSet ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.Map ; 21 import java.util.Set ; 22 import java.util.Map.Entry; 23 24 import org.eclipse.core.runtime.CoreException; 25 import org.eclipse.core.runtime.IProgressMonitor; 26 import org.eclipse.core.runtime.ISafeRunnable; 27 import org.eclipse.core.runtime.IStatus; 28 import org.eclipse.core.runtime.OperationCanceledException; 29 import org.eclipse.core.runtime.SafeRunner; 30 import org.eclipse.core.runtime.Status; 31 import org.eclipse.core.runtime.SubProgressMonitor; 32 33 import org.eclipse.core.resources.IFile; 34 35 import org.eclipse.ltk.core.refactoring.Change; 36 import org.eclipse.ltk.core.refactoring.ChangeDescriptor; 37 import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor; 38 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; 39 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 40 import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments; 41 42 import org.eclipse.jdt.core.BindingKey; 43 import org.eclipse.jdt.core.ICompilationUnit; 44 import org.eclipse.jdt.core.IJavaElement; 45 import org.eclipse.jdt.core.IJavaProject; 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.ASTParser; 50 import org.eclipse.jdt.core.dom.ASTRequestor; 51 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; 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.IBinding; 57 import org.eclipse.jdt.core.dom.Name; 58 import org.eclipse.jdt.core.dom.ParameterizedType; 59 import org.eclipse.jdt.core.dom.ParenthesizedExpression; 60 import org.eclipse.jdt.core.dom.SimpleType; 61 import org.eclipse.jdt.core.dom.Type; 62 import org.eclipse.jdt.core.dom.TypeLiteral; 63 import org.eclipse.jdt.core.refactoring.IJavaRefactorings; 64 65 import org.eclipse.jdt.internal.corext.SourceRange; 66 import org.eclipse.jdt.internal.corext.refactoring.Checks; 67 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments; 68 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptor; 69 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; 70 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 71 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext; 72 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange; 73 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationStateChange; 74 import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring; 75 import org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsUpdate.CuUpdate; 76 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; 77 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType; 78 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.EnumeratedTypeSet; 79 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet; 80 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.CastVariable2; 81 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.CollectionElementVariable2; 82 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ConstraintVariable2; 83 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TypeVariable2; 84 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser; 85 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil; 86 import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager; 87 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 88 import org.eclipse.jdt.internal.corext.util.Messages; 89 90 import org.eclipse.jdt.ui.JavaElementLabels; 91 92 import org.eclipse.jdt.internal.ui.IJavaStatusConstants; 93 import org.eclipse.jdt.internal.ui.JavaPlugin; 94 95 public class InferTypeArgumentsRefactoring extends ScriptableRefactoring { 96 97 private static final String ATTRIBUTE_CLONE= "clone"; private static final String ATTRIBUTE_LEAVE= "leave"; 100 private static final String REWRITTEN= "InferTypeArgumentsRefactoring.rewritten"; 102 private TextChangeManager fChangeManager; 103 private IJavaElement[] fElements; 104 private InferTypeArgumentsTCModel fTCModel; 105 106 private boolean fAssumeCloneReturnsSameType; 107 private boolean fLeaveUnconstrainedRaw; 108 109 113 public InferTypeArgumentsRefactoring(IJavaElement[] elements) { 114 fElements= elements; 115 } 116 117 120 public String getName() { 121 return RefactoringCoreMessages.InferTypeArgumentsRefactoring_name; 122 } 123 124 public void setAssumeCloneReturnsSameType(boolean assume) { 125 fAssumeCloneReturnsSameType= assume; 126 } 127 128 public boolean getAssumeCloneReturnsSameType() { 129 return fAssumeCloneReturnsSameType; 130 } 131 132 public void setLeaveUnconstrainedRaw(boolean raw) { 133 fLeaveUnconstrainedRaw= raw; 134 } 135 136 public boolean getLeaveUnconstrainedRaw() { 137 return fLeaveUnconstrainedRaw; 138 } 139 140 143 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { 144 RefactoringStatus result= check15(); 145 pm.done(); 146 return result; 147 } 148 149 152 public RefactoringStatus checkFinalConditions(final IProgressMonitor pm) throws CoreException, OperationCanceledException { 153 HashMap projectsToElements= getJavaElementsPerProject(fElements); 154 pm.beginTask("", projectsToElements.size() + 2); final RefactoringStatus result= new RefactoringStatus(); 156 try { 157 fTCModel= new InferTypeArgumentsTCModel(); 158 final InferTypeArgumentsConstraintCreator unitCollector= new InferTypeArgumentsConstraintCreator(fTCModel, fAssumeCloneReturnsSameType); 159 160 for (Iterator iter= projectsToElements.entrySet().iterator(); iter.hasNext(); ) { 161 Entry entry= (Entry) iter.next(); 162 IJavaProject project= (IJavaProject) entry.getKey(); 163 List javaElementsList= (List ) entry.getValue(); 164 IJavaElement[] javaElements= (IJavaElement[]) javaElementsList.toArray(new IJavaElement[javaElementsList.size()]); 165 List cus= Arrays.asList(JavaModelUtil.getAllCompilationUnits(javaElements)); 166 167 int batchSize= 150; 168 int batches= ((cus.size()-1) / batchSize) + 1; 169 SubProgressMonitor projectMonitor= new SubProgressMonitor(pm, 1); 170 projectMonitor.beginTask("", batches); projectMonitor.setTaskName(RefactoringCoreMessages.InferTypeArgumentsRefactoring_building); 172 for (int i= 0; i < batches; i++) { 173 List batch= cus.subList(i * batchSize, Math.min(cus.size(), (i + 1) * batchSize)); 174 ICompilationUnit[] batchCus= (ICompilationUnit[]) batch.toArray(new ICompilationUnit[batch.size()]); 175 final SubProgressMonitor batchMonitor= new SubProgressMonitor(projectMonitor, 1); 176 batchMonitor.subTask(RefactoringCoreMessages.InferTypeArgumentsRefactoring_calculating_dependencies); 177 178 ASTParser parser= ASTParser.newParser(AST.JLS3); 179 parser.setProject(project); 180 parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project)); 181 parser.setResolveBindings(true); 182 parser.createASTs(batchCus, new String [0], new ASTRequestor() { 183 public void acceptAST(final ICompilationUnit source, final CompilationUnit ast) { 184 batchMonitor.subTask(source.getElementName()); 185 186 SafeRunner.run(new ISafeRunnable() { 187 public void run() throws Exception { 188 IProblem[] problems= ast.getProblems(); 189 for (int p= 0; p < problems.length; p++) { 190 if (problems[p].isError()) { 191 String cuName= JavaElementLabels.getElementLabel(source, JavaElementLabels.CU_QUALIFIED); 192 String msg= Messages.format(RefactoringCoreMessages.InferTypeArgumentsRefactoring_error_in_cu_skipped, new Object [] {cuName}); 193 result.addError(msg, JavaStatusContext.create(source, new SourceRange(problems[p]))); 194 return; 195 } 196 } 197 ast.accept(unitCollector); 198 } 199 public void handleException(Throwable exception) { 200 String cuName= JavaElementLabels.getElementLabel(source, JavaElementLabels.CU_QUALIFIED); 201 String msg= Messages.format(RefactoringCoreMessages.InferTypeArgumentsRefactoring_internal_error, new Object [] {cuName}); 202 JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IJavaStatusConstants.INTERNAL_ERROR, msg, null)); 203 String msg2= Messages.format(RefactoringCoreMessages.InferTypeArgumentsRefactoring_error_skipped, new Object [] {cuName}); 204 result.addError(msg2, JavaStatusContext.create(source)); 205 } 206 }); 207 208 fTCModel.newCu(); 209 } 210 public void acceptBinding(String bindingKey, IBinding binding) { 211 } 213 }, batchMonitor); 214 } 215 216 projectMonitor.done(); 217 fTCModel.newCu(); 218 } 219 220 226 pm.setTaskName(RefactoringCoreMessages.InferTypeArgumentsRefactoring_solving); 227 InferTypeArgumentsConstraintsSolver solver= new InferTypeArgumentsConstraintsSolver(fTCModel); 228 InferTypeArgumentsUpdate updates= solver.solveConstraints(new SubProgressMonitor(pm, 1)); 229 solver= null; 231 fChangeManager= new TextChangeManager(); 232 rewriteDeclarations(updates, new SubProgressMonitor(pm, 1)); 233 234 IFile[] filesToModify= ResourceUtil.getFiles(fChangeManager.getAllCompilationUnits()); 235 result.merge(Checks.validateModifiesFiles(filesToModify, getValidationContext())); 236 return result; 237 } finally { 238 pm.done(); 239 clearGlobalState(); 240 } 241 } 242 243 private void clearGlobalState() { 244 TypeSet.resetCount(); 245 EnumeratedTypeSet.resetCount(); 246 fTCModel= null; 247 } 248 249 private HashMap getJavaElementsPerProject(IJavaElement[] elements) { 250 HashMap result= new HashMap (); 251 for (int i= 0; i < fElements.length; i++) { 252 IJavaElement element= fElements[i]; 253 IJavaProject javaProject= element.getJavaProject(); 254 ArrayList javaElements= (ArrayList ) result.get(javaProject); 255 if (javaElements == null) { 256 javaElements= new ArrayList (); 257 result.put(javaProject, javaElements); 258 } 259 javaElements.add(element); 260 } 261 return result; 262 } 263 264 private RefactoringStatus check15() throws CoreException { 265 RefactoringStatus result= new RefactoringStatus(); 266 HashSet checkedProjects= new HashSet (); 267 268 for (int i= 0; i < fElements.length; i++) { 269 IJavaProject javaProject= fElements[i].getJavaProject(); 270 if (! checkedProjects.contains(javaProject)) { 271 if (! JavaModelUtil.is50OrHigher(javaProject)) { 272 String message= Messages.format(RefactoringCoreMessages.InferTypeArgumentsRefactoring_not50, javaProject.getElementName()); 273 result.addFatalError(message); 274 } else if (! JavaModelUtil.is50OrHigherJRE(javaProject)) { 275 String message= Messages.format(RefactoringCoreMessages.InferTypeArgumentsRefactoring_not50Library, javaProject.getElementName()); 276 result.addFatalError(message); 277 } 278 checkedProjects.add(javaProject); 279 } 280 } 281 return result; 282 } 283 284 private void rewriteDeclarations(InferTypeArgumentsUpdate update, IProgressMonitor pm) throws CoreException { 285 HashMap updates= update.getUpdates(); 286 287 Set entrySet= updates.entrySet(); 288 pm.beginTask("", entrySet.size()); pm.setTaskName(RefactoringCoreMessages.InferTypeArgumentsRefactoring_creatingChanges); 290 for (Iterator iter= entrySet.iterator(); iter.hasNext();) { 291 if (pm.isCanceled()) 292 throw new OperationCanceledException(); 293 294 Map.Entry entry= (Map.Entry ) iter.next(); 295 ICompilationUnit cu= (ICompilationUnit) entry.getKey(); 296 pm.worked(1); 297 pm.subTask(cu.getElementName()); 298 299 CompilationUnitRewrite rewrite= new CompilationUnitRewrite(cu); 300 rewrite.setResolveBindings(false); 301 CuUpdate cuUpdate= (CuUpdate) entry.getValue(); 302 303 for (Iterator cvIter= cuUpdate.getDeclarations().iterator(); cvIter.hasNext();) { 304 ConstraintVariable2 cv= (ConstraintVariable2) cvIter.next(); 305 rewriteConstraintVariable(cv, rewrite, fTCModel, fLeaveUnconstrainedRaw, null); 306 } 307 308 for (Iterator castsIter= cuUpdate.getCastsToRemove().iterator(); castsIter.hasNext();) { 309 CastVariable2 castCv= (CastVariable2) castsIter.next(); 310 rewriteCastVariable(castCv, rewrite, fTCModel); 311 } 312 313 CompilationUnitChange change= rewrite.createChange(); 314 if (change != null) { 315 fChangeManager.manage(cu, change); 316 } 317 } 318 319 } 320 321 public static ParameterizedType[] inferArguments(SimpleType[] types, InferTypeArgumentsUpdate update, InferTypeArgumentsTCModel model, CompilationUnitRewrite rewrite) { 322 for (int i= 0; i < types.length; i++) { 323 types[i].setProperty(REWRITTEN, null); 324 } 325 List result= new ArrayList (); 326 HashMap updates= update.getUpdates(); 327 Set entrySet= updates.entrySet(); 328 for (Iterator iter= entrySet.iterator(); iter.hasNext();) { 329 330 Map.Entry entry= (Map.Entry ) iter.next(); 331 332 rewrite.setResolveBindings(false); 333 CuUpdate cuUpdate= (CuUpdate) entry.getValue(); 334 335 for (Iterator cvIter= cuUpdate.getDeclarations().iterator(); cvIter.hasNext();) { 336 ConstraintVariable2 cv= (ConstraintVariable2) cvIter.next(); 337 ParameterizedType newNode= rewriteConstraintVariable(cv, rewrite, model, false, types); 338 if (newNode != null) 339 result.add(newNode); 340 } 341 } 342 return (ParameterizedType[])result.toArray(new ParameterizedType[result.size()]); 343 } 344 345 private static ParameterizedType rewriteConstraintVariable(ConstraintVariable2 cv, CompilationUnitRewrite rewrite, InferTypeArgumentsTCModel tCModel, boolean leaveUnconstraindRaw, SimpleType[] types) { 346 if (cv instanceof CollectionElementVariable2) { 347 ConstraintVariable2 parentElement= ((CollectionElementVariable2) cv).getParentConstraintVariable(); 348 if (parentElement instanceof TypeVariable2) { 349 TypeVariable2 typeCv= (TypeVariable2) parentElement; 350 return rewriteTypeVariable(typeCv, rewrite, tCModel, leaveUnconstraindRaw, types); 351 } else { 352 } 354 } 355 return null; 356 } 357 358 private static ParameterizedType rewriteTypeVariable(TypeVariable2 typeCv, CompilationUnitRewrite rewrite, InferTypeArgumentsTCModel tCModel, boolean leaveUnconstraindRaw, SimpleType[] types) { 359 ASTNode node= typeCv.getRange().getNode(rewrite.getRoot()); 360 if (node instanceof Name && node.getParent() instanceof Type) { 361 Type originalType= (Type) node.getParent(); 362 363 if (types != null && !has(types, originalType)) 364 return null; 365 366 Object rewritten= originalType.getProperty(REWRITTEN); 368 if (rewritten == REWRITTEN) 369 return null; 370 originalType.setProperty(REWRITTEN, REWRITTEN); 371 372 ArrayList typeArgumentCvs= getTypeArgumentCvs(typeCv, tCModel); 373 Type[] typeArguments= getTypeArguments(originalType, typeArgumentCvs, rewrite, tCModel, leaveUnconstraindRaw); 374 if (typeArguments == null) 375 return null; 376 377 Type movingType= (Type) rewrite.getASTRewrite().createMoveTarget(originalType); 378 ParameterizedType newType= rewrite.getAST().newParameterizedType(movingType); 379 380 for (int i= 0; i < typeArguments.length; i++) { 381 newType.typeArguments().add(typeArguments[i]); 382 } 383 384 rewrite.getASTRewrite().replace(originalType, newType, rewrite.createGroupDescription(RefactoringCoreMessages.InferTypeArgumentsRefactoring_addTypeArguments)); 385 return newType; 386 } else { return null; 388 } 389 } 390 391 private static boolean has(SimpleType[] types, Type originalType) { 392 for (int i= 0; i < types.length; i++) { 393 if (types[i] == originalType) 394 return true; 395 } 396 return false; 397 } 398 399 402 private static Type[] getTypeArguments(Type baseType, ArrayList typeArgumentCvs, CompilationUnitRewrite rewrite, InferTypeArgumentsTCModel tCModel, boolean leaveUnconstraindRaw) { 403 if (typeArgumentCvs.size() == 0) 404 return null; 405 406 Type[] typeArguments= new Type[typeArgumentCvs.size()]; 407 for (int i= 0; i < typeArgumentCvs.size(); i++) { 408 CollectionElementVariable2 elementCv= (CollectionElementVariable2) typeArgumentCvs.get(i); 409 Type typeArgument; 410 TType chosenType= InferTypeArgumentsConstraintsSolver.getChosenType(elementCv); 411 if (chosenType != null) { 412 if (chosenType.isWildcardType() && ! unboundedWildcardAllowed(baseType)) 413 return null; if (chosenType.isParameterizedType()) chosenType= chosenType.getTypeDeclaration(); 416 BindingKey bindingKey= new BindingKey(chosenType.getBindingKey()); 417 typeArgument= rewrite.getImportRewrite().addImportFromSignature(bindingKey.toSignature(), rewrite.getAST()); 418 ArrayList nestedTypeArgumentCvs= getTypeArgumentCvs(elementCv, tCModel); 419 Type[] nestedTypeArguments= getTypeArguments(typeArgument, nestedTypeArgumentCvs, rewrite, tCModel, leaveUnconstraindRaw); if (nestedTypeArguments != null) { 421 ParameterizedType parameterizedType= rewrite.getAST().newParameterizedType(typeArgument); 422 for (int j= 0; j < nestedTypeArguments.length; j++) 423 parameterizedType.typeArguments().add(nestedTypeArguments[j]); 424 typeArgument= parameterizedType; 425 } 426 427 } else { if (leaveUnconstraindRaw) { 429 return null; 431 } else { 432 if (unboundedWildcardAllowed(baseType)) { 433 typeArgument= rewrite.getAST().newWildcardType(); 434 } else { 435 String object= rewrite.getImportRewrite().addImport("java.lang.Object"); typeArgument= (Type) rewrite.getASTRewrite().createStringPlaceholder(object, ASTNode.SIMPLE_TYPE); 437 } 438 } 439 } 451 typeArguments[i]= typeArgument; 452 } 453 return typeArguments; 454 } 455 456 private static ArrayList getTypeArgumentCvs(ConstraintVariable2 baseCv, InferTypeArgumentsTCModel tCModel) { 457 Map elementCvs= tCModel.getElementVariables(baseCv); 458 ArrayList typeArgumentCvs= new ArrayList (); 459 for (Iterator iter= elementCvs.values().iterator(); iter.hasNext();) { 460 CollectionElementVariable2 elementCv= (CollectionElementVariable2) iter.next(); 461 int index= elementCv.getDeclarationTypeVariableIndex(); 462 if (index != CollectionElementVariable2.NOT_DECLARED_TYPE_VARIABLE_INDEX) { 463 while (index >= typeArgumentCvs.size()) 464 typeArgumentCvs.add(null); typeArgumentCvs.set(index, elementCv); 466 } 467 } 468 return typeArgumentCvs; 469 } 470 471 private static boolean unboundedWildcardAllowed(Type originalType) { 472 ASTNode parent= originalType.getParent(); 473 while (parent instanceof Type) 474 parent= parent.getParent(); 475 476 if (parent instanceof ClassInstanceCreation) { 477 return false; 478 } else if (parent instanceof AbstractTypeDeclaration) { 479 return false; 480 } else if (parent instanceof TypeLiteral) { 481 return false; 482 } 483 return true; 484 } 485 486 private static ASTNode rewriteCastVariable(CastVariable2 castCv, CompilationUnitRewrite rewrite, InferTypeArgumentsTCModel tCModel) { ASTNode node= castCv.getRange().getNode(rewrite.getRoot()); 488 489 ConstraintVariable2 expressionVariable= castCv.getExpressionVariable(); 490 ConstraintVariable2 methodReceiverCv= tCModel.getMethodReceiverCv(expressionVariable); 491 if (methodReceiverCv != null) { 492 TType chosenReceiverType= InferTypeArgumentsConstraintsSolver.getChosenType(methodReceiverCv); 493 if (chosenReceiverType == null) 494 return null; 495 else if (! InferTypeArgumentsTCModel.isAGenericType(chosenReceiverType)) 496 return null; 497 else if (hasUnboundElement(methodReceiverCv, tCModel)) 498 return null; 499 } 500 501 CastExpression castExpression= (CastExpression) node; 502 Expression expression= castExpression.getExpression(); 503 ASTNode nodeToReplace; 504 if (castExpression.getParent() instanceof ParenthesizedExpression) 505 nodeToReplace= castExpression.getParent(); 506 else 507 nodeToReplace= castExpression; 508 509 Expression newExpression= (Expression) rewrite.getASTRewrite().createMoveTarget(expression); 510 rewrite.getASTRewrite().replace(nodeToReplace, newExpression, rewrite.createGroupDescription(RefactoringCoreMessages.InferTypeArgumentsRefactoring_removeCast)); 511 rewrite.getImportRemover().registerRemovedNode(nodeToReplace); 512 return newExpression; 513 } 514 515 private static boolean hasUnboundElement(ConstraintVariable2 methodReceiverCv, InferTypeArgumentsTCModel tCModel) { 516 ArrayList typeArgumentCvs= getTypeArgumentCvs(methodReceiverCv, tCModel); 517 for (Iterator iter= typeArgumentCvs.iterator(); iter.hasNext();) { 518 CollectionElementVariable2 elementCv= (CollectionElementVariable2) iter.next(); 519 TType chosenElementType= InferTypeArgumentsConstraintsSolver.getChosenType(elementCv); 520 if (chosenElementType == null) 521 return true; 522 } 523 return false; 524 } 525 526 529 public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { 530 pm.beginTask("", 1); try { 532 DynamicValidationStateChange result= new DynamicValidationStateChange(RefactoringCoreMessages.InferTypeArgumentsRefactoring_name, fChangeManager.getAllChanges()) { 533 534 public final ChangeDescriptor getDescriptor() { 535 final Map arguments= new HashMap (); 536 final IJavaProject project= getSingleProject(); 537 final String description= RefactoringCoreMessages.InferTypeArgumentsRefactoring_descriptor_description; 538 final String header= project != null ? Messages.format(RefactoringCoreMessages.InferTypeArgumentsRefactoring_descriptor_description_project, project.getElementName()) : RefactoringCoreMessages.InferTypeArgumentsRefactoring_descriptor_description; 539 final String name= project != null ? project.getElementName() : null; 540 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(name, this, header); 541 final String [] settings= new String [fElements.length]; 542 for (int index= 0; index < settings.length; index++) 543 settings[index]= JavaElementLabels.getTextLabel(fElements[index], JavaElementLabels.ALL_FULLY_QUALIFIED); 544 comment.addSetting(JDTRefactoringDescriptorComment.createCompositeSetting(RefactoringCoreMessages.InferTypeArgumentsRefactoring_original_elements, settings)); 545 if (fAssumeCloneReturnsSameType) 546 comment.addSetting(RefactoringCoreMessages.InferTypeArgumentsRefactoring_assume_clone); 547 if (fLeaveUnconstrainedRaw) 548 comment.addSetting(RefactoringCoreMessages.InferTypeArgumentsRefactoring_leave_unconstrained); 549 final JDTRefactoringDescriptor descriptor= new JDTRefactoringDescriptor(IJavaRefactorings.INFER_TYPE_ARGUMENTS, name, description, comment.asString(), arguments, RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE); 550 for (int index= 0; index < fElements.length; index++) 551 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (index + 1), descriptor.elementToHandle(fElements[index])); 552 arguments.put(ATTRIBUTE_CLONE, Boolean.valueOf(fAssumeCloneReturnsSameType).toString()); 553 arguments.put(ATTRIBUTE_LEAVE, Boolean.valueOf(fLeaveUnconstrainedRaw).toString()); 554 return new RefactoringChangeDescriptor(descriptor); 555 } 556 }; 557 return result; 558 } finally { 559 pm.done(); 560 } 561 } 562 563 private IJavaProject getSingleProject() { 564 IJavaProject first= null; 565 for (int index= 0; index < fElements.length; index++) { 566 final IJavaProject project= fElements[index].getJavaProject(); 567 if (project != null) { 568 if (first == null) 569 first= project; 570 else if (!project.equals(first)) 571 return null; 572 } 573 } 574 return first; 575 } 576 577 public RefactoringStatus initialize(final RefactoringArguments arguments) { 578 if (arguments instanceof JavaRefactoringArguments) { 579 final JavaRefactoringArguments generic= (JavaRefactoringArguments) arguments; 580 final String clone= generic.getAttribute(ATTRIBUTE_CLONE); 581 if (clone != null) { 582 fAssumeCloneReturnsSameType= Boolean.valueOf(clone).booleanValue(); 583 } else 584 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_CLONE)); 585 final String leave= generic.getAttribute(ATTRIBUTE_LEAVE); 586 if (leave != null) { 587 fLeaveUnconstrainedRaw= Boolean.valueOf(leave).booleanValue(); 588 } else 589 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_LEAVE)); 590 int count= 1; 591 final List elements= new ArrayList (); 592 String handle= null; 593 String attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + count; 594 final RefactoringStatus status= new RefactoringStatus(); 595 while ((handle= generic.getAttribute(attribute)) != null) { 596 final IJavaElement element= JDTRefactoringDescriptor.handleToElement(generic.getProject(), handle, false); 597 if (element == null || !element.exists()) 598 return createInputFatalStatus(element, IJavaRefactorings.INFER_TYPE_ARGUMENTS); 599 else 600 elements.add(element); 601 count++; 602 attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + count; 603 } 604 fElements= (IJavaElement[]) elements.toArray(new IJavaElement[elements.size()]); 605 if (elements.isEmpty()) 606 return createInputFatalStatus(null, IJavaRefactorings.INFER_TYPE_ARGUMENTS); 607 if (!status.isOK()) 608 return status; 609 } else 610 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments); 611 return new RefactoringStatus(); 612 } 613 } 614 | Popular Tags |