This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 201254
Collapse All | Expand All

(-)a/java.source/apichanges.xml (+14 lines)
Lines 108-113 Link Here
108
    <!-- ACTUAL CHANGES BEGIN HERE: -->
108
    <!-- ACTUAL CHANGES BEGIN HERE: -->
109
109
110
    <changes>
110
    <changes>
111
        <change id="OrganizeImports">
112
             <api name="general"/>
113
             <summary>Added <code>GeneratorUtilities.addImports</code> and several methods to <code>CodeStyle</code> to support organizing imports.</summary>
114
             <version major="0" minor="85"/>
115
             <date day="25" month="8" year="2011"/>
116
             <author login="dbalek"/>
117
             <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
118
             <description>
119
                 Added <code>GeneratorUtilities.addImports</code> method to add import statements for given elements to a compilation unit
120
                 in a way that complies with the rules specified in <code>CodeStyle</code>. Added <code>CodeStyle.importInnerClasses</code>,
121
                 <code>CodeStyle.getImportGroups</code>, and <code>CodeStyle.separateImportGroups</code> to specify the rules.
122
             </description>
123
             <issue number="201254"/>
124
        </change>
111
        <change id="ElementHandle-jvm-signature">
125
        <change id="ElementHandle-jvm-signature">
112
             <api name="general"/>
126
             <api name="general"/>
113
             <summary>Added SourceUtils.getJVMSignature to obtain the JVM signature for an ElementHandle</summary>
127
             <summary>Added SourceUtils.getJVMSignature to obtain the JVM signature for an ElementHandle</summary>
(-)a/java.source/nbproject/project.properties (-1 / +1 lines)
Lines 46-52 Link Here
46
javadoc.title=Java Source
46
javadoc.title=Java Source
47
javadoc.arch=${basedir}/arch.xml
47
javadoc.arch=${basedir}/arch.xml
48
javadoc.apichanges=${basedir}/apichanges.xml
48
javadoc.apichanges=${basedir}/apichanges.xml
49
spec.version.base=0.84.0
49
spec.version.base=0.85.0
50
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/javac-api-nb-7.0-b07.jar
50
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/javac-api-nb-7.0-b07.jar
51
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
51
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
52
    ${o.n.core.dir}/lib/boot.jar:\
52
    ${o.n.core.dir}/lib/boot.jar:\
(-)a/java.source/src/org/netbeans/api/java/source/CodeStyle.java (-1 / +77 lines)
Lines 755-760 Link Here
755
        return preferences.getBoolean(useFQNs, getDefaultAsBoolean(useFQNs));
755
        return preferences.getBoolean(useFQNs, getDefaultAsBoolean(useFQNs));
756
    }
756
    }
757
757
758
    public boolean importInnerClasses() {
759
        return preferences.getBoolean(importInnerClasses, getDefaultAsBoolean(importInnerClasses));
760
    }
761
758
    public int countForUsingStarImport() {
762
    public int countForUsingStarImport() {
759
        return preferences.getInt(countForUsingStarImport, getDefaultAsInt(countForUsingStarImport));
763
        return preferences.getInt(countForUsingStarImport, getDefaultAsInt(countForUsingStarImport));
760
    }
764
    }
Lines 764-770 Link Here
764
    }
768
    }
765
769
766
    public String[] getPackagesForStarImport() {
770
    public String[] getPackagesForStarImport() {
767
        return null;
771
        String pkgs = preferences.get(packagesForStarImport, getDefaultAsString(packagesForStarImport));
772
        if (pkgs == null || pkgs.length() == 0) {
773
            return new String[0];
774
        } else {
775
            return pkgs.trim().split("\\s*[,;]\\s*"); //NOI18N
776
        }
777
    }
778
    
779
    public ImportGroups getImportGroups() {
780
        return new ImportGroups(preferences.get(importGroupsOrder, getDefaultAsString(importGroupsOrder)));
781
    }
782
783
    public boolean separateImportGroups() {
784
        return preferences.getBoolean(separateImportGroups, getDefaultAsBoolean(separateImportGroups));
768
    }
785
    }
769
786
770
    // Comments -----------------------------------------------------------------
