KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > editor > overridden > IsOverriddenAnnotationHandler


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.java.editor.overridden;
21
22 import com.sun.source.tree.CompilationUnitTree;
23 import com.sun.source.tree.Tree;
24 import java.io.IOException JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import java.util.EnumSet JavaDoc;
32 import java.util.LinkedList JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.logging.Level JavaDoc;
37 import java.util.logging.Logger JavaDoc;
38 import javax.lang.model.element.Element;
39 import javax.lang.model.element.ExecutableElement;
40 import javax.lang.model.element.Modifier;
41 import javax.lang.model.element.Name;
42 import javax.lang.model.element.TypeElement;
43 import javax.lang.model.type.DeclaredType;
44 import javax.lang.model.type.TypeKind;
45 import javax.lang.model.type.TypeMirror;
46 import javax.lang.model.util.ElementFilter;
47 import javax.swing.text.BadLocationException JavaDoc;
48 import javax.swing.text.Position JavaDoc;
49 import javax.swing.text.StyledDocument JavaDoc;
50 import org.netbeans.api.java.classpath.ClassPath;
51 import org.netbeans.api.java.classpath.ClassPath;
52 import org.netbeans.api.java.classpath.ClassPath.Entry;
53 import org.netbeans.api.java.queries.SourceForBinaryQuery;
54 import org.netbeans.api.java.source.CancellableTask;
55 import org.netbeans.api.java.source.ClassIndex.SearchKind;
56 import org.netbeans.api.java.source.ClasspathInfo;
57 import org.netbeans.api.java.source.CompilationController;
58 import org.netbeans.api.java.source.CompilationInfo;
59 import org.netbeans.api.java.source.ElementHandle;
60 import org.netbeans.api.java.source.JavaSource;
61 import org.netbeans.api.java.source.SourceUtils;
62 import org.netbeans.api.java.source.ClassIndex;
63 import org.netbeans.api.timers.TimesCollector;
64 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
65 import org.openide.ErrorManager;
66 import org.openide.cookies.EditorCookie;
67 import org.openide.filesystems.FileObject;
68 import org.openide.filesystems.FileUtil;
69 import org.openide.loaders.DataObject;
70 import org.openide.text.NbDocument;
71 import org.openide.util.RequestProcessor;
72 import org.openide.util.TopologicalSortException;
73 import org.openide.util.Utilities;
74
75
76 /**
77  *
78  * @author Jan Lahoda
79  */

