KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > apt > model > ElementsImpl


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 BEA Systems, Inc.
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  * wharley@bea.com - initial API and implementation
10  *
11  *******************************************************************************/

12
13 package org.eclipse.jdt.internal.compiler.apt.model;
14
15 import java.io.IOException JavaDoc;
16 import java.io.Writer JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.Collections JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.LinkedHashSet JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Set JavaDoc;
25 import java.util.regex.Matcher JavaDoc;
26 import java.util.regex.Pattern JavaDoc;
27
28 import javax.lang.model.element.AnnotationMirror;
29 import javax.lang.model.element.AnnotationValue;
30 import javax.lang.model.element.Element;
31 import javax.lang.model.element.ElementKind;
32 import javax.lang.model.element.ExecutableElement;
33 import javax.lang.model.element.Name;
34 import javax.lang.model.element.PackageElement;
35 import javax.lang.model.element.TypeElement;
36 import javax.lang.model.util.Elements;
37
38 import org.eclipse.jdt.core.compiler.CharOperation;
39 import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
40 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
41 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
42 import org.eclipse.jdt.internal.compiler.ast.Javadoc;
43 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
44 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
45 import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
46 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
47 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
48 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
49 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
50 import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier;
51 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
52 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
53 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
54 import org.eclipse.jdt.internal.compiler.lookup.TagBits;
55 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
56
57 /**
58  * Utilities for working with language elements.
59  * There is one of these for every ProcessingEnvironment.
60  */