787
    // Comments -----------------------------------------------------------------
Lines 838-847 Link Here
838
        WRAP_NEVER
855
        WRAP_NEVER
839
    }
856
    }
840
    
857
    
858
    public static final class ImportGroups {
859
860
        private Info[] infos;
861
        private boolean separateStatic;
862
        private int defaultGroupId;
863
864
        private ImportGroups(String groups) {
865
            if (groups == null || groups.length() == 0) {
866
                this.infos = new Info[0];
867
                this.defaultGroupId = 0;
868
            } else {
869
                String[] order = groups.trim().split("\\s*[,;]\\s*"); //NOI18N
870
                this.infos = new Info[order.length - 1];
871
                int i = 0;
872
                for (String imp : order) {
873
                    Info info = new Info();
874
                    if (imp.startsWith("static ")) { //NOI18N
875
                        info.isStatic = true;
876
                        this.separateStatic = true;
877
                        imp = imp.substring(7);
878
                    }
879
                    if (imp.endsWith("*")) { //NOI18N
880
                        info.prefix = imp.substring(0, imp.length() - 1);
881
                    }
882
                    if (info.prefix.length() == 0) {
883
                        this.defaultGroupId = i * 2 + 1;
884
                    } else {
885
                        this.infos[i++] = info;
886
                    }
887
                }
888
            }
889
        }
890
891
        public int getGroupId(String name) {
892
            for (int i = 0; i < infos.length; i++) {
893
                Info info = infos[i];
894
                if (separateStatic ? info.check(name, false) : info.check(name)) {
895
                    return i * 2;
896
                }
897
            }
898
            return defaultGroupId;
899
        }
900
901
        private static final class Info {
902
903
            private boolean isStatic;
904
            private String prefix;
905
906
            private boolean check(String s) {
907
                return prefix.charAt(prefix.length() - 1) == '.' ? s.startsWith(prefix) : s.equals(prefix);
908
            }
909
910
            private boolean check(String s, boolean b) {
911
                return isStatic == b && check(s);
912
            }
913
        }
914
    }
915
841
    // Communication with non public packages ----------------------------------
916
    // Communication with non public packages ----------------------------------
842
    
917
    
