KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > dom > ASTNodes


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  * Dmitry Stalnov (dstalnov@fusionone.com) - contributed fix for
11  * bug "inline method - doesn't handle implicit cast" (see
12  * https://bugs.eclipse.org/bugs/show_bug.cgi?id=24941).
13  * Dmitry Stalnov (dstalnov@fusionone.com) - contributed fix for
14  * bug Encapsulate field can fail when two variables in one variable declaration (see
15  * https://bugs.eclipse.org/bugs/show_bug.cgi?id=51540).
16  *******************************************************************************/

17 package org.eclipse.jdt.internal.corext.dom;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.eclipse.text.edits.TextEdit;
24
25 import org.eclipse.core.runtime.Assert;
26
27 import org.eclipse.jdt.core.Flags;
28 import org.eclipse.jdt.core.IField;
29 import org.eclipse.jdt.core.IJavaElement;
30 import org.eclipse.jdt.core.IMember;
31 import org.eclipse.jdt.core.ISourceReference;
32 import org.eclipse.jdt.core.IType;
33 import org.eclipse.jdt.core.JavaModelException;
34 import org.eclipse.jdt.core.compiler.IProblem;
35 import org.eclipse.jdt.core.dom.ASTNode;
36 import org.eclipse.jdt.core.dom.ASTVisitor;
37 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
38 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
39 import org.eclipse.jdt.core.dom.ArrayType;
40 import org.eclipse.jdt.core.dom.Assignment;
41 import org.eclipse.jdt.core.dom.BodyDeclaration;
42 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
43 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
44 import org.eclipse.jdt.core.dom.CompilationUnit;
45 import org.eclipse.jdt.core.dom.DoStatement;
46 import org.eclipse.jdt.core.dom.EnhancedForStatement;
47 import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
48 import org.eclipse.jdt.core.dom.Expression;
49 import org.eclipse.jdt.core.dom.FieldDeclaration;
50 import org.eclipse.jdt.core.dom.ForStatement;
51 import org.eclipse.jdt.core.dom.IBinding;
52 import org.eclipse.jdt.core.dom.IMethodBinding;
53 import org.eclipse.jdt.core.dom.ITypeBinding;
54 import org.eclipse.jdt.core.dom.IVariableBinding;
55 import org.eclipse.jdt.core.dom.IfStatement;
56 import org.eclipse.jdt.core.dom.InfixExpression;
57 import org.eclipse.jdt.core.dom.Message;
58 import org.eclipse.jdt.core.dom.MethodDeclaration;
59 import org.eclipse.jdt.core.dom.MethodInvocation;
60 import org.eclipse.jdt.core.dom.Modifier;
61 import org.eclipse.jdt.core.dom.Name;
62 import org.eclipse.jdt.core.dom.ParameterizedType;
63 import org.eclipse.jdt.core.dom.PrimitiveType;
64 import org.eclipse.jdt.core.dom.QualifiedName;
65 import org.eclipse.jdt.core.dom.QualifiedType;
66 import org.eclipse.jdt.core.dom.ReturnStatement;
67 import org.eclipse.jdt.core.dom.SimpleName;
68 import org.eclipse.jdt.core.dom.SimpleType;
69 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
70 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
71 import org.eclipse.jdt.core.dom.Type;
72 import org.eclipse.jdt.core.dom.VariableDeclaration;
73 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
74 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
75 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
76 import org.eclipse.jdt.core.dom.WhileStatement;
77
78 import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
79
80 import org.eclipse.jdt.internal.ui.JavaPlugin;
81 import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache;
82
83 public class ASTNodes {
84
85     public static final int NODE_ONLY= 0;
86     public static final int INCLUDE_FIRST_PARENT= 1;
87     public static final int INCLUDE_ALL_PARENTS= 2;
88     
89     public static final int WARNING= 1 << 0;
90     public static final int ERROR= 1 << 1;
91     public static final int PROBLEMS= WARNING | ERROR;
92
93     private static final Message[] EMPTY_MESSAGES= new Message[0];
94     private static final IProblem[] EMPTY_PROBLEMS= new IProblem[0];
95     
96     private static final int CLEAR_VISIBILITY= ~(Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE);
97     
98     
99     private ASTNodes() {
100         // no instance;
101
}
102
103     public static String JavaDoc asString(ASTNode node) {
104         ASTFlattener flattener= new ASTFlattener();
105         node.accept(flattener);
106         return flattener.getResult();
107     }
108         
109     public static String JavaDoc asFormattedString(ASTNode node, int indent, String JavaDoc lineDelim, Map JavaDoc options) {
110         String JavaDoc unformatted= asString(node);
111         TextEdit edit= CodeFormatterUtil.format2(node, unformatted, indent, lineDelim, options);
112         if (edit != null) {
113             return CodeFormatterUtil.evaluateFormatterEdit(unformatted, edit, null);
114         }
115         return unformatted; // unknown node
116
}
117
118     /**
119      * Returns the list that contains the given ASTNode. If the node
120      * isn't part of any list, <code>null</code> is returned.
121      *
122      * @param node the node in question
123      * @return the list that contains the node or <code>null</code>
124      */

125     public static List JavaDoc getContainingList(ASTNode node) {
126         StructuralPropertyDescriptor locationInParent= node.getLocationInParent();
127         if (locationInParent != null && locationInParent.isChildListProperty()) {
128             return (List JavaDoc) node.getParent().getStructuralProperty(locationInParent);
129         }
130         return null;
131     }
132     
133     /**
134      * Returns a list of the direct children of a node. The siblings are ordered by start offset.
135      * @param node the node to get the children for
136      * @return the children
137      */

138     public static List JavaDoc getChildren(ASTNode node) {
139         ChildrenCollector visitor= new ChildrenCollector();
140         node.accept(visitor);
141         return visitor.result;
142     }
143     
144     private static class ChildrenCollector extends GenericVisitor {
145         public List JavaDoc result;
146
147         public ChildrenCollector() {
148             super(true);
149             result= null;
150         }
151         protected boolean visitNode(ASTNode node) {
152             if (result == null) { // first visitNode: on the node's parent: do nothing, return true
153
result= new ArrayList JavaDoc();
154                 return true;
155             }
156             result.add(node);
157             return false;
158         }
159     }
160     
161     /**
162      * Returns true if this is an existing node, i.e. it was created as part of
163      * a parsing process of a source code file. Returns false if this is a newly
164      * created node which has not yet been given a source position.
165      *
166      * @param node the node to be tested.
167      * @return true if this is an existing node, false if not.
168      */

169     public static boolean isExistingNode(ASTNode node) {
170         return node.getStartPosition() != -1;
171     }
172     
173     /**
174      * Returns the element type. This is a convenience method that returns its
175      * argument if it is a simple type and the element type if the parameter is an array type.
176      * @param type The type to get the element type from.
177      * @return The element type of the type or the type itself.
178      */

179     public static Type getElementType(Type type) {
180         if (! type.isArrayType())
181             return type;
182         return ((ArrayType)type).getElementType();
183     }
184         
185     public static ASTNode findDeclaration(IBinding binding, ASTNode root) {
186         root= root.getRoot();
187         if (root instanceof CompilationUnit) {
188             return ((CompilationUnit)root).findDeclaringNode(binding);
189         }
190         return null;
191     }
192     
193     public static VariableDeclaration findVariableDeclaration(IVariableBinding binding, ASTNode root) {
194         if (binding.isField())
195             return null;
196         ASTNode result= findDeclaration(binding, root);
197         if (result instanceof VariableDeclaration)
198                 return (VariableDeclaration)result;
199                 
200         return null;
201     }
202     
203     /**
204      * Returns the type node for the given declaration.
205      * @param declaration the declaration
206      * @return the type node
207      */

208     public static Type getType(VariableDeclaration declaration) {
209         if (declaration instanceof SingleVariableDeclaration) {
210             return ((SingleVariableDeclaration)declaration).getType();
211         } else if (declaration instanceof VariableDeclarationFragment) {
212             ASTNode parent= ((VariableDeclarationFragment)declaration).getParent();
213             if (parent instanceof VariableDeclarationExpression)
214                 return ((VariableDeclarationExpression)parent).getType();
215             else if (parent instanceof VariableDeclarationStatement)
216                 return ((VariableDeclarationStatement)parent).getType();
217             else if (parent instanceof FieldDeclaration)
218                 return ((FieldDeclaration)parent).getType();
219         }
220         Assert.isTrue(false, "Unknown VariableDeclaration"); //$NON-NLS-1$
221
return null;
222     }
223         
224     public static int getDimensions(VariableDeclaration declaration) {
225         int dim= declaration.getExtraDimensions();
226         Type type= getType(declaration);
227         if (type instanceof ArrayType) {
228             dim += ((ArrayType) type).getDimensions();
229         }
230         return dim;
231     }
232         
233     public static List JavaDoc getModifiers(VariableDeclaration declaration) {
234         Assert.isNotNull(declaration);
235         if (declaration instanceof SingleVariableDeclaration) {
236             return ((SingleVariableDeclaration)declaration).modifiers();
237         } else if (declaration instanceof VariableDeclarationFragment) {
238             ASTNode parent= declaration.getParent();
239             if (parent instanceof VariableDeclarationExpression)
240                 return ((VariableDeclarationExpression)parent).modifiers();
241             else if (parent instanceof VariableDeclarationStatement)
242                 return ((VariableDeclarationStatement)parent).modifiers();
243         }
244         return new ArrayList JavaDoc(0);
245     }
246     
247     public static boolean isSingleDeclaration(VariableDeclaration declaration) {
248         Assert.isNotNull(declaration);
249         if (declaration instanceof SingleVariableDeclaration) {
250             return true;
251         } else if (declaration instanceof VariableDeclarationFragment) {
252             ASTNode parent= declaration.getParent();
253             if (parent instanceof VariableDeclarationExpression)
254                 return ((VariableDeclarationExpression)parent).fragments().size() == 1;
255             else if (parent instanceof VariableDeclarationStatement)
256                 return ((VariableDeclarationStatement)parent).fragments().size() == 1;
257         }
258         return false;
259     }
260     
261     public static boolean isLiteral(Expression expression) {
262         int type= expression.getNodeType();
263         return type == ASTNode.BOOLEAN_LITERAL || type == ASTNode.CHARACTER_LITERAL || type == ASTNode.NULL_LITERAL ||
264             type == ASTNode.NUMBER_LITERAL || type == ASTNode.STRING_LITERAL || type == ASTNode.TYPE_LITERAL;
265     }
266     
267     public static boolean isLabel(SimpleName name) {
268         int parentType= name.getParent().getNodeType();
269         return parentType == ASTNode.LABELED_STATEMENT ||
270             parentType == ASTNode.BREAK_STATEMENT || parentType != ASTNode.CONTINUE_STATEMENT;
271     }
272     
273     public static boolean isStatic(BodyDeclaration declaration) {
274         return Modifier.isStatic(declaration.getModifiers());
275     }
276     
277     public static List JavaDoc getBodyDeclarations(ASTNode node) {
278         if (node instanceof AbstractTypeDeclaration) {
279             return ((AbstractTypeDeclaration)node).bodyDeclarations();
280         } else if (node instanceof AnonymousClassDeclaration) {
281             return ((AnonymousClassDeclaration)node).bodyDeclarations();
282         }
283         // should not happen.
284
Assert.isTrue(false);
285         return null;
286     }
287     
288     public static ChildListPropertyDescriptor getBodyDeclarationsProperty(ASTNode node) {
289         if (node instanceof AbstractTypeDeclaration) {
290             return ((AbstractTypeDeclaration)node).getBodyDeclarationsProperty();
291         } else if (node instanceof AnonymousClassDeclaration) {
292             return AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;
293         }
294         // should not happen.
295
Assert.isTrue(false);
296         return null;
297     }
298     
299     public static String JavaDoc getTypeName(Type type) {
300         final StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
301         ASTVisitor visitor= new ASTVisitor() {
302             public boolean visit(PrimitiveType node) {
303                 buffer.append(node.getPrimitiveTypeCode().toString());
304                 return false;
305             }
306             public boolean visit(SimpleName node) {
307                 buffer.append(node.getIdentifier());
308                 return false;
309             }
310             public boolean visit(QualifiedName node) {
311                 buffer.append(node.getName().getIdentifier());
312                 return false;
313             }
314             public void endVisit(ArrayType node) {
315                 buffer.append("[]"); //$NON-NLS-1$
316
}
317         };
318         type.accept(visitor);
319         return buffer.toString();
320     }
321     
322     public static InfixExpression.Operator convertToInfixOperator(Assignment.Operator operator) {
323         if (operator.equals(Assignment.Operator.PLUS_ASSIGN))
324             return InfixExpression.Operator.PLUS;
325             
326         if (operator.equals(Assignment.Operator.MINUS_ASSIGN))
327             return InfixExpression.Operator.MINUS;
328             
329         if (operator.equals(Assignment.Operator.TIMES_ASSIGN))
330             return InfixExpression.Operator.TIMES;
331             
332         if (operator.equals(Assignment.Operator.DIVIDE_ASSIGN))
333             return InfixExpression.Operator.DIVIDE;
334             
335         if (operator.equals(Assignment.Operator.BIT_AND_ASSIGN))
336             return InfixExpression.Operator.AND;
337             
338         if (operator.equals(Assignment.Operator.BIT_OR_ASSIGN))
339             return InfixExpression.Operator.OR;
340             
341         if (operator.equals(Assignment.Operator.BIT_XOR_ASSIGN))
342             return InfixExpression.Operator.XOR;
343             
344         if (operator.equals(Assignment.Operator.REMAINDER_ASSIGN))
345             return InfixExpression.Operator.REMAINDER;
346             
347         if (operator.equals(Assignment.Operator.LEFT_SHIFT_ASSIGN))
348             return InfixExpression.Operator.LEFT_SHIFT;
349             
350         if (operator.equals(Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN))
351             return InfixExpression.Operator.RIGHT_SHIFT_SIGNED;
352             
353         if (operator.equals(Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN))
354             return InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED;
355
356         Assert.isTrue(false, "Cannot convert assignment operator"); //$NON-NLS-1$
357
return null;
358     }
359     
360     /**
361      * Returns true if a node at a given location is a body of a control statement. Such body nodes are
362      * interesting as when replacing them, it has to be evaluates if a Block is needed instead.
363      * E.g. <code> if (x) do(); -> if (x) { do1(); do2() } </code>
364      *
365      * @param locationInParent Location of the body node
366      * @return Returns true if the location is a body node location of a control statement.
367      */

368     public static boolean isControlStatementBody(StructuralPropertyDescriptor locationInParent) {
369         return locationInParent == IfStatement.THEN_STATEMENT_PROPERTY
370             || locationInParent == IfStatement.ELSE_STATEMENT_PROPERTY
371             || locationInParent == ForStatement.BODY_PROPERTY
372             || locationInParent == EnhancedForStatement.BODY_PROPERTY
373             || locationInParent == WhileStatement.BODY_PROPERTY
374             || locationInParent == DoStatement.BODY_PROPERTY;
375     }
376     
377     public static boolean needsParentheses(Expression expression) {
378         int type= expression.getNodeType();
379         return type == ASTNode.INFIX_EXPRESSION || type == ASTNode.CONDITIONAL_EXPRESSION ||
380             type == ASTNode.PREFIX_EXPRESSION || type == ASTNode.POSTFIX_EXPRESSION ||
381             type == ASTNode.CAST_EXPRESSION || type == ASTNode.INSTANCEOF_EXPRESSION;
382     }
383     
384     
385     public static boolean substituteMustBeParenthesized(Expression substitute, Expression location) {
386         if (!needsParentheses(substitute))
387             return false;
388             
389         ASTNode parent= location.getParent();
390         if (parent instanceof VariableDeclarationFragment){
391             VariableDeclarationFragment vdf= (VariableDeclarationFragment)parent;
392             if (vdf.getInitializer().equals(location))
393                 return false;
394         } else if (parent instanceof MethodInvocation){
395             MethodInvocation mi= (MethodInvocation)parent;
396             if (mi.arguments().contains(location))
397                 return false;
398         } else if (parent instanceof ReturnStatement)
399             return false;
400             
401         return true;
402     }
403     
404     public static ASTNode getParent(ASTNode node, Class JavaDoc parentClass) {
405         do {
406             node= node.getParent();
407         } while (node != null && !parentClass.isInstance(node));
408         return node;
409     }
410     
411     public static ASTNode getParent(ASTNode node, int nodeType) {
412         do {
413             node= node.getParent();
414         } while (node != null && node.getNodeType() != nodeType);
415         return node;
416     }
417     
418     public static ASTNode findParent(ASTNode node, StructuralPropertyDescriptor[][] pathes) {
419         for (int p= 0; p < pathes.length; p++) {
420             StructuralPropertyDescriptor[] path= pathes[p];
421             ASTNode current= node;
422             int d= path.length - 1;
423             for (; d >= 0 && current != null; d--) {
424                 StructuralPropertyDescriptor descriptor= path[d];
425                 if (!descriptor.equals(current.getLocationInParent()))
426                     break;
427                 current= current.getParent();
428             }
429             if (d < 0)
430                 return current;
431         }
432         return null;
433     }
434     
435     public static ASTNode getNormalizedNode(ASTNode node) {
436         ASTNode current= node;
437         // normalize name
438
if (QualifiedName.NAME_PROPERTY.equals(current.getLocationInParent())) {
439             current= current.getParent();
440         }
441         // normalize type
442
if (QualifiedType.NAME_PROPERTY.equals(current.getLocationInParent()) ||
443             SimpleType.NAME_PROPERTY.equals(current.getLocationInParent())) {
444             current= current.getParent();
445         }
446         // normalize parameterized types
447
if (ParameterizedType.TYPE_PROPERTY.equals(current.getLocationInParent())) {
448             current= current.getParent();
449         }
450         return current;
451     }
452     
453     public static boolean isParent(ASTNode node, ASTNode parent) {
454         Assert.isNotNull(parent);
455         do {
456             node= node.getParent();
457             if (node == parent)
458                 return true;
459         } while (node != null);
460         return false;
461     }
462     
463     public static int getExclusiveEnd(ASTNode node){
464         return node.getStartPosition() + node.getLength();
465     }
466     
467     public static int getInclusiveEnd(ASTNode node){
468         return node.getStartPosition() + node.getLength() - 1;
469     }
470     
471     public static IMethodBinding getMethodBinding(Name node) {
472         IBinding binding= node.resolveBinding();
473         if (binding instanceof IMethodBinding)
474             return (IMethodBinding)binding;
475         return null;
476     }
477     
478     public static IVariableBinding getVariableBinding(Name node) {
479         IBinding binding= node.resolveBinding();
480         if (binding instanceof IVariableBinding)
481             return (IVariableBinding)binding;
482         return null;
483     }
484     
485     public static IVariableBinding getLocalVariableBinding(Name node) {
486         IVariableBinding result= getVariableBinding(node);
487         if (result == null || result.isField())
488             return null;
489         
490         return result;
491     }
492     
493     public static IVariableBinding getFieldBinding(Name node) {
494         IVariableBinding result= getVariableBinding(node);
495         if (result == null || !result.isField())
496             return null;
497         
498         return result;
499     }
500     
501     public static ITypeBinding getTypeBinding(Name node) {
502         IBinding binding= node.resolveBinding();
503         if (binding instanceof ITypeBinding)
504             return (ITypeBinding)binding;
505         return null;
506     }
507
508     /**
509      * Returns the receiver's type binding of the given method invocation.
510      *
511      * @param invocation method invocation to resolve type of
512      * @return the type binding of the receiver
513      */

514     public static ITypeBinding getReceiverTypeBinding(MethodInvocation invocation) {
515         ITypeBinding result= null;
516         Expression exp= invocation.getExpression();
517         if(exp != null) {
518             return exp.resolveTypeBinding();
519         }
520         else {
521             AbstractTypeDeclaration type= (AbstractTypeDeclaration)getParent(invocation, AbstractTypeDeclaration.class);
522             if (type != null)
523                 return type.resolveBinding();
524         }
525         return result;
526     }
527
528     public static ITypeBinding getEnclosingType(ASTNode node) {
529         while(node != null) {
530             if (node instanceof AbstractTypeDeclaration) {
531                 return ((AbstractTypeDeclaration)node).resolveBinding();
532             } else if (node instanceof AnonymousClassDeclaration) {
533                 return ((AnonymousClassDeclaration)node).resolveBinding();
534             }
535             node= node.getParent();
536         }
537         return null;
538     }
539
540     public static IProblem[] getProblems(ASTNode node, int scope, int severity) {
541         ASTNode root= node.getRoot();
542         if (!(root instanceof CompilationUnit))
543             return EMPTY_PROBLEMS;
544         IProblem[] problems= ((CompilationUnit)root).getProblems();
545         if (root == node)
546             return problems;
547         final int iterations= computeIterations(scope);
548         List JavaDoc result= new ArrayList JavaDoc(5);
549         for (int i= 0; i < problems.length; i++) {
550             IProblem problem= problems[i];
551             boolean consider= false;
552             if ((severity & PROBLEMS) == PROBLEMS)
553                 consider= true;
554             else if ((severity & WARNING) != 0)
555                 consider= problem.isWarning();
556             else if ((severity & ERROR) != 0)
557                 consider= problem.isError();
558             if (consider) {
559                 ASTNode temp= node;
560                 int count= iterations;
561                 do {
562                     int nodeOffset= temp.getStartPosition();
563                     int problemOffset= problem.getSourceStart();
564                     if (nodeOffset <= problemOffset && problemOffset < nodeOffset + temp.getLength()) {
565                         result.add(problem);
566                         count= 0;
567                     } else {
568                         count--;
569                     }
570                 } while ((temp= temp.getParent()) != null && count > 0);
571             }
572         }
573         return (IProblem[]) result.toArray(new IProblem[result.size()]);
574     }
575     
576     public static Message[] getMessages(ASTNode node, int flags) {
577         ASTNode root= node.getRoot();
578         if (!(root instanceof CompilationUnit))
579             return EMPTY_MESSAGES;
580         Message[] messages= ((CompilationUnit)root).getMessages();
581         if (root == node)
582             return messages;
583         final int iterations= computeIterations(flags);
584         List JavaDoc result= new ArrayList JavaDoc(5);
585         for (int i= 0; i < messages.length; i++) {
586             Message message= messages[i];
587             ASTNode temp= node;
588             int count= iterations;
589             do {
590                 int nodeOffset= temp.getStartPosition();
591                 int messageOffset= message.getStartPosition();
592                 if (nodeOffset <= messageOffset && messageOffset < nodeOffset + temp.getLength()) {
593                     result.add(message);
594                     count= 0;
595                 } else {
596                     count--;
597                 }
598             } while ((temp= temp.getParent()) != null && count > 0);
599         }
600         return (Message[]) result.toArray(new Message[result.size()]);
601     }
602     
603     private static int computeIterations(int flags) {
604         switch (flags) {
605             case NODE_ONLY:
606                 return 1;
607             case INCLUDE_ALL_PARENTS:
608                 return Integer.MAX_VALUE;
609             case INCLUDE_FIRST_PARENT:
610                 return 2;
611             default:
612                 return 1;
613         }
614     }
615     
616     
617     private static int getOrderPreference(BodyDeclaration member, MembersOrderPreferenceCache store) {
618         int memberType= member.getNodeType();
619         int modifiers= member.getModifiers();
620
621         switch (memberType) {
622             case ASTNode.TYPE_DECLARATION:
623             case ASTNode.ENUM_DECLARATION :
624             case ASTNode.ANNOTATION_TYPE_DECLARATION :
625                 return store.getCategoryIndex(MembersOrderPreferenceCache.TYPE_INDEX) * 2;
626             case ASTNode.FIELD_DECLARATION:
627                 if (Modifier.isStatic(modifiers)) {
628                     int index= store.getCategoryIndex(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX) * 2;
629                     if (Modifier.isFinal(modifiers)) {
630                         return index; // first final static, then static
631
}
632                     return index + 1;
633                 }
634                 return store.getCategoryIndex(MembersOrderPreferenceCache.FIELDS_INDEX) * 2;
635             case ASTNode.INITIALIZER:
636                 if (Modifier.isStatic(modifiers)) {
637                     return store.getCategoryIndex(MembersOrderPreferenceCache.STATIC_INIT_INDEX) * 2;
638                 }
639                 return store.getCategoryIndex(MembersOrderPreferenceCache.INIT_INDEX) * 2;
640             case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION:
641                 return store.getCategoryIndex(MembersOrderPreferenceCache.METHOD_INDEX) * 2;
642             case ASTNode.METHOD_DECLARATION:
643                 if (Modifier.isStatic(modifiers)) {
644                     return store.getCategoryIndex(MembersOrderPreferenceCache.STATIC_METHODS_INDEX) * 2;
645                 }
646                 if (((MethodDeclaration) member).isConstructor()) {
647                     return store.getCategoryIndex(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX) * 2;
648                 }
649                 return store.getCategoryIndex(MembersOrderPreferenceCache.METHOD_INDEX) * 2;
650             default:
651                 return 100;
652         }
653     }
654             
655     /**
656      * Computes the insertion index to be used to add the given member to the
657      * the list <code>container</code>.
658      * @param member the member to add
659      * @param container a list containing objects of type <code>BodyDeclaration</code>
660      * @return the insertion index to be used
661      */

662     public static int getInsertionIndex(BodyDeclaration member, List JavaDoc container) {
663         int containerSize= container.size();
664         
665         MembersOrderPreferenceCache orderStore= JavaPlugin.getDefault().getMemberOrderPreferenceCache();
666         
667         int orderIndex= getOrderPreference(member, orderStore);
668         
669         int insertPos= containerSize;
670         int insertPosOrderIndex= -1;
671
672         for (int i= containerSize - 1; i >= 0; i--) {
673             int currOrderIndex= getOrderPreference((BodyDeclaration) container.get(i), orderStore);
674             if (orderIndex == currOrderIndex) {
675                 if (insertPosOrderIndex != orderIndex) { // no perfect match yet
676
insertPos= i + 1; // after a same kind
677
insertPosOrderIndex= orderIndex; // perfect match
678
}
679             } else if (insertPosOrderIndex != orderIndex) { // not yet a perfect match
680
if (currOrderIndex < orderIndex) { // we are bigger
681
if (insertPosOrderIndex == -1) {
682                         insertPos= i + 1; // after
683
insertPosOrderIndex= currOrderIndex;
684                     }
685                 } else {
686                     insertPos= i; // before
687
insertPosOrderIndex= currOrderIndex;
688                 }
689             }
690         }
691         return insertPos;
692     }
693
694     public static SimpleName getLeftMostSimpleName(Name name) {
695         if (name instanceof SimpleName) {
696             return (SimpleName)name;
697         } else {
698             final SimpleName[] result= new SimpleName[1];
699             ASTVisitor visitor= new ASTVisitor() {
700                 public boolean visit(QualifiedName qualifiedName) {
701                     Name left= qualifiedName.getQualifier();
702                     if (left instanceof SimpleName)
703                         result[0]= (SimpleName)left;
704                     else
705                         left.accept(this);
706                     return false;
707                 }
708             };
709             name.accept(visitor);
710             return result[0];
711         }
712     }
713     
714     public static SimpleType getLeftMostSimpleType(QualifiedType type) {
715         final SimpleType[] result= new SimpleType[1];
716         ASTVisitor visitor= new ASTVisitor() {
717             public boolean visit(QualifiedType qualifiedType) {
718                 Type left= qualifiedType.getQualifier();
719                 if (left instanceof SimpleType)
720                     result[0]= (SimpleType)left;
721                 else
722                     left.accept(this);
723                 return false;
724             }
725         };
726         type.accept(visitor);
727         return result[0];
728     }
729     
730     public static Name getTopMostName(Name name) {
731         Name result= name;
732         while(result.getParent() instanceof Name) {
733             result= (Name)result.getParent();
734         }
735         return result;
736     }
737     
738     public static Type getTopMostType(Type type) {
739         Type result= type;
740         while(result.getParent() instanceof Type) {
741             result= (Type)result.getParent();
742         }
743         return result;
744     }
745     
746     public static int changeVisibility(int modifiers, int visibility) {
747         return (modifiers & CLEAR_VISIBILITY) | visibility;
748     }
749     
750     /**
751      * Adds flags to the given node and all its descendants.
752      * @param root The root node
753      * @param flags The flags to set
754      */

755     public static void setFlagsToAST(ASTNode root, final int flags) {
756         root.accept(new GenericVisitor(true) {
757             protected boolean visitNode(ASTNode node) {
758                 node.setFlags(node.getFlags() | flags);
759                 return true;
760             }
761         });
762     }
763
764     public static String JavaDoc getQualifier(Name name) {
765         if (name.isQualifiedName()) {
766             return ((QualifiedName) name).getQualifier().getFullyQualifiedName();
767         }
768         return ""; //$NON-NLS-1$
769
}
770
771     public static String JavaDoc getSimpleNameIdentifier(Name name) {
772         if (name.isQualifiedName()) {
773             return ((QualifiedName) name).getName().getIdentifier();
774         } else {
775             return ((SimpleName) name).getIdentifier();
776         }
777     }
778
779     public static boolean isDeclaration(Name name) {
780         if (name.isQualifiedName()) {
781             return ((QualifiedName) name).getName().isDeclaration();
782         } else {
783             return ((SimpleName) name).isDeclaration();
784         }
785     }
786
787     public static Modifier findModifierNode(int flag, List JavaDoc modifiers) {
788         for (int i= 0; i < modifiers.size(); i++) {
789             Object JavaDoc curr= modifiers.get(i);
790             if (curr instanceof Modifier && ((Modifier) curr).getKeyword().toFlagValue() == flag) {
791                 return (Modifier) curr;
792             }
793         }
794         return null;
795     }
796
797     public static ITypeBinding getTypeBinding(CompilationUnit root, IType type) throws JavaModelException {
798         if (type.isAnonymous()) {
799             final IJavaElement parent= type.getParent();
800             if (parent instanceof IField && Flags.isEnum(((IMember) parent).getFlags())) {
801                 final EnumConstantDeclaration constant= (EnumConstantDeclaration) NodeFinder.perform(root, ((ISourceReference) parent).getSourceRange());
802                 if (constant != null) {
803                     final AnonymousClassDeclaration declaration= constant.getAnonymousClassDeclaration();
804                     if (declaration != null)
805                         return declaration.resolveBinding();
806                 }
807             } else {
808                 final ClassInstanceCreation creation= (ClassInstanceCreation) getParent(NodeFinder.perform(root, type.getNameRange()), ClassInstanceCreation.class);
809                 if (creation != null)
810                     return creation.resolveTypeBinding();
811             }
812         } else {
813             final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) getParent(NodeFinder.perform(root, type.getNameRange()), AbstractTypeDeclaration.class);
814             if (declaration != null)
815                 return declaration.resolveBinding();
816         }
817         return null;
818     }
819 }
820
Popular Tags