61 public class ElementsImpl implements Elements {
62
63     // Used for parsing Javadoc comments: matches initial delimiter, followed by whitespace
64
private static final Pattern JavaDoc INITIAL_DELIMITER = Pattern.compile("^\\s*/\\*+"); //$NON-NLS-1$
65

66     private final BaseProcessingEnvImpl _env;
67
68     /*
69      * The processing env creates and caches an ElementsImpl. Other clients should
70      * not create their own; they should ask the env for it.
71      */

72     public ElementsImpl(BaseProcessingEnvImpl env) {
73         _env = env;
74     }
75
76     /**
77      * Return all the annotation mirrors on this element, including inherited annotations.
78      * Annotations are inherited only if the annotation type is meta-annotated with @Inherited,
79      * and the annotation is on a class: e.g., annotations are not inherited for interfaces, methods,
80      * or fields.
81      */

82     @Override JavaDoc
83     public List JavaDoc<? extends AnnotationMirror> getAllAnnotationMirrors(Element e) {
84         // if e is a class, walk up its superclass hierarchy looking for @Inherited annotations not already in the list
85
if (e.getKind() == ElementKind.CLASS && e instanceof TypeElementImpl) {
86             List JavaDoc<AnnotationBinding> annotations = new ArrayList JavaDoc<AnnotationBinding>();
87             // A class can only have one annotation of a particular annotation type.
88
Set JavaDoc<ReferenceBinding> annotationTypes = new HashSet JavaDoc<ReferenceBinding>();
89             ReferenceBinding binding = (ReferenceBinding)((TypeElementImpl)e)._binding;
90             while (null != binding) {
91                 for (AnnotationBinding annotation : binding.getAnnotations()) {
92                     if (annotation == null) continue;
93                     ReferenceBinding annotationType = annotation.getAnnotationType();
94                     if (!annotationTypes.contains(annotationType)) {
95                         annotationTypes.add(annotationType);
96                         annotations.add(annotation);
97                     }
98                 }
99                 binding = binding.superclass();
100             }
101             List JavaDoc<AnnotationMirror> list = new ArrayList JavaDoc<AnnotationMirror>(annotations.size());
102             for (AnnotationBinding annotation : annotations) {
103                 list.add(_env.getFactory().newAnnotationMirror(annotation));
104             }
105             return Collections.unmodifiableList(list);
106         }
107         else {
108             return e.getAnnotationMirrors();
109         }
110     }
111
112     /**
113      * Compute a list of all the visible entities in this type. Specifically:
114      * <ul>
115      * <li>All nested types declared in this type, including interfaces and enums</li>
116      * <li>All protected or public nested types declared in this type's superclasses
117      * and superinterfaces, that are not hidden by a name collision</li>
118      * <li>All methods declared in this type, including constructors but not
119      * including static or instance initializers, and including abstract
120      * methods and unimplemented methods declared in interfaces</li>
121      * <li>All protected or public methods declared in this type's superclasses,
122      * that are not overridden by another method, but not including constructors
123      * or initializers. Includes abstract methods and methods declared in
124      * superinterfaces but not implemented</li>
125      * <li>All fields declared in this type, including constants</li>
126      * <li>All non-private fields declared in this type's superclasses and
127      * superinterfaces, that are not hidden by a name collision.</li>
128      * </ul>
129      */

130     @Override JavaDoc
131     public List JavaDoc<? extends Element> getAllMembers(TypeElement type) {
132         if (null == type || !(type instanceof TypeElementImpl)) {
133             return Collections.emptyList();
134         }
135         ReferenceBinding binding = (ReferenceBinding)((TypeElementImpl)type)._binding;
136         // Map of element simple name to binding
137
Map JavaDoc<String JavaDoc, ReferenceBinding> types = new HashMap JavaDoc<String JavaDoc, ReferenceBinding>();
138         // Javac implementation does not take field name collisions into account
139
List JavaDoc<FieldBinding> fields = new ArrayList JavaDoc<FieldBinding>();
140         // For methods, need to compare parameters, not just names
141
Map JavaDoc<String JavaDoc, Set JavaDoc<MethodBinding>> methods = new HashMap JavaDoc<String JavaDoc, Set JavaDoc<MethodBinding>>();
142         Set JavaDoc<ReferenceBinding> superinterfaces = new LinkedHashSet JavaDoc<ReferenceBinding>();
143         boolean ignoreVisibility = true;
144         while (null != binding) {
145             addMembers(binding, ignoreVisibility, types, fields, methods);
146             Set JavaDoc<ReferenceBinding> newfound = new LinkedHashSet JavaDoc<ReferenceBinding>();
147             collectSuperInterfaces(binding, superinterfaces, newfound);
148             for (ReferenceBinding superinterface : newfound) {
149                 addMembers(superinterface, false, types, fields, methods);
150             }
151             superinterfaces.addAll(newfound);
152             binding = binding.superclass();
153             ignoreVisibility = false;
154         }
155         List JavaDoc<Element> allMembers = new ArrayList JavaDoc<Element>();
156         for (ReferenceBinding nestedType : types.values()) {
157             allMembers.add(_env.getFactory().newElement(nestedType));
158         }
159         for (FieldBinding field : fields) {
160             allMembers.add(_env.getFactory().newElement(field));
161         }
162         for (Set JavaDoc<MethodBinding> sameNamedMethods : methods.values()) {
163             for (MethodBinding method : sameNamedMethods) {
164                 allMembers.add(_env.getFactory().newElement(method));
165             }
166         }
167         return allMembers;
168     }
169
170     /**
171      * Recursively depth-first walk the tree of superinterfaces of a type, collecting
172      * all the unique superinterface bindings. (Note that because of generics, a type may
173      * have multiple unique superinterface bindings corresponding to the same interface
174      * declaration.)
175      * @param existing bindings already in this set will not be re-added or recursed into
176      * @param newfound newly found bindings will be added to this set
177      */

178     private void collectSuperInterfaces(ReferenceBinding type,
179             Set JavaDoc<ReferenceBinding> existing, Set JavaDoc<ReferenceBinding> newfound) {
180         for (ReferenceBinding superinterface : type.superInterfaces()) {
181             if (!existing.contains(superinterface) && !newfound.contains(superinterface)) {
182                 newfound.add(superinterface);
183                 collectSuperInterfaces(superinterface, existing, newfound);
184             }
185         }
186     }
187
188     /**
189      * Add the members of a type to the maps of subtypes, fields, and methods. Add only those
190      * which are non-private and which are not overridden by an already-discovered member.
191      * For fields, add them all; javac implementation does not take field hiding into account.
192      * @param binding the type whose members will be added to the lists
193      * @param ignoreVisibility if true, all members will be added regardless of whether they
194      * are private, overridden, etc.
195      * @param types a map of type simple name to type binding
196      * @param fields a list of field bindings
197      * @param methods a map of method simple name to set of method bindings with that name
198      */

199     private void addMembers(ReferenceBinding binding, boolean ignoreVisibility, Map JavaDoc<String JavaDoc, ReferenceBinding> types,
200             List JavaDoc<FieldBinding> fields, Map JavaDoc<String JavaDoc, Set JavaDoc<MethodBinding>> methods)
201     {
202         for (ReferenceBinding subtype : binding.memberTypes()) {
203             if (ignoreVisibility || !subtype.isPrivate()) {
204                 String JavaDoc name = new String JavaDoc(subtype.sourceName());
205                 if (null == types.get(name)) {
206                     types.put(name, subtype);
207                 }
208             }
209         }
210         for (FieldBinding field : binding.fields()) {
211             if (ignoreVisibility || !field.isPrivate()) {
212                 fields.add(field);
213             }
214         }
215         for (MethodBinding method : binding.methods()) {
216             if (!method.isSynthetic() && (ignoreVisibility || (!method.isPrivate() && !method.isConstructor()))) {
217                 String JavaDoc methodName = new String JavaDoc(method.selector);
218                 Set JavaDoc<MethodBinding> sameNamedMethods = methods.get(methodName);
219                 if (null == sameNamedMethods) {
220                     // New method name. Create a set for it and add it to the list.
221
// We don't expect many methods with same name, so only 4 slots:
222
sameNamedMethods = new HashSet JavaDoc<MethodBinding>(4);
223                     methods.put(methodName, sameNamedMethods);
224                     sameNamedMethods.add(method);
225                 }
226                 else {
227                     // We already have a method with this name. Is this method overridden?
228
boolean unique = true;
229                     if (!ignoreVisibility) {
230                         for (MethodBinding existing : sameNamedMethods) {
231                             MethodVerifier verifier = _env.getLookupEnvironment().methodVerifier();
232                             if (verifier.doesMethodOverride(existing, method)) {
233                                 unique = false;
234                                 break;
235                             }
236                         }
237                     }
238                     if (unique) {
239                         sameNamedMethods.add(method);
240                     }
241                 }
242             }
243         }
244     }
245
246     /* (non-Javadoc)
247      * @see javax.lang.model.util.Elements#getBinaryName(javax.lang.model.element.TypeElement)
248      */

249     @Override JavaDoc
250     public Name getBinaryName(TypeElement type) {
251         TypeElementImpl typeElementImpl = (TypeElementImpl) type;
252         ReferenceBinding referenceBinding = (ReferenceBinding) typeElementImpl._binding;
253         return new NameImpl(
254             CharOperation.replaceOnCopy(referenceBinding.constantPoolName(), '/', '.'));
255     }
256
257     /* (non-Javadoc)
258      * @see javax.lang.model.util.Elements#getConstantExpression(java.lang.Object)
259      */

260     @Override JavaDoc
261     public String JavaDoc getConstantExpression(Object JavaDoc value) {
262         if (!(value instanceof Integer JavaDoc)
263                 && !(value instanceof Byte JavaDoc)
264                 && !(value instanceof Float JavaDoc)
265                 && !(value instanceof Double JavaDoc)
266                 && !(value instanceof Long JavaDoc)
267                 && !(value instanceof Short JavaDoc)
268                 && !(value instanceof Character JavaDoc)
269                 && !(value instanceof String JavaDoc)
270                 && !(value instanceof Boolean JavaDoc)) {
271             throw new IllegalArgumentException JavaDoc("Not a valid wrapper type : " + value.getClass()); //$NON-NLS-1$
272
}
273         if (value instanceof Character JavaDoc) {
274             StringBuilder JavaDoc builder = new StringBuilder JavaDoc();
275             builder.append('\'').append(value).append('\'');
276             return String.valueOf(builder);
277         }
278         return String.valueOf(value);
279     }
280
281     /* (non-Javadoc)
282      * @see javax.lang.model.util.Elements#getDocComment(javax.lang.model.element.Element)
283      */

284     @Override JavaDoc
285     public String JavaDoc getDocComment(Element e) {
286         char[] unparsed = getUnparsedDocComment(e);
287         return formatJavadoc(unparsed);
288     }
289
290     /**
291      * Return the entire javadoc comment on e, including the comment characters and whitespace
292      * @param e an Element of any sort, possibly with a javadoc comment.
293      * @return a String, or null if the comment is not available
294      */

295     private char[] getUnparsedDocComment(Element e)
296     {
297         Javadoc javadoc = null;
298         ReferenceContext referenceContext = null;
299         switch(e.getKind()) {
300             case ANNOTATION_TYPE :
301             case CLASS :
302             case ENUM :
303             case INTERFACE :
304                 TypeElementImpl typeElementImpl = (TypeElementImpl) e;
305                 ReferenceBinding referenceBinding = (ReferenceBinding)typeElementImpl._binding;
306                 if (referenceBinding instanceof SourceTypeBinding) {
307                     SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) referenceBinding;
308                     referenceContext = sourceTypeBinding.scope.referenceContext;
309                     javadoc = ((TypeDeclaration) referenceContext).javadoc;
310                 }
311                 break;
312             case PACKAGE :
313                 // might need to handle javadoc of package-info.java file
314
PackageElementImpl packageElementImpl = (PackageElementImpl) e;
315                 PackageBinding packageBinding = (PackageBinding) packageElementImpl._binding;
316                 char[][] compoundName = CharOperation.arrayConcat(packageBinding.compoundName, TypeConstants.PACKAGE_INFO_NAME);
317                 ReferenceBinding type = this._env.getLookupEnvironment().getType(compoundName);
318                 if (type != null && type.isValidBinding() && (type instanceof SourceTypeBinding)) {
319                     SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) type;
320                     referenceContext = sourceTypeBinding.scope.referenceContext;
321                     javadoc = ((TypeDeclaration) referenceContext).javadoc;
322                 }
323                 break;
324             case CONSTRUCTOR :
325             case METHOD :
326                 ExecutableElementImpl executableElementImpl = (ExecutableElementImpl) e;
327                 MethodBinding methodBinding = (MethodBinding) executableElementImpl._binding;
328                 AbstractMethodDeclaration sourceMethod = methodBinding.sourceMethod();
329                 if (sourceMethod != null) {
330                     javadoc = sourceMethod.javadoc;
331                     referenceContext = sourceMethod;
332                 }
333                 break;
334             case ENUM_CONSTANT :
335             case FIELD :
336                 VariableElementImpl variableElementImpl = (VariableElementImpl) e;
337                 FieldBinding fieldBinding = (FieldBinding) variableElementImpl._binding;
338                 FieldDeclaration sourceField = fieldBinding.sourceField();
339                 if (sourceField != null) {
340                     javadoc = sourceField.javadoc;
341                     if (fieldBinding.declaringClass instanceof SourceTypeBinding) {
342                         SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) fieldBinding.declaringClass;
343                         referenceContext = sourceTypeBinding.scope.referenceContext;
344                     }
345                 }
346         }
347         if (javadoc != null && referenceContext != null) {
348             char[] contents = referenceContext.compilationResult().getCompilationUnit().getContents();
349             if (contents != null) {
350                 return CharOperation.subarray(contents, javadoc.sourceStart, javadoc.sourceEnd - 1);
351             }
352         }
353         return null;
354     }
355
356     /**
357      * Strip the comment characters from a javadoc comment. Assume the comment is already
358      * missing its closing delimiter.
359      *
360      * Javac's behavior with regard to tab expansion and trimming of whitespace and
361      * asterisks is bizarre and undocumented. We do our best here to emulate it.
362      */

