KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > java > source > ElementUtilities


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.api.java.source;
20
21 import com.sun.javadoc.Doc;
22 import com.sun.source.tree.CompilationUnitTree;
23 import com.sun.source.tree.Scope;
24 import com.sun.source.util.JavacTask;
25 import com.sun.source.util.TreePath;
26 import com.sun.source.util.Trees;
27 import com.sun.tools.javac.api.JavacTaskImpl;
28 import com.sun.tools.javac.api.JavacTrees;
29 import com.sun.tools.javac.code.Flags;
30 import com.sun.tools.javac.code.Source;
31 import com.sun.tools.javac.code.Symbol;
32 import com.sun.tools.javac.code.Symbol.ClassSymbol;
33 import com.sun.tools.javac.code.Symbol.MethodSymbol;
34 import com.sun.tools.javac.code.Symbol.PackageSymbol;
35 import com.sun.tools.javac.code.Symbol.VarSymbol;
36 import com.sun.tools.javac.code.Symtab;
37 import com.sun.tools.javac.code.Type;
38 import com.sun.tools.javac.code.Type.ClassType;
39 import com.sun.tools.javac.model.JavacElements;
40 import com.sun.tools.javac.model.JavacTypes;
41 import com.sun.tools.javac.util.Context;
42 import com.sun.tools.javac.util.Name;
43 import com.sun.tools.javadoc.DocEnv;
44
45 import java.util.ArrayList JavaDoc;
46 import java.util.HashMap JavaDoc;
47 import java.util.HashSet JavaDoc;
48 import javax.lang.model.element.Element;
49 import javax.lang.model.element.ElementKind;
50 import javax.lang.model.element.ExecutableElement;
51 import javax.lang.model.element.PackageElement;
52 import javax.lang.model.element.TypeElement;
53 import javax.lang.model.type.DeclaredType;
54 import javax.lang.model.type.ExecutableType;
55 import javax.lang.model.type.TypeMirror;
56 import javax.lang.model.util.Elements;
57 import javax.lang.model.util.Types;
58 import org.netbeans.modules.java.source.builder.ASTService;
59
60 import org.netbeans.modules.java.source.builder.ElementsService;
61 import org.netbeans.modules.java.source.JavadocEnv;
62 import org.netbeans.modules.java.source.engine.RootTree;
63
64 /**
65  *
66  * @author Jan Lahoda, Dusan Balek
67  */