80 public class IsOverriddenAnnotationHandler implements CancellableTask<CompilationInfo> {
81     
82     private static final boolean enableReverseLookups = Boolean.getBoolean("org.netbeans.java.editor.enableReverseLookups");
83     static final Logger JavaDoc LOG = Logger.getLogger(IsOverriddenAnnotationHandler.class.getName());
84
85     private FileObject file;
86     
87     IsOverriddenAnnotationHandler(FileObject file) {
88         this.file = file;
89         
90         TimesCollector.getDefault().reportReference(file, IsOverriddenAnnotationHandler.class.getName(), "[M] IsOverriddenAnnotationHandler", this);
91     }
92     
93     public StyledDocument JavaDoc getDocument() {
94         try {
95             DataObject d = DataObject.find(file);
96             EditorCookie ec = d.getCookie(EditorCookie.class);
97             
98             if (ec == null)
99                 return null;
100             
101             return ec.getDocument();
102         } catch (IOException JavaDoc e) {
103             LOG.log(Level.INFO, "Cannot find DataObject for file: " + FileUtil.getFileDisplayName(file), e);
104             return null;
105         }
106     }
107     
108     private IsOverriddenVisitor visitor;
109     
110     public void run(CompilationInfo info) {
111         resume();
112         
113         StyledDocument JavaDoc doc = getDocument();
114         
115         if (doc == null) {
116             LOG.log(Level.INFO, "Cannot get document!");
117             return ;
118         }
119         
120         long startTime = System.currentTimeMillis();
121         
122         try {
123             List JavaDoc<IsOverriddenAnnotation> annotations = process(info, doc);
124             
125             if (annotations == null) {
126                 //cancelled:
127
return ;
128             }
129             
130             newAnnotations(annotations);
131         } finally {
132             synchronized (this) {
133                 visitor = null;
134             }
135             
136             TimesCollector.getDefault().reportTime(file, "is-overridden", "Overridden in", System.currentTimeMillis() - startTime);
137         }
138     }
139     
140     private FileObject findSourceRoot() {
141         final ClassPath cp = ClassPath.getClassPath(file, ClassPath.SOURCE);
142         if (cp != null) {
143             for (FileObject root : cp.getRoots()) {
144                 if (FileUtil.isParentOf(root, file))
145                     return root;
146             }
147         }
148         //Null is a valid value for files which have no source path (default filesystem).
149
return null;
150     }
151     
152     //temporary hack:
153
private synchronized Set JavaDoc<FileObject> findReverseSourceRoots(final FileObject thisSourceRoot, final FileObject thisFile) {
154         final Object JavaDoc o = new Object JavaDoc();
155         final Set JavaDoc<FileObject> reverseSourceRoots = new HashSet JavaDoc<FileObject>();
156         
157         RequestProcessor.getDefault().post(new Runnable JavaDoc() {
158             public void run() {
159                 long startTime = System.currentTimeMillis();
160                 Set JavaDoc<FileObject> reverseSourceRootsInt = new HashSet JavaDoc<FileObject>(ReverseSourceRootsLookup.reverseSourceRootsLookup(thisSourceRoot));
161                 long endTime = System.currentTimeMillis();
162                 
163                 TimesCollector.getDefault().reportTime(thisFile, "findReverseSourceRoots", "Find Reverse Source Roots", endTime - startTime);
164                 
165                 synchronized (o) {
166                     reverseSourceRoots.addAll(reverseSourceRootsInt);
167                 }
168                 
169                 wakeUp();
170             }
171         });
172         
173         try {
174             wait();
175         } catch (InterruptedException JavaDoc ex) {
176             ErrorManager.getDefault().notify(ex);
177         }
178         
179         return reverseSourceRoots;
180     }
181     
182     public static AnnotationType detectOverrides(CompilationInfo info, TypeElement type, ExecutableElement ee, List JavaDoc<ElementDescription> result) {
183         final Map JavaDoc<Name, List JavaDoc<ExecutableElement>> name2Method = new HashMap JavaDoc<Name, List JavaDoc<ExecutableElement>>();
184         
185         sortOutMethods(info, name2Method, type, false);
186         
187         List JavaDoc<ExecutableElement> lee = name2Method.get(ee.getSimpleName());
188         
189         if (lee == null || lee.isEmpty()) {
190             return null;
191         }
192         
193         Set JavaDoc<ExecutableElement> seenMethods = new HashSet JavaDoc<ExecutableElement>();
194         
195         for (ExecutableElement overridee : lee) {
196             if (info.getElements().overrides(ee, overridee, SourceUtils.getEnclosingTypeElement(ee))) {
197                 if (seenMethods.add(overridee)) {
198                     result.add(new ElementDescription(info, overridee));
199                 }
200             }
201         }
202         
203         if (!result.isEmpty()) {
204             for (ElementDescription ed : result) {
205                 if (!ed.getModifiers().contains(Modifier.ABSTRACT)) {
206                     return AnnotationType.OVERRIDES;
207                 }
208             }
209             
210             return AnnotationType.IMPLEMENTS;
211         }
212         
213         return null;
214     }
215     
216     List JavaDoc<IsOverriddenAnnotation> process(CompilationInfo info, final StyledDocument JavaDoc doc) {
217         IsOverriddenVisitor v;
218         
219         synchronized (this) {
220             if (isCanceled())
221                 return null;
222             
223             v = visitor = new IsOverriddenVisitor(doc, info);
224         }
225         
226         CompilationUnitTree unit = info.getCompilationUnit();
227         
228         long startTime1 = System.currentTimeMillis();
229         
230         v.scan(unit, null);
231         
232         long endTime1 = System.currentTimeMillis();
233         
234         TimesCollector.getDefault().reportTime(file, "overridden-scanner", "Overridden Scanner", endTime1 - startTime1);
235         
236         Set JavaDoc<FileObject> reverseSourceRoots;
237         
238         if (enableReverseLookups) {
239             FileObject thisSourceRoot = findSourceRoot();
240             if (thisSourceRoot == null) {
241                 return null;
242             }
243             
244             reverseSourceRoots = findReverseSourceRoots(thisSourceRoot, info.getFileObject());
245             
246             //XXX: special case "this" source root (no need to create a new JS and load the classes again for it):
247
reverseSourceRoots.add(thisSourceRoot);
248         } else {
249             reverseSourceRoots = null;
250         }
251         
252         LOG.log(Level.FINE, "reverseSourceRoots: {0}", reverseSourceRoots);
253         
254         List JavaDoc<IsOverriddenAnnotation> annotations = new ArrayList JavaDoc<IsOverriddenAnnotation>();
255         
256         for (ElementHandle<TypeElement> td : v.type2Declaration.keySet()) {
257             if (isCanceled())
258                 return null;
259             
260             LOG.log(Level.FINE, "type: {0}", td.getQualifiedName());
261             
262             final Map JavaDoc<Name, List JavaDoc<ExecutableElement>> name2Method = new HashMap JavaDoc<Name, List JavaDoc<ExecutableElement>>();
263             
264             TypeElement resolvedType = td.resolve(info);
265             
266             if (resolvedType == null)
267                 continue;
268             
269             sortOutMethods(info, name2Method, resolvedType, false);
270             
271             for (ElementHandle<ExecutableElement> methodHandle : v.type2Declaration.get(td)) {
272                 if (isCanceled())
273                     return null;
274                 
275                 ExecutableElement ee = methodHandle.resolve(info);
276                 
277                 if (ee == null)
278                     continue;
279                 
280                 if (LOG.isLoggable(Level.FINE)) {
281                     LOG.log(Level.FINE, "method: {0}", ee.toString());
282                 }
283                 
284                 List JavaDoc<ExecutableElement> lee = name2Method.get(ee.getSimpleName());
285                 
286                 if (lee == null || lee.isEmpty()) {
287                     continue;
288                 }
289                 
290                 Set JavaDoc<ExecutableElement> seenMethods = new HashSet JavaDoc<ExecutableElement>();
291                 List JavaDoc<ElementDescription> overrides = new ArrayList JavaDoc<ElementDescription>();
292                 
293                 for (ExecutableElement overridee : lee) {
294                     if (info.getElements().overrides(ee, overridee, SourceUtils.getEnclosingTypeElement(ee))) {
295                         if (seenMethods.add(overridee)) {
296                             overrides.add(new ElementDescription(info, overridee));
297                         }
298                     }
299                 }
300                 
301                 if (!overrides.isEmpty()) {
302                     int position = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), v.declaration2Tree.get(methodHandle));
303                     Position JavaDoc pos = getPosition(doc, position);
304                     
305                     if (pos == null) {
306                         //cannot compute the position, skip
307
continue;
308                     }
309                     
310                     StringBuffer JavaDoc tooltip = new StringBuffer JavaDoc();
311                     boolean wasOverrides = false;
312                     
313                     boolean newline = false;
314                     
315                     for (ElementDescription ed : overrides) {
316                         if (newline) {
317                             tooltip.append("\n");
318                         }
319                         
320                         newline = true;
321                         
322                         if (ed.getModifiers().contains(Modifier.ABSTRACT)) {
323                             tooltip.append("Implements: " + ed.getDisplayName());
324                         } else {
325                             tooltip.append("Overrides: " + ed.getDisplayName());
326                             wasOverrides = true;
327                         }
328                     }
329                     
330                     annotations.add(new IsOverriddenAnnotation(doc, pos, wasOverrides ? AnnotationType.OVERRIDES : AnnotationType.IMPLEMENTS, tooltip.toString(), overrides));
331                 }
332             }
333             
334             if (enableReverseLookups) {
335                 String JavaDoc typeOverridden = null;
336                 AnnotationType typeType = null;
337                 TypeElement resolved = td.resolve(info);
338                 
339                 
340                 if (resolved == null) {
341                     Logger.getLogger("global").log(Level.SEVERE, "IsOverriddenAnnotationHandler: resolved == null!");
342                     continue;
343                 }
344                 
345                 if (resolved.getKind().isInterface()) {
346                     typeOverridden = "Has Implementations";
347                     typeType = AnnotationType.HAS_IMPLEMENTATION;
348                 }
349                 
350                 if (resolved.getKind().isClass()) {
351                     typeOverridden = "Is Overridden:";
352                     typeType = AnnotationType.IS_OVERRIDDEN;
353                 }
354                 
355                 final Map JavaDoc<ElementHandle<ExecutableElement>, List JavaDoc<ElementDescription>> overriding = new HashMap JavaDoc<ElementHandle<ExecutableElement>, List JavaDoc<ElementDescription>>();
356                 final List JavaDoc<ElementDescription> overridingClasses = new ArrayList JavaDoc<ElementDescription>();
357                 
358                 long startTime = System.currentTimeMillis();
359                 long[] classIndexTime = new long[1];
360                 final Map JavaDoc<FileObject, Set JavaDoc<ElementHandle<TypeElement>>> users = computeUsers(reverseSourceRoots, ElementHandle.create(resolved), classIndexTime);
361                 long endTime = System.currentTimeMillis();
362                 
363                 if (users == null) {
364                     return null;
365                 }
366                 
367                 TimesCollector.getDefault().reportTime(file, "overridden-users-classindex", "Overridden Users Class Index", classIndexTime[0]);
368                 TimesCollector.getDefault().reportTime(file, "overridden-users", "Overridden Users", endTime - startTime);
369                 
370                 for (Map.Entry JavaDoc<FileObject, Set JavaDoc<ElementHandle<TypeElement>>> data : users.entrySet()) {
371                     if (isCanceled())
372                         return null;
373                     
374                     findOverriddenAnnotations(data.getKey(), data.getValue(), td, v.type2Declaration.get(td), overriding, overridingClasses);
375                 }
376                 
377                 if (!overridingClasses.isEmpty()) {
378                     Tree t = v.declaration2Class.get(td);
379                     
380                     if (t != null) {
381                         Position JavaDoc pos = getPosition(doc, (int) info.getTrees().getSourcePositions().getStartPosition(unit, t));
382                         
383                         if (pos == null) {
384                             //cannot compute the position, skip
385
continue;
386                         }
387                         
388                         annotations.add(new IsOverriddenAnnotation(doc, pos, typeType, typeOverridden.toString(), overridingClasses));
389                     }
390                 }
391                 
392                 for (ElementHandle<ExecutableElement> original : overriding.keySet()) {
393                     if (isCanceled())
394                         return null;
395                     
396                     Position JavaDoc pos = getPosition(doc, (int) info.getTrees().getSourcePositions().getStartPosition(unit, v.declaration2Tree.get(original)));
397                     
398                     if (pos == null) {
399                         //cannot compute the position, skip
400
continue;
401                     }
402                     
403                     Set JavaDoc<Modifier> mods = original.resolve(info).getModifiers();
404                     String JavaDoc tooltip = null;
405                     
406                     if (mods.contains(Modifier.ABSTRACT)) {
407                         tooltip = "Has Implementations";
408                     } else {
409                         tooltip = "Is Overridden";
410                     }
411                     
412                     IsOverriddenAnnotation ann = new IsOverriddenAnnotation(doc, pos, mods.contains(Modifier.ABSTRACT) ? AnnotationType.HAS_IMPLEMENTATION : AnnotationType.IS_OVERRIDDEN, tooltip, overriding.get(original));
413                     
414                     annotations.add(ann);
415                 }
416             }
417         }
418         
419         if (isCanceled())
420             return null;
421         else
422             return annotations;
423     }
424     
425     private static final ClassPath EMPTY = ClassPathSupport.createClassPath(new URL JavaDoc[0]);
426     
427     private Set JavaDoc<ElementHandle<TypeElement>> computeUsers(FileObject source, Set JavaDoc<ElementHandle<TypeElement>> base, long[] classIndexCumulative) {
428         ClasspathInfo cpinfo = ClasspathInfo.create(/*source);/*/EMPTY, EMPTY, ClassPathSupport.createClassPath(new FileObject[] {source}));
429         
430         long startTime = System.currentTimeMillis();
431         
432         try {
433             List JavaDoc<ElementHandle<TypeElement>> l = new LinkedList JavaDoc<ElementHandle<TypeElement>>(base);
434             Set JavaDoc<ElementHandle<TypeElement>> result = new HashSet JavaDoc<ElementHandle<TypeElement>>();
435             
436             while (!l.isEmpty()) {
437                 ElementHandle<TypeElement> eh = l.remove(0);
438                 
439                 result.add(eh);
440                 
441                 l.addAll(cpinfo.getClassIndex().getElements(eh, Collections.singleton(SearchKind.IMPLEMENTORS), EnumSet.of(ClassIndex.SearchScope.SOURCE)));
442             }
443             return result;
444         } finally {
445             classIndexCumulative[0] += (System.currentTimeMillis() - startTime);
446         }
447     }
448     
449     private Map JavaDoc<FileObject, Set JavaDoc<ElementHandle<TypeElement>>> computeUsers(Set JavaDoc<FileObject> sources, ElementHandle<TypeElement> base, long[] classIndexCumulative) {
450         Map JavaDoc<FileObject, Collection JavaDoc<FileObject>> edges = new HashMap JavaDoc<FileObject, Collection JavaDoc<FileObject>>();
451         Map JavaDoc<FileObject, Collection JavaDoc<FileObject>> dependsOn = new HashMap JavaDoc<FileObject, Collection JavaDoc<FileObject>>();
452         
453         for (FileObject source : sources) {
454             edges.put(source, new ArrayList JavaDoc<FileObject>());
455         }
456         
457         for (FileObject source : sources) {
458             List JavaDoc<FileObject> deps = new ArrayList JavaDoc<FileObject>();
459             
460             dependsOn.put(source, deps);
461             
462             for (Entry entry : ClassPath.getClassPath(source, ClassPath.COMPILE).entries()) { //TODO: should also check BOOT?
463
for (FileObject s : SourceForBinaryQuery.findSourceRoots(entry.getURL()).getRoots()) {
464                     Collection JavaDoc<FileObject> targets = edges.get(s);
465                     
466                     if (targets != null) {
467                         targets.add(source);
468                     }
469                     
470                     deps.add(s);
471                 }
472             }
473         }
474         
475         List JavaDoc<FileObject> sourceRoots = new ArrayList JavaDoc<FileObject>(sources);
476         
477         try {
478             Utilities.topologicalSort(sourceRoots, edges);
479         } catch (TopologicalSortException ex) {
480             LOG.log(Level.WARNING, "internal error", ex);
481             return null;
482         }
483         
484         Map JavaDoc<FileObject, Set JavaDoc<ElementHandle<TypeElement>>> result = new HashMap JavaDoc<FileObject, Set JavaDoc<ElementHandle<TypeElement>>>();
485         
486         for (FileObject file : sourceRoots) {
487             Set JavaDoc<ElementHandle<TypeElement>> baseTypes = new HashSet JavaDoc<ElementHandle<TypeElement>>();
488             
489             baseTypes.add(base);
490             
491             for (FileObject dep : dependsOn.get(file)) {
492                 Set JavaDoc<ElementHandle<TypeElement>> depTypes = result.get(dep);
493                 
494                 if (depTypes != null) {
495                     baseTypes.addAll(depTypes);
496                 }
497             }
498             
499             Set JavaDoc<ElementHandle<TypeElement>> types = computeUsers(file, baseTypes, classIndexCumulative);
500             
501             types.removeAll(baseTypes);
502             
503             result.put(file, types);
504         }
505         
506         return result;
507     }
508     private void findOverriddenAnnotations(
509             FileObject sourceRoot,
510             final Set JavaDoc<ElementHandle<TypeElement>> users,
511             final ElementHandle<TypeElement> originalType,
512             final List JavaDoc<ElementHandle<ExecutableElement>> methods,
513             final Map JavaDoc<ElementHandle<ExecutableElement>, List JavaDoc<ElementDescription>> overriding,
514             final List JavaDoc<ElementDescription> overridingClasses) {
515         ClasspathInfo cpinfo = ClasspathInfo.create(sourceRoot);
516         
517         if (!users.isEmpty()) {
518             JavaSource js = JavaSource.create(cpinfo);
519             
520             try {
521                 js.runUserActionTask(new CancellableTask<CompilationController>() {
522                     public void cancel() {
523                         cancel();
524                     }
525                     public void run(CompilationController controller) throws Exception JavaDoc {
526                         Set JavaDoc<Element> seenElements = new HashSet JavaDoc<Element>();
527                         
528                         for (ElementHandle<TypeElement> typeHandle : users) {
529                             if (isCanceled())
530                                 return;
531                             TypeElement type = typeHandle.resolve(controller);
532                             Element resolvedOriginalType = originalType.resolve(controller);
533                             
534                             if (!seenElements.add(resolvedOriginalType))
535                                 continue;
536                             
537                             if (controller.getTypes().isSubtype(type.asType(), resolvedOriginalType.asType())) {
538                                 overridingClasses.add(new ElementDescription(controller, type));
539                                 
540                                 for (ElementHandle<ExecutableElement> originalMethodHandle : methods) {
541                                     ExecutableElement originalMethod = originalMethodHandle.resolve(controller);
542                                     
543                                     if (originalMethod != null) {
544                                         ExecutableElement overrider = getImplementationOf(controller, originalMethod, type);
545                                         
546                                         if (overrider == null)
547                                             continue;
548                                         
549                                         List JavaDoc<ElementDescription> overriddingMethods = overriding.get(originalMethodHandle);
550                                         
551                                         if (overriddingMethods == null) {
552                                             overriding.put(originalMethodHandle, overriddingMethods = new ArrayList JavaDoc<ElementDescription>());
553                                         }
554                                         
555                                         overriddingMethods.add(new ElementDescription(controller, overrider));
556                                     } else {
557                                         Logger.getLogger("global").log(Level.SEVERE, "IsOverriddenAnnotationHandler: originalMethod == null!");
558                                     }
559                                 }
560                             }
561                         }
562                     }
563                 },true);
564             } catch (Exception JavaDoc e) {
565                 ErrorManager.getDefault().notify(e);
566             }
567         }
568     }
569     
570     private ExecutableElement getImplementationOf(CompilationInfo info, ExecutableElement overridee, TypeElement implementor) {
571         for (ExecutableElement overrider : ElementFilter.methodsIn(implementor.getEnclosedElements())) {
572             if (info.getElements().overrides(overrider, overridee, implementor)) {
573                 return overrider;
574             }
575         }
576         
577         return null;
578     }
579             
580     private boolean canceled;
581     
582     public synchronized void cancel() {
583         canceled = true;
584         
585         if (visitor != null) {
586             visitor.cancel();
587         }
588         
589         wakeUp();
590     }
591     
592     private synchronized void resume() {
593         canceled = false;
594     }
595     
596     private synchronized void wakeUp() {
597         notifyAll();
598     }
599     
600     private synchronized boolean isCanceled() {
601         return canceled;
602     }
603     
604     private void newAnnotations(List JavaDoc<IsOverriddenAnnotation> as) {
605         AnnotationsHolder a = AnnotationsHolder.get(file);
606         
607         if (a != null) {
608             a.setNewAnnotations(as);
609         }
610     }
611
612     private static void sortOutMethods(CompilationInfo info, Map JavaDoc<Name, List JavaDoc<ExecutableElement>> where, Element td, boolean current) {
613         if (current) {
614             Map JavaDoc<Name, List JavaDoc<ExecutableElement>> newlyAdded = new HashMap JavaDoc<Name, List JavaDoc<ExecutableElement>>();
615             
616             OUTTER: for (ExecutableElement ee : ElementFilter.methodsIn(td.getEnclosedElements())) {
617                 Name name = ee.getSimpleName();
618                 List JavaDoc<ExecutableElement> alreadySeen = where.get(name);
619                 
620                 if (alreadySeen != null) {
621                     for (ExecutableElement seen : alreadySeen) {
622                         if (info.getElements().overrides(seen, ee, (TypeElement) seen.getEnclosingElement())) {
623                             continue OUTTER; //a method that overrides this one was already handled, ignore
624
}
625                     }
626                 }
627                 
628                 List JavaDoc<ExecutableElement> lee = newlyAdded.get(name);
629                 
630                 if (lee == null) {
631                     newlyAdded.put(name, lee = new ArrayList JavaDoc<ExecutableElement>());
632                 }
633                 
634                 lee.add(ee);
635             }
636             
637             for (Map.Entry JavaDoc<Name, List JavaDoc<ExecutableElement>> e : newlyAdded.entrySet()) {
638                 List JavaDoc<ExecutableElement> lee = where.get(e.getKey());
639                 
640                 if (lee == null) {
641                     where.put(e.getKey(), e.getValue());
642                 } else {
643                     lee.addAll(e.getValue());
644                 }
645             }
646         }
647         
648         for (TypeMirror superType : info.getTypes().directSupertypes(td.asType())) {
649             if (superType.getKind() == TypeKind.DECLARED) {
650                 sortOutMethods(info, where, ((DeclaredType) superType).asElement(), true);
651             }
652         }
653     }
654     
655     private static Position JavaDoc getPosition(final StyledDocument JavaDoc doc, final int offset) {
656         class Impl implements Runnable JavaDoc {
657             private Position JavaDoc pos;
658             public void run() {
659                 if (offset < 0 || offset >= doc.getLength())
660                     return ;
661                 
662                 try {
663                     pos = doc.createPosition(offset - NbDocument.findLineColumn(doc, offset));
664                 } catch (BadLocationException JavaDoc ex) {
665                     //should not happen?
666
LOG.log(Level.FINE, null, ex);
667                 }
668             }
669         }
670         
671         Impl i = new Impl();
672         
673         doc.render(i);
674         
675         return i.pos;
676     }
677     
678 }
679
Popular Tags