363     private static String JavaDoc formatJavadoc(char[] unparsed)
364     {
365         if (unparsed == null || unparsed.length < 5) { // delimiters take 5 chars
366
return null;
367         }
368
369         String JavaDoc[] lines = new String JavaDoc(unparsed).split("\n"); //$NON-NLS-1$
370
Matcher JavaDoc delimiterMatcher = INITIAL_DELIMITER.matcher(lines[0]);
371         if (!delimiterMatcher.find()) {
372             return null;
373         }
374         int iOpener = delimiterMatcher.end();
375         lines[0] = lines[0].substring(iOpener);
376         if (lines.length == 1) {
377             // single-line comment. Should trim(), but javac doesn't.
378
// we should however remove the starting whitespaces
379
StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
380             char[] chars = lines[0].toCharArray();
381             boolean startingWhitespaces = true;
382             for (char c : chars) {
383                 if (Character.isWhitespace(c))
384                     if (startingWhitespaces) {
385                         continue;
386                     } else {
387                         sb.append(c);
388                 } else {
389                     startingWhitespaces = false;
390                     sb.append(c);
391                 }
392             }
393             return sb.toString();
394         }
395
396         // if the first line ends with spaces after the /** then we want to insert a line separator
397
int firstLine = lines[0].trim().length() > 0 ? 0 : 1;
398
399         // If the last line is now empty, skip it
400
int lastLine = lines[lines.length - 1].trim().length() > 0 ? lines.length - 1 : lines.length - 2;
401
402         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
403         if (lines[0].length() != 0 && firstLine == 1) {
404             // insert a line separator only if the remaining chars on the line are whitespaces
405
sb.append('\n');
406         }
407         boolean preserveLineSeparator = lines[0].length() == 0;
408         for (int line = firstLine; line <= lastLine; ++line) {
409             char[] chars = lines[line].toCharArray();
410             int starsIndex = getStars(chars);
411             int leadingWhitespaces = 0;
412             boolean recordLeadingWhitespaces = true;
413             for (int i = 0, max = chars.length; i < max; i++) {
414                 char c = chars[i];
415                 switch(c) {
416                     case '\t' :
417                         if (starsIndex == -1) {
418                             if (recordLeadingWhitespaces) {
419                                 leadingWhitespaces += 8;
420                             } else {
421                                 sb.append(c);
422                             }
423                         } else if (i >= starsIndex) {
424                             sb.append(c);
425                         }
426                         break;
427                     case ' ' :
428                         if (starsIndex == -1) {
429                             if (recordLeadingWhitespaces) {
430                                 leadingWhitespaces++;
431                             } else {
432                                 sb.append(c);
433                             }
434                         } else if (i >= starsIndex) {
435                             sb.append(c);
436                         }
437                         break;
438                     default :
439                         // convert leading whitespaces to spaces
440
recordLeadingWhitespaces = false;
441                         if (leadingWhitespaces != 0) {
442                             int numberOfTabs = leadingWhitespaces / 8;
443                             if (numberOfTabs != 0) {
444                                 for (int j = 0, max2 = numberOfTabs; j < max2; j++) {
445                                     sb.append(" "); //$NON-NLS-1$
446
}
447                                 if ((leadingWhitespaces % 8) >= 1) {
448                                     sb.append(' ');
449                                 }
450                             } else if (line != 0) {
451                                 // we don't want to preserve the leading spaces for the first line
452
for (int j = 0, max2 = leadingWhitespaces; j < max2; j++) {
453                                     sb.append(' ');
454                                 }
455                             }
456                             leadingWhitespaces = 0;
457                             sb.append(c);
458                         } else if (c != '*' || i > starsIndex) {
459                             sb.append(c);
460                         }
461                 }
462             }
463
464             // append a newline at the end of each line except the last, even if we skipped the last entirely
465
int end = lines.length - 1;
466             if (line < end) {
467                 sb.append('\n');
468             } else if (preserveLineSeparator && line == end) {
469                 sb.append('\n');
470             }
471         }
472         return sb.toString();
473     }
474
475     /**
476      * Returns the index of the last leading stars on this line, -1 if none.
477      *
478      * @param line the given line
479      * @return the computed index
480      */

