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 / +127 lines)
Lines 747-770 Link Here
747
747
748
    // Imports -----------------------------------------------------------------
748
    // Imports -----------------------------------------------------------------
749
749
750
    /**
751
     * Returns whether to use single class import statements when adding imports.
752
     * @return <code>true</code> if the single class imports should be added,
753
     * <code>false</code> if the 'star' import of the entire package should be added
754
     */
750
    public boolean useSingleClassImport() {
755
    public boolean useSingleClassImport() {
751
        return preferences.getBoolean(useSingleClassImport, getDefaultAsBoolean(useSingleClassImport));
756
        return preferences.getBoolean(useSingleClassImport, getDefaultAsBoolean(useSingleClassImport));
752
    }
757
    }
753
758
759
    /**
760
     * Returns whether to use fully qualified class names when generating code.
761
     * @return <code>true</code> if the fully qualified class name should be generated
762
     * every time the class is used, <code>false</code> if the import statement
763
     * and the simple class name should be used instead.
764
     */
754
    public boolean useFQNs() {
765
    public boolean useFQNs() {
755
        return preferences.getBoolean(useFQNs, getDefaultAsBoolean(useFQNs));
766
        return preferences.getBoolean(useFQNs, getDefaultAsBoolean(useFQNs));
756
    }
767
    }
757
768
769
    /**
770
     * Returns whether to create import statements for the inner classes.
771
     * @since 0.85
772
     */
773
    public boolean importInnerClasses() {
774
        return preferences.getBoolean(importInnerClasses, getDefaultAsBoolean(importInnerClasses));
775
    }
776
777
    /**
778
     * Returns the number of classes that have to be imported from a package
779
     * to convert the single class imports to a 'star' import of the entire package.
780
     */
758
    public int countForUsingStarImport() {
781
    public int countForUsingStarImport() {
759
        return preferences.getInt(countForUsingStarImport, getDefaultAsInt(countForUsingStarImport));
782
        return preferences.getInt(countForUsingStarImport, getDefaultAsInt(countForUsingStarImport));
760
    }
783
    }
761
784
785
    /**
786
     * Returns the number of static members that have to be imported from a class
787
     * to convert the single member static imports to a 'star' import of the entire class.
788
     */
762
    public int countForUsingStaticStarImport() {
789
    public int countForUsingStaticStarImport() {
763
        return preferences.getInt(countForUsingStaticStarImport, getDefaultAsInt(countForUsingStaticStarImport));
790
        return preferences.getInt(countForUsingStaticStarImport, getDefaultAsInt(countForUsingStaticStarImport));
764
    }
791
    }
765
792
793
    /**
794
     * Returns the names of packages that should be always imported using the 'star'
795
     * import statements.
796
     */
766
    public String[] getPackagesForStarImport() {
797
    public String[] getPackagesForStarImport() {
767
        return null;
798
        String pkgs = preferences.get(packagesForStarImport, getDefaultAsString(packagesForStarImport));
799
        if (pkgs == null || pkgs.length() == 0) {
800
            return new String[0];
801
        } else {
802
            return pkgs.trim().split("\\s*[,;]\\s*"); //NOI18N
803
        }
804
    }
805
    
806
    /**
807
     * Returns an information about the desired grouping of import statements.
808
     * Imported classes are grouped as per their packages. 
809
     * @since 0.85
810
     */
811
    public ImportGroups getImportGroups() {
812
        return new ImportGroups(preferences.get(importGroupsOrder, getDefaultAsString(importGroupsOrder)));
813
    }
814
815
    /**
816
     * Returns whether to separate the import groups with blank lines.
817
     * @since 0.85
818
     */
819
    public boolean separateImportGroups() {
820
        return preferences.getBoolean(separateImportGroups, getDefaultAsBoolean(separateImportGroups));
768
    }
821
    }
769
822
770
    // Comments -----------------------------------------------------------------
823
    // Comments -----------------------------------------------------------------
Lines 838-847 Link Here
838
        WRAP_NEVER
891
        WRAP_NEVER
839
    }
892
    }
840
    
893
    
894
    /**
895
     * Provides an information about the desired grouping of import statements,
896
     * including group order.
897
     * @since 0.85
898
     */
899
    public static final class ImportGroups {
900
901
        private Info[] infos;
902
        private boolean separateStatic;
903
        private int defaultGroupId;
904
905
        private ImportGroups(String groups) {
906
            if (groups == null || groups.length() == 0) {
907
                this.infos = new Info[0];
908
                this.defaultGroupId = 0;
909
            } else {
910
                String[] order = groups.trim().split("\\s*[,;]\\s*"); //NOI18N
911
                this.infos = new Info[order.length - 1];
912
                int i = 0;
913
                for (String imp : order) {
914
                    Info info = new Info();
915
                    if (imp.startsWith("static ")) { //NOI18N
916
                        info.isStatic = true;
917
                        this.separateStatic = true;
918
                        imp = imp.substring(7);
919
                    }
920
                    if (imp.endsWith("*")) { //NOI18N
921
                        info.prefix = imp.substring(0, imp.length() - 1);
922
                    }
923
                    if (info.prefix.length() == 0) {
924
                        this.defaultGroupId = i * 2 + 1;
925
                    } else {
926
                        this.infos[i++] = info;
927
                    }
928
                }
929
            }
930
        }
931
932
        /**
933
         * Returns the group number of the given package. Imports with the same
934
         * number form a group. Groups with lower numbers should be positioned
935
         * higher in the import statement list. Imports within a group should
936
         * be sorted alphabetically.
937
         * @param name the package name
938
         * @return the group number
939
         * @since 0.85
940
         */
941
        public int getGroupId(String name) {
942
            for (int i = 0; i < infos.length; i++) {
943
                Info info = infos[i];
944
                if (separateStatic ? info.check(name, false) : info.check(name)) {
945
                    return i * 2;
946
                }
947
            }
948
            return defaultGroupId;
949
        }
950
951
        private static final class Info {
952
953
            private boolean isStatic;
954
            private String prefix;
955
956
            private boolean check(String s) {
957
                return prefix.charAt(prefix.length() - 1) == '.' ? s.startsWith(prefix) : s.equals(prefix);
958
            }
959
960
            private boolean check(String s, boolean b) {
961
                return isStatic == b && check(s);
962
            }
963
        }
964
    }
965
841
    // Communication with non public packages ----------------------------------
966
    // Communication with non public packages ----------------------------------
842
    
967
    
843
    private static class Producer implements FmtOptions.CodeStyleProducer {
968
    private static class Producer implements FmtOptions.CodeStyleProducer {
844
969
970
        @Override
845
        public CodeStyle create(Preferences preferences) {
971
        public CodeStyle create(Preferences preferences) {
846
            return new CodeStyle(preferences);
972
            return new CodeStyle(preferences);
847
        }
973
        }
(-)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