1 11 package org.eclipse.jdt.internal.corext.fix; 12 13 import java.util.ArrayList ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 17 import org.eclipse.text.edits.TextEditGroup; 18 19 import org.eclipse.core.runtime.CoreException; 20 import org.eclipse.core.runtime.NullProgressMonitor; 21 22 import org.eclipse.jdt.core.ICompilationUnit; 23 import org.eclipse.jdt.core.compiler.IProblem; 24 import org.eclipse.jdt.core.dom.AST; 25 import org.eclipse.jdt.core.dom.ASTNode; 26 import org.eclipse.jdt.core.dom.Annotation; 27 import org.eclipse.jdt.core.dom.BodyDeclaration; 28 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 29 import org.eclipse.jdt.core.dom.CompilationUnit; 30 import org.eclipse.jdt.core.dom.Expression; 31 import org.eclipse.jdt.core.dom.FieldDeclaration; 32 import org.eclipse.jdt.core.dom.ITypeBinding; 33 import org.eclipse.jdt.core.dom.MethodDeclaration; 34 import org.eclipse.jdt.core.dom.MethodInvocation; 35 import org.eclipse.jdt.core.dom.Name; 36 import org.eclipse.jdt.core.dom.ParameterizedType; 37 import org.eclipse.jdt.core.dom.QualifiedName; 38 import org.eclipse.jdt.core.dom.SimpleName; 39 import org.eclipse.jdt.core.dom.SimpleType; 40 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 41 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; 42 import org.eclipse.jdt.core.dom.Type; 43 import org.eclipse.jdt.core.dom.TypeDeclaration; 44 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 45 import org.eclipse.jdt.core.dom.VariableDeclarationStatement; 46 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 47 import org.eclipse.jdt.core.dom.rewrite.ListRewrite; 48 49 import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder; 50 import org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsConstraintCreator; 51 import org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsConstraintsSolver; 52 import org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsRefactoring; 53 import org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsTCModel; 54 import org.eclipse.jdt.internal.corext.refactoring.generics.InferTypeArgumentsUpdate; 55 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; 56 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 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 71 public class Java50Fix extends LinkedFix { 72 73 private static final String OVERRIDE= "Override"; private static final String DEPRECATED= "Deprecated"; 76 private static class AnnotationRewriteOperation extends AbstractFixRewriteOperation { 77 private final BodyDeclaration fBodyDeclaration; 78 private final String fAnnotation; 79 80 public AnnotationRewriteOperation(BodyDeclaration bodyDeclaration, String annotation) { 81 fBodyDeclaration= bodyDeclaration; 82 fAnnotation= annotation; 83 } 84 85 88 public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException { 89 AST ast= cuRewrite.getRoot().getAST(); 90 ListRewrite listRewrite= cuRewrite.getASTRewrite().getListRewrite(fBodyDeclaration, fBodyDeclaration.getModifiersProperty()); 91 Annotation newAnnotation= ast.newMarkerAnnotation(); 92 newAnnotation.setTypeName(ast.newSimpleName(fAnnotation)); 93 TextEditGroup group= createTextEditGroup(Messages.format(FixMessages.Java50Fix_AddMissingAnnotation_description, fAnnotation)); 94 textEditGroups.add(group); 95 listRewrite.insertFirst(newAnnotation, group); 96 } 97 } 98 99 private static class AddTypeParametersOperation extends AbstractLinkedFixRewriteOperation { 100 101 private final SimpleType[] fTypes; 102 103 public AddTypeParametersOperation(SimpleType[] types) { 104 fTypes= types; 105 } 106 107 110 public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups, LinkedProposalModel positionGroups) throws CoreException { 111 InferTypeArgumentsTCModel model= new InferTypeArgumentsTCModel(); 112 InferTypeArgumentsConstraintCreator creator= new InferTypeArgumentsConstraintCreator(model, true); 113 114 CompilationUnit root= cuRewrite.getRoot(); 115 root.accept(creator); 116 117 InferTypeArgumentsConstraintsSolver solver= new InferTypeArgumentsConstraintsSolver(model); 118 InferTypeArgumentsUpdate update= solver.solveConstraints(new NullProgressMonitor()); 119 solver= null; 121 ASTNode[] nodes= InferTypeArgumentsRefactoring.inferArguments(fTypes, update, model, cuRewrite); 122 if (nodes.length == 0) 123 return; 124 125 ASTRewrite astRewrite= cuRewrite.getASTRewrite(); 126 for (int i= 0; i < nodes.length; i++) { 127 if (nodes[i] instanceof ParameterizedType) { 128 ParameterizedType type= (ParameterizedType)nodes[0]; 129 List args= (List )type.getStructuralProperty(ParameterizedType.TYPE_ARGUMENTS_PROPERTY); 130 int j= 0; 131 for (Iterator iter= args.iterator(); iter.hasNext();) { 132 LinkedProposalPositionGroup group= new LinkedProposalPositionGroup("G" + i + "_" + j); Type argType= (Type)iter.next(); 134 if (!positionGroups.hasLinkedPositions()) { 135 group.addPosition(astRewrite.track(argType), true); 136 } else { 137 group.addPosition(astRewrite.track(argType), false); 138 } 139 if (argType.isWildcardType()) { 140 group.addProposal("?", null, 10); group.addProposal("Object", null, 10); } 143 positionGroups.addPositionGroup(group); 144 j++; 145 } 146 } 147 } 148 positionGroups.setEndPosition(astRewrite.track(nodes[0])); 149 } 150 } 151 152 public static Java50Fix createAddOverrideAnnotationFix(CompilationUnit compilationUnit, IProblemLocation problem) { 153 if (problem.getProblemId() != IProblem.MissingOverrideAnnotation) 154 return null; 155 156 return createFix(compilationUnit, problem, OVERRIDE, FixMessages.Java50Fix_AddOverride_description); 157 } 158 159 public static Java50Fix createAddDeprectatedAnnotation(CompilationUnit compilationUnit, IProblemLocation problem) { 160 int id= problem.getProblemId(); 161 if (id != IProblem.FieldMissingDeprecatedAnnotation && 162 id != IProblem.MethodMissingDeprecatedAnnotation && 163 id != IProblem.TypeMissingDeprecatedAnnotation) 164 165 return null; 166 167 return createFix(compilationUnit, problem, DEPRECATED, FixMessages.Java50Fix_AddDeprecated_description); 168 } 169 170 private static Java50Fix createFix(CompilationUnit compilationUnit, IProblemLocation problem, String annotation, String label) { 171 ICompilationUnit cu= (ICompilationUnit)compilationUnit.getJavaElement(); 172 if (!JavaModelUtil.is50OrHigher(cu.getJavaProject())) 173 return null; 174 175 ASTNode selectedNode= problem.getCoveringNode(compilationUnit); 176 if (selectedNode == null) 177 return null; 178 179 ASTNode declaringNode= getDeclaringNode(selectedNode); 180 if (!(declaringNode instanceof BodyDeclaration)) 181 return null; 182 183 BodyDeclaration declaration= (BodyDeclaration) declaringNode; 184 185 AnnotationRewriteOperation operation= new AnnotationRewriteOperation(declaration, annotation); 186 187 return new Java50Fix(label, compilationUnit, new IFixRewriteOperation[] {operation}); 188 } 189 190 public static Java50Fix createRawTypeReferenceFix(CompilationUnit compilationUnit, IProblemLocation problem) { 191 List operations= new ArrayList (); 192 SimpleType node= createRawTypeReferenceOperations(compilationUnit, new IProblemLocation[] {problem}, operations); 193 if (operations.size() == 0) 194 return null; 195 196 return new Java50Fix(Messages.format(FixMessages.Java50Fix_AddTypeParameters_description, node.getName()), compilationUnit, (IFixRewriteOperation[])operations.toArray(new IFixRewriteOperation[operations.size()])); 197 } 198 199 public static IFix createCleanUp(CompilationUnit compilationUnit, 200 boolean addOverrideAnnotation, 201 boolean addDeprecatedAnnotation, 202 boolean rawTypeReference) { 203 204 ICompilationUnit cu= (ICompilationUnit)compilationUnit.getJavaElement(); 205 if (!JavaModelUtil.is50OrHigher(cu.getJavaProject())) 206 return null; 207 208 if (!addOverrideAnnotation && !addDeprecatedAnnotation && !rawTypeReference) 209 return null; 210 211 List operations= new ArrayList (); 212 213 IProblem[] problems= compilationUnit.getProblems(); 214 IProblemLocation[] locations= new IProblemLocation[problems.length]; 215 for (int i= 0; i < problems.length; i++) { 216 locations[i]= new ProblemLocation(problems[i]); 217 } 218 219 if (addOverrideAnnotation) 220 createAddOverrideAnnotationOperations(compilationUnit, locations, operations); 221 222 if (addDeprecatedAnnotation) 223 createAddDeprecatedAnnotationOperations(compilationUnit, locations, operations); 224 225 if (rawTypeReference) 226 createRawTypeReferenceOperations(compilationUnit, locations, operations); 227 228 if (operations.size() == 0) 229 return null; 230 231 IFixRewriteOperation[] operationsArray= (IFixRewriteOperation[])operations.toArray(new IFixRewriteOperation[operations.size()]); 232 return new Java50Fix(FixMessages.Java50Fix_add_annotations_change_name, compilationUnit, operationsArray); 233 } 234 235 public static IFix createCleanUp(CompilationUnit compilationUnit, IProblemLocation[] problems, 236 boolean addOverrideAnnotation, 237 boolean addDeprecatedAnnotation, 238 boolean rawTypeReferences) { 239 240 ICompilationUnit cu= (ICompilationUnit)compilationUnit.getJavaElement(); 241 if (!JavaModelUtil.is50OrHigher(cu.getJavaProject())) 242 return null; 243 244 if (!addOverrideAnnotation && !addDeprecatedAnnotation && !rawTypeReferences) 245 return null; 246 247 List operations= new ArrayList (); 248 249 if (addOverrideAnnotation) 250 createAddOverrideAnnotationOperations(compilationUnit, problems, operations); 251 252 if (addDeprecatedAnnotation) 253 createAddDeprecatedAnnotationOperations(compilationUnit, problems, operations); 254 255 if (rawTypeReferences) 256 createRawTypeReferenceOperations(compilationUnit, problems, operations); 257 258 259 if (operations.size() == 0) 260 return null; 261 262 IFixRewriteOperation[] operationsArray= (IFixRewriteOperation[])operations.toArray(new IFixRewriteOperation[operations.size()]); 263 return new Java50Fix(FixMessages.Java50Fix_add_annotations_change_name, compilationUnit, operationsArray); 264 } 265 266 private static void createAddDeprecatedAnnotationOperations(CompilationUnit compilationUnit, IProblemLocation[] locations, List result) { 267 for (int i= 0; i < locations.length; i++) { 268 int id= locations[i].getProblemId(); 269 270 if (id == IProblem.FieldMissingDeprecatedAnnotation || 271 id == IProblem.MethodMissingDeprecatedAnnotation || 272 id == IProblem.TypeMissingDeprecatedAnnotation) { 273 274 IProblemLocation problem= locations[i]; 275 276 ASTNode selectedNode= problem.getCoveringNode(compilationUnit); 277 if (selectedNode != null) { 278 279 ASTNode declaringNode= getDeclaringNode(selectedNode); 280 if (declaringNode instanceof BodyDeclaration) { 281 BodyDeclaration declaration= (BodyDeclaration) declaringNode; 282 AnnotationRewriteOperation operation= new AnnotationRewriteOperation(declaration, DEPRECATED); 283 result.add(operation); 284 } 285 } 286 } 287 } 288 } 289 290 private static void createAddOverrideAnnotationOperations(CompilationUnit compilationUnit, IProblemLocation[] locations, List result) { 291 for (int i= 0; i < locations.length; i++) { 292 293 if (locations[i].getProblemId() == IProblem.MissingOverrideAnnotation) { 294 295 IProblemLocation problem= locations[i]; 296 297 ASTNode selectedNode= problem.getCoveringNode(compilationUnit); 298 if (selectedNode != null) { 299 300 ASTNode declaringNode= getDeclaringNode(selectedNode); 301 if (declaringNode instanceof BodyDeclaration) { 302 BodyDeclaration declaration= (BodyDeclaration) declaringNode; 303 AnnotationRewriteOperation operation= new AnnotationRewriteOperation(declaration, OVERRIDE); 304 result.add(operation); 305 } 306 } 307 } 308 } 309 } 310 311 private static SimpleType createRawTypeReferenceOperations(CompilationUnit compilationUnit, IProblemLocation[] locations, List operations) { 312 List result= new ArrayList (); 313 for (int i= 0; i < locations.length; i++) { 314 IProblemLocation problem= locations[i]; 315 int id= problem.getProblemId(); 316 if (id == IProblem.UnsafeTypeConversion || id == IProblem.RawTypeReference || id == IProblem.UnsafeRawMethodInvocation) { 317 318 ASTNode node= problem.getCoveredNode(compilationUnit); 319 if (node instanceof ClassInstanceCreation) { 320 ASTNode rawReference= (ASTNode)node.getStructuralProperty(ClassInstanceCreation.TYPE_PROPERTY); 321 if (isRawTypeReference(rawReference)) { 322 result.add(rawReference); 323 } 324 } else if (node instanceof SimpleName) { 325 ASTNode rawReference= node.getParent(); 326 if (isRawTypeReference(rawReference)) { 327 result.add(rawReference); 328 } 329 } else if (node instanceof MethodInvocation) { 330 MethodInvocation invocation= (MethodInvocation)node; 331 332 ASTNode rawReference= getRawReference(invocation, compilationUnit); 333 if (rawReference != null) { 334 result.add(rawReference); 335 } 336 } 337 } 338 } 339 340 if (result.size() == 0) 341 return null; 342 343 SimpleType[] types= (SimpleType[])result.toArray(new SimpleType[result.size()]); 344 operations.add(new AddTypeParametersOperation(types)); 345 return types[0]; 346 } 347 348 private static ASTNode getRawReference(MethodInvocation invocation, CompilationUnit compilationUnit) { 349 Name name1= (Name)invocation.getStructuralProperty(MethodInvocation.NAME_PROPERTY); 350 if (name1 instanceof SimpleName) { 351 ASTNode rawReference= getRawReference((SimpleName)name1, compilationUnit); 352 if (rawReference != null) { 353 return rawReference; 354 } 355 } 356 357 Expression expr= (Expression)invocation.getStructuralProperty(MethodInvocation.EXPRESSION_PROPERTY); 358 if (expr instanceof SimpleName) { 359 ASTNode rawReference= getRawReference((SimpleName)expr, compilationUnit); 360 if (rawReference != null) { 361 return rawReference; 362 } 363 } else if (expr instanceof QualifiedName) { 364 Name name= (Name)expr; 365 while (name instanceof QualifiedName) { 366 SimpleName simpleName= (SimpleName)name.getStructuralProperty(QualifiedName.NAME_PROPERTY); 367 ASTNode rawReference= getRawReference(simpleName, compilationUnit); 368 if (rawReference != null) { 369 return rawReference; 370 } 371 name= (Name)name.getStructuralProperty(QualifiedName.QUALIFIER_PROPERTY); 372 } 373 if (name instanceof SimpleName) { 374 ASTNode rawReference= getRawReference((SimpleName)name, compilationUnit); 375 if (rawReference != null) { 376 return rawReference; 377 } 378 } 379 } else if (expr instanceof MethodInvocation) { 380 ASTNode rawReference= getRawReference((MethodInvocation)expr, compilationUnit); 381 if (rawReference != null) { 382 return rawReference; 383 } 384 } 385 return null; 386 } 387 388 private static ASTNode getRawReference(SimpleName name, CompilationUnit compilationUnit) { 389 SimpleName[] names= LinkedNodeFinder.findByNode(compilationUnit, name); 390 for (int j= 0; j < names.length; j++) { 391 if (names[j].getParent() instanceof VariableDeclarationFragment) { 392 VariableDeclarationFragment fragment= (VariableDeclarationFragment)names[j].getParent(); 393 if (fragment.getParent() instanceof VariableDeclarationStatement) { 394 VariableDeclarationStatement statement= (VariableDeclarationStatement)fragment.getParent(); 395 ASTNode result= (ASTNode)statement.getStructuralProperty(VariableDeclarationStatement.TYPE_PROPERTY); 396 if (isRawTypeReference(result)) 397 return result; 398 } else if (fragment.getParent() instanceof FieldDeclaration) { 399 FieldDeclaration declaration= (FieldDeclaration)fragment.getParent(); 400 ASTNode result= (ASTNode)declaration.getStructuralProperty(FieldDeclaration.TYPE_PROPERTY); 401 if (isRawTypeReference(result)) 402 return result; 403 } 404 } else if (names[j].getParent() instanceof SingleVariableDeclaration) { 405 SingleVariableDeclaration declaration= (SingleVariableDeclaration)names[j].getParent(); 406 ASTNode result= (ASTNode)declaration.getStructuralProperty(SingleVariableDeclaration.TYPE_PROPERTY); 407 if (isRawTypeReference(result)) 408 return result; 409 } else if (names[j].getParent() instanceof MethodDeclaration) { 410 MethodDeclaration methodDecl= (MethodDeclaration)names[j].getParent(); 411 ASTNode result= (ASTNode)methodDecl.getStructuralProperty(MethodDeclaration.RETURN_TYPE2_PROPERTY); 412 if (isRawTypeReference(result)) 413 return result; 414 } 415 } 416 return null; 417 } 418 419 private static boolean isRawTypeReference(ASTNode node) { 420 if (!(node instanceof SimpleType)) 421 return false; 422 423 ITypeBinding binding= ((SimpleType)node).resolveBinding().getTypeDeclaration(); 424 ITypeBinding[] parameters= binding.getTypeParameters(); 425 if (parameters.length == 0) 426 return false; 427 428 return true; 429 } 430 431 private static ASTNode getDeclaringNode(ASTNode selectedNode) { 432 ASTNode declaringNode= null; 433 if (selectedNode instanceof MethodDeclaration) { 434 declaringNode= selectedNode; 435 } else if (selectedNode instanceof SimpleName) { 436 StructuralPropertyDescriptor locationInParent= selectedNode.getLocationInParent(); 437 if (locationInParent == MethodDeclaration.NAME_PROPERTY || locationInParent == TypeDeclaration.NAME_PROPERTY) { 438 declaringNode= selectedNode.getParent(); 439 } else if (locationInParent == VariableDeclarationFragment.NAME_PROPERTY) { 440 declaringNode= selectedNode.getParent().getParent(); 441 } 442 } 443 return declaringNode; 444 } 445 446 private Java50Fix(String name, CompilationUnit compilationUnit, IFixRewriteOperation[] fixRewrites) { 447 super(name, compilationUnit, fixRewrites); 448 } 449 450 } 451 | Popular Tags |