481     private static int getStars(char[] line) {
482         loop: for (int i = 0, max = line.length; i < max; i++) {
483             char c = line[i];
484             if (!Character.isWhitespace(c)) {
485                 if (c == '*') {
486                     // only whitespaces before the first star
487
// consume all stars and return the last index
488
for (int j = i + 1; j < max; j++) {
489                         if (line[j] != '*') {
490                             return j;
491                         }
492                     }
493                     return max - 1;
494                 }
495                 // no need to continue
496
break loop;
497             }
498         }
499         return -1;
500     }
501     /**
502      * @return all the annotation instance's explicitly set values, plus default values
503      * for all the annotation members that are not explicitly set but that have
504      * defaults. By comparison, {@link AnnotationMirror#getElementValues()} only
505      * returns the explicitly set values.
506      * @see javax.lang.model.util.Elements#getElementValuesWithDefaults(javax.lang.model.element.AnnotationMirror)
507      */

508     @Override JavaDoc
509     public Map JavaDoc<? extends ExecutableElement, ? extends AnnotationValue> getElementValuesWithDefaults(
510             AnnotationMirror a) {
511         return ((AnnotationMirrorImpl)a).getElementValuesWithDefaults();
512     }
513
514     /* (non-Javadoc)
515      * @see javax.lang.model.util.Elements#getName(java.lang.CharSequence)
516      */