843
    private static class Producer implements FmtOptions.CodeStyleProducer {
918
    private static class Producer implements FmtOptions.CodeStyleProducer {
844
919
920
        @Override
845
        public CodeStyle create(Preferences preferences) {
921
        public CodeStyle create(Preferences preferences) {
846
            return new CodeStyle(preferences);
922
            return new CodeStyle(preferences);
847
        }
923
        }
(-)a/java.source/src/org/netbeans/api/java/source/GeneratorUtilities.java (-4 / +298 lines)
Lines 49-59 Link Here
49
import com.sun.source.tree.ClassTree;
49
import com.sun.source.tree.ClassTree;
50
import com.sun.source.tree.CompilationUnitTree;
50
import com.sun.source.tree.CompilationUnitTree;
51
import com.sun.source.tree.ExpressionTree;
51
import com.sun.source.tree.ExpressionTree;
52
import com.sun.source.tree.IdentifierTree;
53
import com.sun.source.tree.ImportTree;
54
import com.sun.source.tree.MemberSelectTree;
52
import com.sun.source.tree.MethodInvocationTree;
55
import com.sun.source.tree.MethodInvocationTree;
53
import com.sun.source.tree.MethodTree;
56
import com.sun.source.tree.MethodTree;
54
import com.sun.source.tree.ModifiersTree;
57
import com.sun.source.tree.ModifiersTree;
55
import com.sun.source.tree.NewClassTree;
58
import com.sun.source.tree.NewClassTree;
56
import com.sun.source.tree.PrimitiveTypeTree;
59
import com.sun.source.tree.PrimitiveTypeTree;
60
import com.sun.source.tree.Scope;
57
import com.sun.source.tree.StatementTree;
61
import com.sun.source.tree.StatementTree;
58
import com.sun.source.tree.Tree;
62
import com.sun.source.tree.Tree;
59
import com.sun.source.tree.Tree.Kind;
63
import com.sun.source.tree.Tree.Kind;
Lines 62-69 Link Here
62
import com.sun.source.tree.WildcardTree;
66
import com.sun.source.tree.WildcardTree;
63
import com.sun.source.util.SourcePositions;
67
import com.sun.source.util.SourcePositions;
64
import com.sun.source.util.TreePath;
68
import com.sun.source.util.TreePath;
69
import com.sun.source.util.TreePathScanner;
65
import com.sun.source.util.TreeScanner;
70
import com.sun.source.util.TreeScanner;
71
import com.sun.source.util.Trees;
66
import com.sun.tools.javac.code.Flags;
72
import com.sun.tools.javac.code.Flags;
73
import com.sun.tools.javac.code.Scope.Entry;
67
import com.sun.tools.javac.code.Symbol.ClassSymbol;
74
import com.sun.tools.javac.code.Symbol.ClassSymbol;
68
import com.sun.tools.javac.code.Type;
75
import com.sun.tools.javac.code.Type;
69
import com.sun.tools.javac.tree.JCTree;
76
import com.sun.tools.javac.tree.JCTree;
Lines 72-91 Link Here
72
import java.io.IOException;
79
import java.io.IOException;
73
import java.util.ArrayList;
80
import java.util.ArrayList;
74
import java.util.Collections;
81
import java.util.Collections;
82
import java.util.Comparator;
75
import java.util.EnumSet;
83
import java.util.EnumSet;
84
import java.util.HashMap;
85
import java.util.HashSet;
76
import java.util.IdentityHashMap;
86
import java.util.IdentityHashMap;
77
import java.util.Iterator;
87
import java.util.Iterator;
78
import java.util.LinkedList;
88
import java.util.LinkedList;
79
import java.util.List;
89
import java.util.List;
80
import java.util.Map;
90
import java.util.Map;
81
import java.util.Set;
91
import java.util.Set;
92
82
import javax.lang.model.SourceVersion;
93
import javax.lang.model.SourceVersion;
83
import javax.lang.model.element.Element;
94
import javax.lang.model.element.Element;
84
85
import javax.lang.model.element.ElementKind;
95
import javax.lang.model.element.ElementKind;
86
import javax.lang.model.element.ExecutableElement;
96
import javax.lang.model.element.ExecutableElement;
87
import javax.lang.model.element.Modifier;
97
import javax.lang.model.element.Modifier;
88
import javax.lang.model.element.Name;
98
import javax.lang.model.element.Name;
99
import javax.lang.model.element.PackageElement;
89
import javax.lang.model.element.TypeElement;
100
import javax.lang.model.element.TypeElement;
90
import javax.lang.model.element.TypeParameterElement;
101
import javax.lang.model.element.TypeParameterElement;
91
import javax.lang.model.element.VariableElement;
102
import javax.lang.model.element.VariableElement;
Lines 95-100 Link Here
95
import javax.lang.model.type.TypeMirror;
106
import javax.lang.model.type.TypeMirror;
96
import javax.lang.model.type.TypeVariable;
107
import javax.lang.model.type.TypeVariable;
97
import javax.lang.model.type.WildcardType;
108
import javax.lang.model.type.WildcardType;
109
import javax.lang.model.util.Elements;
98
import javax.lang.model.util.Types;
110
import javax.lang.model.util.Types;
99
import javax.swing.text.Document;
111
import javax.swing.text.Document;
100
112
Lines 165-171 Link Here
165
        Tree lastMember = null;
177
        Tree lastMember = null;
166
        for (Tree tree : clazz.getMembers()) {
178
        for (Tree tree : clazz.getMembers()) {
167
            TreePath path = TreePath.getPath(compilationUnit, tree);
179
            TreePath path = TreePath.getPath(compilationUnit, tree);
168
            if ((path == null || !utils.isSynthetic(path)) && ClassMemberComparator.compare(member, tree) < 0) {
180
            if ((path == null || !utils.isSynthetic(path)) && CLASS_MEMBER_COMPARATOR.compare(member, tree) < 0) {
169
                if (gdoc == null)
181
                if (gdoc == null)
170
                    break;
182
                    break;
171
                int pos = (int)(lastMember != null ? sp.getEndPosition(compilationUnit, lastMember) : sp.getStartPosition( compilationUnit,clazz));
183
                int pos = (int)(lastMember != null ? sp.getEndPosition(compilationUnit, lastMember) : sp.getStartPosition( compilationUnit,clazz));
Lines 512-517 Link Here
512
        BlockTree body = make.Block(Collections.singletonList(make.ExpressionStatement(make.Assignment(make.MemberSelect(isStatic? make.Identifier(clazz.getSimpleName()) : make.Identifier("this"), name), make.Identifier(name)))), false); //NOI18N
524
        BlockTree body = make.Block(Collections.singletonList(make.ExpressionStatement(make.Assignment(make.MemberSelect(isStatic? make.Identifier(clazz.getSimpleName()) : make.Identifier("this"), name), make.Identifier(name)))), false); //NOI18N
513
        return make.Method(make.Modifiers(mods), sb, make.Type(copy.getTypes().getNoType(TypeKind.VOID)), Collections.<TypeParameterTree>emptyList(), params, Collections.<ExpressionTree>emptyList(), body, null);
525
        return make.Method(make.Modifiers(mods), sb, make.Type(copy.getTypes().getNoType(TypeKind.VOID)), Collections.<TypeParameterTree>emptyList(), params, Collections.<ExpressionTree>emptyList(), body, null);
514
    }
526
    }
527
    
528
    /**
529
     * Adds import statements for given elements to a compilation unit. The import section of the
530
     * given compilation unit is modified according to the rules specified in the {@link CodeStyle}.
531
     *
532
     * @param cut the compilation unit to insert imports to
533
     * @param toImport the elements to import. 
534
     * @return the modified compilation unit
535
     * @since 0.85
536
     */
537
    public CompilationUnitTree addImports(CompilationUnitTree cut, Set<Element> toImport) {
538
        assert cut != null && toImport != null && toImport.size() > 0;
539
540
        ArrayList<Element> elementsToImport = new ArrayList<Element>(toImport);
541
542
        Trees trees = copy.getTrees();
543
        Elements elements = copy.getElements();
544
        ElementUtilities elementUtilities = copy.getElementUtilities();
545
        CodeStyle cs = CodeStyle.getDefault(copy.getFileObject());
546
        
547
        // check weather any conversions to star imports are needed
548
        int treshold = cs.countForUsingStarImport();
549
        int staticTreshold = cs.countForUsingStaticStarImport();        
550
        Map<PackageElement, Integer> pkgCounts = new HashMap<PackageElement, Integer>();
551
        pkgCounts.put(elements.getPackageElement("java.lang"), -2); //NOI18N
552
        pkgCounts.put((PackageElement)trees.getElement(TreePath.getPath(cut, cut.getPackageName())), -2);
553
        Map<TypeElement, Integer> typeCounts = new HashMap<TypeElement, Integer>();
554
        Scope scope = trees.getScope(new TreePath(cut));
555
        for (Element e : elementsToImport) {
556
            boolean isStatic = false;
557
            Element el = null;
558
            switch (e.getKind()) {
559
                case PACKAGE:
560
                    el = e;
561
                    break;
562
                case ANNOTATION_TYPE:
563
                case CLASS:
564
                case ENUM:
565
                case INTERFACE:
566
                    if (e.getEnclosingElement().getKind() == ElementKind.PACKAGE)
567
                        el = e.getEnclosingElement();
568
                    break;
569
                case METHOD:
570
                case ENUM_CONSTANT:
571
                case FIELD:
572
                    isStatic = true;
573
                    el = e.getEnclosingElement();
574
                    assert e.getModifiers().contains(Modifier.STATIC) && trees.isAccessible(scope, e, (DeclaredType)el.asType()) : "Only static accessible members could be imported"; //NOI18N
575
                    break;
576
                default:
577
                    assert false : "Illegal element kind: " + e.getKind(); //NOI18N
578
            }
579
            if (el != null) {
580
                Integer cnt = isStatic ? typeCounts.get((TypeElement)el) : pkgCounts.get((PackageElement)el);
581
                if (cnt == null)
582
                    cnt = 0;
583
                if (el == e) {
584
                    cnt = -1;
585
                } else if (cnt >= 0) {
586
                    cnt++;
587
                    if (isStatic ? cnt >= staticTreshold : cnt >= treshold)
588
                        cnt = -1;
589
                }
590
                if (isStatic) {
591
                    typeCounts.put((TypeElement)el, cnt);
592
                } else {
593
                    pkgCounts.put((PackageElement)el, cnt);
594
                }
595
            }
596
        }
597
        List<ImportTree> imports = new ArrayList<ImportTree>(cut.getImports());
598
        for (ImportTree imp : imports) {
599
            Element e = getImportedElement(cut, imp, trees);
600
            Element el = imp.isStatic()
601
                    ? e.getKind().isClass() || e.getKind().isInterface() ? e : elementUtilities.enclosingTypeElement(e)
602
                    : e.getKind() == ElementKind.PACKAGE ? e : (e.getKind().isClass() || e.getKind().isInterface()) && e.getEnclosingElement().getKind() == ElementKind.PACKAGE ? e.getEnclosingElement() : null;
603
            if (el != null) {
604
                Integer cnt = imp.isStatic() ? typeCounts.get((TypeElement)el) : pkgCounts.get((PackageElement)el);
605
                if (cnt != null) {
606
                    if (el == e) {
607
                        cnt = -2;
608
                    } else if (cnt >= 0) {
609
                        cnt++;
610
                        if (imp.isStatic() ? cnt >= staticTreshold : cnt >= treshold)
611
                            cnt = -1;
612
                    }
613
                    if (imp.isStatic()) {
614
                        typeCounts.put((TypeElement)el, cnt);
615
                    } else {
616
                        pkgCounts.put((PackageElement)el, cnt);
617
                    }
618
                }
619
            }
620
        }
621
        
622
        // check for possible name clashes originating from adding the package imports
623
        Set<Element> explicitNamedImports = new HashSet<Element>();
624
        Map<Name, TypeElement> usedTypes = null;
625
        JCCompilationUnit unit = (JCCompilationUnit) cut;
626
        if (unit.starImportScope != null) {
627
            for (Map.Entry<PackageElement, Integer> entry : pkgCounts.entrySet()) {
628
                if (entry.getValue() == -1) {
629
                    for (Element element : entry.getKey().getEnclosedElements()) {
630
                        if (element.getKind().isClass() || element.getKind().isInterface()) {
631
                            Entry starEntry = unit.starImportScope.lookup((com.sun.tools.javac.util.Name)element.getSimpleName());
632
                            if (starEntry.scope != null) {
633
                                if (usedTypes == null) {
634
                                    usedTypes = getUsedTypes(cut, trees);
635
                                }
636
                                TypeElement te = usedTypes.get(element.getSimpleName());
637
                                if (te != null) {
638
                                    elementsToImport.add(te);
639
                                    explicitNamedImports.add(te);
640
                                }
641
                            }
642
                        }
643
                    }
644
                }
645
            }
646
        }
647
648
        // sort the elements to import
649
        ImportsComparator comparator = new ImportsComparator(cs, elements);
650
        Collections.sort(elementsToImport, comparator);
651
        
652
        // merge the elements to import with the existing import statemetns
653
        TreeMaker make = copy.getTreeMaker();
654
        int currentToImport = elementsToImport.size() - 1;
655
        int currentExisting = imports.size() - 1;
656
        while (currentToImport >= 0) {
657
            Element currentToImportElement = elementsToImport.get(currentToImport);
658
            boolean isStatic = false;
659
            Element el = null;
660
            switch (currentToImportElement.getKind()) {
661
                case PACKAGE:
662
                    el = currentToImportElement;
663
                    break;
664
                case ANNOTATION_TYPE:
665
                case CLASS:
666
                case ENUM:
667
                case INTERFACE:
668
                    if (currentToImportElement.getEnclosingElement().getKind() == ElementKind.PACKAGE)
669
                        el = currentToImportElement.getEnclosingElement();
670
                    break;
671
                case METHOD:
672
                case ENUM_CONSTANT:
673
                case FIELD:
674
                    isStatic = true;
675
                    el = currentToImportElement.getEnclosingElement();
676
                    break;
677
            }
678
            Integer cnt = el == null ? Integer.valueOf(0) : isStatic ? typeCounts.get((TypeElement)el) : pkgCounts.get((PackageElement)el);
679
            if (explicitNamedImports.contains(currentToImportElement))
680
                cnt = 0;
681
            if (cnt == -2) {
682
                currentToImport--;
683
            } else {
684
                if (cnt == -1) {
685
                    currentToImportElement = el;
686
                    if (isStatic) {
687
                        typeCounts.put((TypeElement)el, -2);
688
                    } else {
689
                        pkgCounts.put((PackageElement)el, -2);
690
                    }
691
                }
692
                boolean isStar = currentToImportElement.getKind() == ElementKind.PACKAGE
693
                        || isStatic && (currentToImportElement.getKind().isClass() || currentToImportElement.getKind().isInterface());
694
                while (currentExisting >= 0) {
695
                    ImportTree imp = imports.get(currentExisting);
696
                    Element impElement = getImportedElement(cut, imp, trees);
697
                    el = imp.isStatic()
698
                            ? impElement.getKind().isClass() || impElement.getKind().isInterface() ? impElement : elementUtilities.enclosingTypeElement(impElement)
699
                            : impElement.getKind() == ElementKind.PACKAGE ? impElement : (impElement.getKind().isClass() || impElement.getKind().isInterface()) && impElement.getEnclosingElement().getKind() == ElementKind.PACKAGE ? impElement.getEnclosingElement() : null;
700
                    if (currentToImportElement == impElement || isStar && currentToImportElement == el) {
701
                        imports.remove(currentExisting);                        
702
                    } else if (comparator.compare(currentToImportElement, impElement) > 0) {
703
                        break;
704
                    }
705
                    currentExisting--;
706
                }
707
                ExpressionTree qualIdent = make.QualIdent(currentToImportElement);
708
                if (isStar)
709
                    qualIdent = make.MemberSelect(qualIdent, elements.getName("*")); //NOI18N
710
                imports.add(currentExisting + 1, make.Import(qualIdent, isStatic));
711
                currentToImport--;
712
            }
713
        }
714
        
715
        // return a copy of the unit with changed imports section
716
        return make.CompilationUnit(cut.getPackageAnnotations(), cut.getPackageName(), imports, cut.getTypeDecls(), cut.getSourceFile());
717
    }
515
718
516
    /**
719
    /**
517
     * Take a tree as a parameter, replace resolved fully qualified names with
720
     * Take a tree as a parameter, replace resolved fully qualified names with
Lines 675-684 Link Here
675
878
676
        return copy.getTreeUtilities().translate(result, translate);
879
        return copy.getTreeUtilities().translate(result, translate);
677
    }
880
    }
881
    
882
    private Element getImportedElement(CompilationUnitTree cut, ImportTree imp, Trees trees) {
883
        Tree qualIdent = imp.getQualifiedIdentifier();        
884
        if (qualIdent.getKind() != Tree.Kind.MEMBER_SELECT)
885
            return trees.getElement(TreePath.getPath(cut, qualIdent));
886
        Name name = ((MemberSelectTree)qualIdent).getIdentifier();
887
        if ("*".contentEquals(name)) //NOI18N
888
            return trees.getElement(TreePath.getPath(cut, ((MemberSelectTree)qualIdent).getExpression()));
889
        if (imp.isStatic()) {
890
            Element parent = trees.getElement(TreePath.getPath(cut, ((MemberSelectTree)qualIdent).getExpression()));
891
            if (parent != null && (parent.getKind().isClass() || parent.getKind().isInterface())) {
892
                Scope s = trees.getScope(new TreePath(cut));
893
                for (Element e : parent.getEnclosedElements()) {
894
                    if (name == e.getSimpleName() && e.getModifiers().contains(Modifier.STATIC) && trees.isAccessible(s, e, (DeclaredType)parent.asType()));
895
                        return e;
896
                }
897
                return parent;
898
            }
899
        }
900
        return trees.getElement(TreePath.getPath(cut, qualIdent));
901
    }
902
    
903
    private Map<Name, TypeElement> getUsedTypes(final CompilationUnitTree cut, final Trees trees) {
904
        final Map<Name, TypeElement> map = new HashMap<Name, TypeElement>();
905
        new TreePathScanner<Void, Void>() {
678
906
679
    private static class ClassMemberComparator {
907
            @Override
908
            public Void visitIdentifier(IdentifierTree node, Void p) {
909
                if (!map.containsKey(node.getName())) {
910
                    Element element = trees.getElement(getCurrentPath());
911
                    if (element != null && (element.getKind().isClass() || element.getKind().isInterface())) {
912
                        map.put(node.getName(), (TypeElement) element);
913
                    }
914
                }
915
                return super.visitIdentifier(node, p);
916
            }
680
917
681
        public static int compare(Tree tree1, Tree tree2) {
918
            @Override
919
            public Void visitCompilationUnit(CompilationUnitTree node, Void p) {
920
                scan(node.getPackageAnnotations(), p);
921
                return scan(node.getTypeDecls(), p);
922
            }
923
        }.scan(cut, null);
924
        return map;
925
    }
926
927
    private static class ClassMemberComparator implements Comparator<Tree> {
928
929
        @Override
930
        public int compare(Tree tree1, Tree tree2) {
682
            if (tree1 == tree2)
931
            if (tree1 == tree2)
683
                return 0;
932
                return 0;
684
            return getSortPriority(tree1) - getSortPriority(tree2);
933
            return getSortPriority(tree1) - getSortPriority(tree2);
Lines 715-721 Link Here
715
            return ret;
964
            return ret;
716
        }
965
        }
717
    }
966
    }
967
    
968
    private static ClassMemberComparator CLASS_MEMBER_COMPARATOR = new ClassMemberComparator();
718
969
970
    private static class ImportsComparator implements Comparator<Element> {
971
972
        private CodeStyle.ImportGroups groups;
973
        
974
        private ImportsComparator(CodeStyle cs, Elements elements) {
975
            this.groups = cs.getImportGroups();
976
        }
977
978
        @Override
979
        public int compare(Element e1, Element e2) {
980
            if (e1 == e2)
981
                return 0;
982
            
983
            StringBuilder sb1 = new StringBuilder();
984
            if (e1.getKind().isField() || e1.getKind() == ElementKind.METHOD) {
985
                sb1.append('.').append(e1.getSimpleName());
986
                e1 = e1.getEnclosingElement();                
987
            }
988
            if (e1.getKind().isClass() || e1.getKind().isInterface()) {
989
                sb1.insert(0, ((TypeElement)e1).getQualifiedName());
990
            } else if (e1.getKind() == ElementKind.PACKAGE) {
991
                sb1.insert(0, ((PackageElement)e1).getQualifiedName());
992
            }
993
            String s1 = sb1.toString();
994
                
995
            StringBuilder sb2 = new StringBuilder();
996
            if (e2.getKind().isField() || e2.getKind() == ElementKind.METHOD) {
997
                sb2.append('.').append(e2.getSimpleName());
998
                e2 = e2.getEnclosingElement();
999
            }
1000
            if (e2.getKind().isClass() || e2.getKind().isInterface()) {
1001
                sb2.insert(0, ((TypeElement)e2).getQualifiedName());
1002
            } else if (e2.getKind() == ElementKind.PACKAGE) {
1003
                sb2.insert(0, ((PackageElement)e2).getQualifiedName());
1004
            }
1005
            String s2 = sb2.toString();
1006
1007
            int bal = groups.getGroupId(s1) - groups.getGroupId(s2);
1008
1009
            return bal == 0 ? s1.compareTo(s2) : bal;
1010
        }
1011
    }
1012
    
719
    /**
1013
    /**
720
     * Tags first method in the list, in order to select it later inside editor
1014
     * Tags first method in the list, in order to select it later inside editor
721
     * @param methods list of methods to be implemented/overriden
1015
     * @param methods list of methods to be implemented/overriden

Return to bug 201254