KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > fix > Java50Fix


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.corext.fix;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
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 /**
64  * Fix which introduce new language constructs to pre Java50 code.
65  * Requires a compiler level setting of 5.0+
66  * Supported:
67  * Add missing @Override annotation
68  * Add missing @Deprecated annotation
69  * Convert for loop to enhanced for loop
70  */

71 public class Java50Fix extends LinkedFix {
72     
73     private static final String JavaDoc OVERRIDE= "Override"; //$NON-NLS-1$
74
private static final String JavaDoc DEPRECATED= "Deprecated"; //$NON-NLS-1$
75

76     private static class AnnotationRewriteOperation extends AbstractFixRewriteOperation {
77         private final BodyDeclaration fBodyDeclaration;
78         private final String JavaDoc fAnnotation;
79
80         public AnnotationRewriteOperation(BodyDeclaration bodyDeclaration, String JavaDoc annotation) {
81             fBodyDeclaration= bodyDeclaration;
82             fAnnotation= annotation;
83         }
84
85         /* (non-Javadoc)
86          * @see org.eclipse.jdt.internal.corext.fix.AbstractFix.IFixRewriteOperation#rewriteAST(org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite, java.util.List)
87          */

88         public void rewriteAST(CompilationUnitRewrite cuRewrite, List JavaDoc 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         /**
108          * {@inheritDoc}
109          */

110         public void rewriteAST(CompilationUnitRewrite cuRewrite, List JavaDoc 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; //free caches
120

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 JavaDoc args= (List JavaDoc)type.getStructuralProperty(ParameterizedType.TYPE_ARGUMENTS_PROPERTY);
130                     int j= 0;
131                     for (Iterator JavaDoc iter= args.iterator(); iter.hasNext();) {
132                         LinkedProposalPositionGroup group= new LinkedProposalPositionGroup("G" + i + "_" + j); //$NON-NLS-1$ //$NON-NLS-2$
133
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); //$NON-NLS-1$
141
group.addProposal("Object", null, 10); //$NON-NLS-1$
142
}
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 JavaDoc annotation, String JavaDoc 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 JavaDoc operations= new ArrayList JavaDoc();
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 JavaDoc/*<IFixRewriteOperation>*/ operations= new ArrayList JavaDoc();
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 JavaDoc/*<IFixRewriteOperation>*/ operations= new ArrayList JavaDoc();
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 JavaDoc 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 JavaDoc 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 JavaDoc operations) {
312         List JavaDoc/*<SimpleType>*/ result= new ArrayList JavaDoc();
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 JavaDoc name, CompilationUnit compilationUnit, IFixRewriteOperation[] fixRewrites) {
447         super(name, compilationUnit, fixRewrites);
448     }
449     
450 }
451
Popular Tags