517     @Override JavaDoc
518     public Name getName(CharSequence JavaDoc cs) {
519         return new NameImpl(cs);
520     }
521
522     @Override JavaDoc
523     public PackageElement getPackageElement(CharSequence JavaDoc name) {
524         LookupEnvironment le = _env.getLookupEnvironment();
525         if (name.length() == 0) {
526             return new PackageElementImpl(_env, le.defaultPackage);
527         }
528         char[] packageName = name.toString().toCharArray();
529         PackageBinding packageBinding = le.createPackage(CharOperation.splitOn('.', packageName));
530         if (packageBinding == null) {
531             return null;
532         }
533         return new PackageElementImpl(_env, packageBinding);
534     }
535
536     @Override JavaDoc
537     public PackageElement getPackageOf(Element type) {
538         switch(type.getKind()) {
539             case ANNOTATION_TYPE :
540             case CLASS :
541             case ENUM :
542             case INTERFACE :
543                 TypeElementImpl typeElementImpl = (TypeElementImpl) type;
544                 ReferenceBinding referenceBinding = (ReferenceBinding)typeElementImpl._binding;
545                 return (PackageElement) _env.getFactory().newElement(referenceBinding.fPackage);
546             case PACKAGE :
547                 return (PackageElement) type;
548             case CONSTRUCTOR :
549             case METHOD :
550                 ExecutableElementImpl executableElementImpl = (ExecutableElementImpl) type;
551                 MethodBinding methodBinding = (MethodBinding) executableElementImpl._binding;
552                 return (PackageElement) _env.getFactory().newElement(methodBinding.declaringClass.fPackage);
553             case ENUM_CONSTANT :
554             case FIELD :
555                 VariableElementImpl variableElementImpl = (VariableElementImpl) type;
556                 FieldBinding fieldBinding = (FieldBinding) variableElementImpl._binding;
557                 return (PackageElement) _env.getFactory().newElement(fieldBinding.declaringClass.fPackage);
558             case PARAMETER :
559                 variableElementImpl = (VariableElementImpl) type;
560                 LocalVariableBinding localVariableBinding = (LocalVariableBinding) variableElementImpl._binding;
561                 return (PackageElement) _env.getFactory().newElement(localVariableBinding.declaringScope.classScope().referenceContext.binding.fPackage);
562             case EXCEPTION_PARAMETER :
563             case INSTANCE_INIT :
564             case OTHER :
565             case STATIC_INIT :
566             case TYPE_PARAMETER :
567             case LOCAL_VARIABLE :
568                 return null;
569         }
570         // unreachable
571
return null;
572     }
573
574     /* (non-Javadoc)
575      * @see javax.lang.model.util.Elements#getTypeElement(java.lang.CharSequence)
576      */