68 public final class ElementUtilities {
69     
70     private Context ctx;
71     private ElementsService delegate;
72     
73     /** Creates a new instance of ElementUtilities */
74     ElementUtilities(CompilationInfo info) {
75         this(info.getJavacTask());
76     }
77     
78     public ElementUtilities(JavacTask task) {
79         this.ctx = ((JavacTaskImpl)task).getContext();
80         this.delegate = ElementsService.instance(ctx);
81     }
82     
83     /**
84      * Returns the TypeElement which encloses the specified element.
85      */

86     public TypeElement enclosingTypeElement(Element element) {
87         return delegate.enclosingTypeElement(element);
88     }
89
90     /**
91      *
92      * The outermost TypeElement which indirectly encloses this element.
93      */

94     public TypeElement outermostTypeElement(Element element) {
95         return delegate.outermostTypeElement(element);
96     }
97
98     /**
99      *
100      * The package element which indirectly encloses this element..
101      */

102     public PackageElement packageElement(Element element) {
103         return delegate.packageElement(element);
104     }
105     
106     /**
107      * Returns the implementation of a method in class origin; null if none exists.
108      */

109     public Element getImplementationOf(ExecutableElement method, TypeElement origin) {
110         return delegate.getImplementationOf(method, origin);
111     }
112     
113     /**Returns true if the given element is syntetic.
114      *
115      * @param element to check
116      * @return true if and only if the given element is syntetic, false otherwise
117      */

118     public boolean isSynthetic(Element element) {
119         return delegate.isSynthetic(element);
120     }
121     
122     /**
123      * Returns true if this element represents a method which overrides a
124      * method in one of its superclasses.
125      */

126     public boolean overridesMethod(ExecutableElement element) {
127         return delegate.overridesMethod(element);
128     }
129
130     /**
131      * Returns a binary name of a type.
132      * @param element for which the binary name should be returned
133      * @return the binary name, see Java Language Specification 13.1
134      * @throws IllegalArgumentException when the element is not a javac element
135      */

136     public static String JavaDoc getBinaryName (TypeElement element) throws IllegalArgumentException JavaDoc {
137         if (element instanceof Symbol.TypeSymbol) {
138             return ((Symbol.TypeSymbol)element).flatName().toString();
139         }
140         else {
141             throw new IllegalArgumentException JavaDoc ();
142         }
143     }
144     
145     public Doc javaDocFor(Element element) {
146         if (element != null) {
147             DocEnv env = DocEnv.instance(ctx);
148             switch (element.getKind()) {
149                 case ANNOTATION_TYPE:
150                 case CLASS:
151                 case ENUM:
152                 case INTERFACE:
153                     return env.getClassDoc((ClassSymbol)element);
154                 case ENUM_CONSTANT:
155                 case FIELD:
156                     return env.getFieldDoc((VarSymbol)element);
157                 case METHOD:
158                     if (element.getEnclosingElement().getKind() == ElementKind.ANNOTATION_TYPE)
159                         return env.getAnnotationTypeElementDoc((MethodSymbol)element);
160                     return env.getMethodDoc((MethodSymbol)element);
161                 case CONSTRUCTOR:
162                     return env.getConstructorDoc((MethodSymbol)element);
163                 case PACKAGE:
164                     return env.getPackageDoc((PackageSymbol)element);
165             }
166         }
167         return null;
168     }
169     
170     public Element elementFor(Doc doc) {
171         return (doc instanceof JavadocEnv.ElementHolder) ? ((JavadocEnv.ElementHolder)doc).getElement() : null;
172     }
173     
174     public Iterable JavaDoc<? extends Element> getMembers(TypeMirror type, ElementAcceptor acceptor) {
175         ArrayList JavaDoc<Element> members = new ArrayList JavaDoc<Element>();
176         if (type != null) {
177             Elements elements = JavacElements.instance(ctx);
178             switch (type.getKind()) {
179                 case DECLARED:
180                     for (Element member : elements.getAllMembers((TypeElement)((DeclaredType)type).asElement())) {
181                         if (acceptor == null || acceptor.accept(member, type))
182                             members.add(member);
183                     }
184                 case BOOLEAN:
185                 case BYTE:
186                 case CHAR:
187                 case DOUBLE:
188                 case FLOAT:
189                 case INT:
190                 case LONG:
191                 case SHORT:
192                 case VOID:
193                     Type t = Symtab.instance(ctx).classType;
194                     com.sun.tools.javac.util.List<Type> typeargs = Source.instance(ctx).allowGenerics() ?
195                         com.sun.tools.javac.util.List.of((Type)type) :
196                         com.sun.tools.javac.util.List.<Type>nil();
197                     t = new ClassType(t.getEnclosingType(), typeargs, t.tsym);
198                     Element classPseudoMember = new VarSymbol(Flags.STATIC | Flags.PUBLIC | Flags.FINAL, Name.Table.instance(ctx)._class, t, ((Type)type).tsym);
199                     if (acceptor == null || acceptor.accept(classPseudoMember, type))
200                         members.add(classPseudoMember);
201                     break;
202                 case ARRAY:
203                     for (Element member : elements.getAllMembers((TypeElement)((Type)type).tsym)) {
204                         if (acceptor == null || acceptor.accept(member, type))
205                             members.add(member);
206                     }
207                     break;
208             }
209         }
210         return members;
211     }
212     
213     public Iterable JavaDoc<? extends Element> getLocalMembersAndVars(Scope scope, ElementAcceptor acceptor) {
214         ArrayList JavaDoc<Element> members = new ArrayList JavaDoc<Element>();
215         HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<Element>> hiders = new HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<Element>>();
216         Elements elements = JavacElements.instance(ctx);
217         Types types = JavacTypes.instance(ctx);
218         TypeElement cls;
219         while(scope != null && (cls = scope.getEnclosingClass()) != null) {
220             for (Element local : scope.getLocalElements())
221                 if (acceptor == null || acceptor.accept(local, null)) {
222                     String JavaDoc name = local.getSimpleName().toString();
223                     ArrayList JavaDoc<Element> h = hiders.get(name);
224                     if (!isHidden(local, h, elements, types)) {
225                         members.add(local);
226                         if (h == null) {
227                             h = new ArrayList JavaDoc<Element>();
228                             hiders.put(name, h);
229                         }
230                         h.add(local);
231                     }
232                 }
233             TypeMirror type = cls.asType();
234             for (Element member : elements.getAllMembers(cls)) {
235                 if (acceptor == null || acceptor.accept(member, type)) {
236                     String JavaDoc name = member.getSimpleName().toString();
237                     ArrayList JavaDoc<Element> h = hiders.get(name);
238                     if (!isHidden(member, h, elements, types)) {
239                         members.add(member);
240                         if (h == null) {
241                             h = new ArrayList JavaDoc<Element>();
242                             hiders.put(name, h);
243                         }
244                         h.add(member);
245                     }
246                 }
247             }
248             scope = scope.getEnclosingScope();
249         }
250         while(scope != null) {
251             for (Element local : scope.getLocalElements()) {
252                 if (!local.getKind().isClass() && !local.getKind().isInterface() &&
253                     (acceptor == null || acceptor.accept(local, local.getEnclosingElement().asType()))) {
254                     String JavaDoc name = local.getSimpleName().toString();
255                     ArrayList JavaDoc<Element> h = hiders.get(name);
256                     if (!isHidden(local, h, elements, types)) {
257                         members.add(local);
258                         if (h == null) {
259                             h = new ArrayList JavaDoc<Element>();
260                             hiders.put(name, h);
261                         }
262                         h.add(local);
263                     }
264                 }
265             }
266             scope = scope.getEnclosingScope();
267         }
268         return members;
269     }
270
271     public Iterable JavaDoc<? extends Element> getLocalVars(Scope scope, ElementAcceptor acceptor) {
272         ArrayList JavaDoc<Element> members = new ArrayList JavaDoc<Element>();
273         HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<Element>> hiders = new HashMap JavaDoc<String JavaDoc, ArrayList JavaDoc<Element>>();
274         Elements elements = JavacElements.instance(ctx);
275         Types types = JavacTypes.instance(ctx);
276         while(scope != null && scope.getEnclosingClass() != null) {
277             for (Element local : scope.getLocalElements())
278                 if (acceptor == null || acceptor.accept(local, null)) {
279                     String JavaDoc name = local.getSimpleName().toString();
280                     ArrayList JavaDoc<Element> h = hiders.get(name);
281                     if (!isHidden(local, h, elements, types)) {
282                         members.add(local);
283                         if (h == null) {
284                             h = new ArrayList JavaDoc<Element>();
285                             hiders.put(name, h);
286                         }
287                         h.add(local);
288                     }
289                 }
290             scope = scope.getEnclosingScope();
291         }
292         return members;
293     }
294     
295     public Iterable JavaDoc<? extends TypeElement> getGlobalTypes(ElementAcceptor acceptor) {
296         HashSet JavaDoc<TypeElement> members = new HashSet JavaDoc<TypeElement>();
297         Trees trees = JavacTrees.instance(ctx);
298         RootTree root = (RootTree)ASTService.instance(ctx).getRoot();
299         for (CompilationUnitTree unit : root.getCompilationUnits()) {
300             TreePath path = new TreePath(unit);
301             Element element = trees.getElement(path);
302             if (element != null && element.getKind() == ElementKind.PACKAGE) {
303                 for (Element member : element.getEnclosedElements()) {
304                     if (acceptor == null || acceptor.accept(member, null))
305                         members.add((TypeElement)member);
306                 }
307             }
308             Scope scope = trees.getScope(path);
309             while (scope != null) {
310                 for (Element local : scope.getLocalElements())
311                     if ((local.getKind().isClass() || local.getKind().isInterface()) &&
312                         (acceptor == null || acceptor.accept(local, null)))
313                         members.add((TypeElement)local);
314                 scope = scope.getEnclosingScope();
315             }
316         }
317         return members;
318     }
319
320     public static interface ElementAcceptor {
321         boolean accept(Element e, TypeMirror type);
322     }
323     
324     private boolean isHidden(Element member, Iterable JavaDoc<Element> hiders, Elements elements, Types types) {
325         if (hiders != null) {
326             for (Element hider : hiders) {
327                 if (hider == member || (hider.getClass() == member.getClass() && //TODO: getClass() should not be used here
328
hider.getSimpleName() == member.getSimpleName() &&
329                     ((hider.getKind() != ElementKind.METHOD && hider.getKind() != ElementKind.CONSTRUCTOR)
330                     || types.isSubsignature((ExecutableType)hider.asType(), (ExecutableType)member.asType()))))
331             return true;
332             }
333         }
334         return false;
335     }
336     
337     /**
338      * Returns true if the specified element is referenced by a specified tree.
339      */

340     public boolean referenced(Element e, Element parent) {
341         return delegate.referenced(e, parent);
342     }
343     
344     /**
345      * Returns true if the element is assigned by a specified tree.
346      */

347     public boolean assigned(Element e, Element parent) {
348         return delegate.assigned(e, parent);
349     }
350     
351     /**
352      * Returns true if the element is a parameter for a specified method.
353      */

354     public boolean parameter(Element e, Element parent) {
355         return delegate.parameter(e, parent);
356     }
357     
358     /**
359      * Returns true if the element is declared (directly or indirectly) local
360      * to a method or variable initializer. Also true for fields of inner
361      * classes which are in turn local to a method or variable initializer.
362      */

363     public boolean isLocal(Element element) {
364         return delegate.isLocal(element);
365     }
366     
367     /**
368      * Returns true if a method specified by name and type is defined in a
369      * class type.
370      */

371     public boolean alreadyDefinedIn(CharSequence JavaDoc name, ExecutableType method, TypeElement enclClass) {
372         return delegate.alreadyDefinedIn(name, method, enclClass);
373     }
374     
375     /**
376      * Returns true if a type element has the specified element as a member.
377      */

378     public boolean isMemberOf(Element e, TypeElement type) {
379         return delegate.isMemberOf(e, type);
380     }
381     
382     /**
383      * Returns the fully qualified name of this element, which is its
384      * simple name with its owner(s) prepended.
385      */

386     public CharSequence JavaDoc getFullName(Element element) {
387         return delegate.getFullName(element);
388     }
389
390     /**
391      * Returns the parent method which the specified method overrides, or null
392      * if the method does not override a parent class method.
393      */

394     public ExecutableElement getOverriddenMethod(ExecutableElement method) {
395         return delegate.getOverriddenMethod(method);
396     }
397     /**
398      * Returns true if this element represents a method which
399      * implements a method in an interface the parent class implements.
400      */

401     public boolean implementsMethod(ExecutableElement element) {
402         return delegate.implementsMethod(element);
403     }
404 }
405
Popular Tags