577     @Override JavaDoc
578     public TypeElement getTypeElement(CharSequence JavaDoc name) {
579         LookupEnvironment le = _env.getLookupEnvironment();
580         final char[][] compoundName = CharOperation.splitOn('.', name.toString().toCharArray());
581         ReferenceBinding binding = le.getType(compoundName);
582         // If we didn't find the binding, maybe it's a nested type;
583
// try finding the top-level type and then working downwards.
584
if (null == binding) {
585             ReferenceBinding topLevelBinding = null;
586             int topLevelSegments = compoundName.length;
587             while (--topLevelSegments > 0) {
588                 char[][] topLevelName = new char[topLevelSegments][];
589                 for (int i = 0; i < topLevelSegments; ++i) {
590                     topLevelName[i] = compoundName[i];
591                 }
592                 topLevelBinding = le.getType(topLevelName);
593                 if (null != topLevelBinding) {
594                     break;
595                 }
596             }
597             if (null == topLevelBinding) {
598                 return null;
599             }
600             binding = topLevelBinding;
601             for (int i = topLevelSegments; null != binding && i < compoundName.length; ++i) {
602                 binding = binding.getMemberType(compoundName[i]);
603             }
604         }
605         if (null == binding) {
606             return null;
607         }
608         return new TypeElementImpl(_env, binding);
609     }
610
611     /* (non-Javadoc)
612      * Element A hides element B if: A and B are both fields, both nested types, or both methods; and
613      * the enclosing element of B is a superclass or superinterface of the enclosing element of A.
614      * See JLS 8.3 (for hiding of fields), 8.4.8.2 (hiding of class methods), and 8.5 (for hiding of member types).
615      * @see javax.lang.model.util.Elements#hides(javax.lang.model.element.Element, javax.lang.model.element.Element)
616      */

617     @Override JavaDoc
618     public boolean hides(Element hider, Element hidden) {
619         if (hidden == null) {
620             // required by API spec
621
throw new NullPointerException JavaDoc();
622         }
623         return ((ElementImpl)hider).hides(hidden);
624     }
625
626     /* (non-Javadoc)
627      * @see javax.lang.model.util.Elements#isDeprecated(javax.lang.model.element.Element)
628      */

629     @Override JavaDoc
630     public boolean isDeprecated(Element e) {
631         if (!(e instanceof ElementImpl)) {
632             return false;
633         }
634         return (((ElementImpl)e)._binding.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0;
635     }
636
637     /* (non-Javadoc)
638      * See JLS 8.4.8.1 for discussion of hiding of methods
639      * @see javax.lang.model.util.Elements#overrides(javax.lang.model.element.ExecutableElement, javax.lang.model.element.ExecutableElement, javax.lang.model.element.TypeElement)
640      */

641     @Override JavaDoc
642     public boolean overrides(ExecutableElement overrider, ExecutableElement overridden,
643             TypeElement type) {
644         if (overridden == null || type == null) {
645             throw new NullPointerException JavaDoc();
646         }
647         return ((ExecutableElementImpl)overrider).overrides(overridden, type);
648     }
649
650     /* (non-Javadoc)
651      * @see javax.lang.model.util.Elements#printElements(java.io.Writer, javax.lang.model.element.Element[])
652      */

653     @Override JavaDoc
654     public void printElements(Writer JavaDoc w, Element... elements) {
655         String JavaDoc lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$
656
for (Element element : elements) {
657             try {
658                 w.write(element.toString());
659                 w.write(lineSeparator);
660             } catch (IOException JavaDoc e) {
661                 // ignore
662
}
663         }
664         try {
665             w.flush();
666         } catch (IOException JavaDoc e) {
667             // ignore
668
}
669     }
670
671 }
672
Popular Tags