in java/java.source.base/src/org/netbeans/api/java/source/GeneratorUtilities.java [1091:1406]
private CompilationUnitTree addImports(CompilationUnitTree cut, List<? extends ImportTree> cutImports, Set<? extends Element> toImport) {
assert cut != null && toImport != null && toImport.size() > 0;
ArrayList<Element> elementsToImport = new ArrayList<Element>(toImport.size());
Set<String> staticImportNames = new HashSet<String>();
for (Element e : toImport) {
if (e == null) {
continue;
}
switch (e.getKind()) {
case METHOD:
case ENUM_CONSTANT:
case FIELD:
String name = new StringBuilder(((TypeElement)e.getEnclosingElement()).getQualifiedName()).append('.').append(e.getSimpleName()).toString();
// skip default static imports
if ("java.lang.StringTemplate.STR".equals(name)) {
break;
}
if (!staticImportNames.add(name))
break;
default:
elementsToImport.add(e);
}
}
Trees trees = copy.getTrees();
Elements elements = copy.getElements();
ElementUtilities elementUtilities = copy.getElementUtilities();
CodeStyle cs = DiffContext.getCodeStyle(copy);
// check weather any conversions to star imports are needed
int treshold = cs.useSingleClassImport() ? cs.countForUsingStarImport() : 1;
int staticTreshold = cs.countForUsingStaticStarImport();
Map<PackageElement, Integer> pkgCounts = new LinkedHashMap<PackageElement, Integer>();
PackageElement pkg = elements.getPackageElement("java.lang"); //NOI18N
if (pkg != null) {
pkgCounts.put(pkg, -2);
}
ExpressionTree packageName = cut.getPackageName();
pkg = packageName != null ? (PackageElement)trees.getElement(TreePath.getPath(cut, packageName)) : null;
if (pkg == null && packageName != null) {
pkg = elements.getPackageElement(elements.getName(packageName.toString()));
}
if (pkg == null) {
pkg = elements.getPackageElement(elements.getName("")); //NOI18N
}
pkgCounts.put(pkg, -2);
Map<TypeElement, Integer> typeCounts = new LinkedHashMap<TypeElement, Integer>();
// initially the import scope has no symbols. We must fill it in by:
// existing CUT named imports, package members AND then star imports, in this specific order
JCCompilationUnit jcut = (JCCompilationUnit)cut;
StarImportScope importScope = new StarImportScope((Symbol)pkg);
if (jcut.starImportScope != null) {
importScope.prependSubScope(((JCCompilationUnit)cut).starImportScope);
}
if (jcut.packge != null) {
importScope.prependSubScope(jcut.packge.members_field);
}
for (Element e : elementsToImport) {
boolean isStatic = false;
Element el = null;
switch (e.getKind()) {
case PACKAGE:
el = e;
break;
case ANNOTATION_TYPE:
case CLASS:
case ENUM:
case INTERFACE:
case RECORD:
if (e.getEnclosingElement().getKind() == ElementKind.PACKAGE)
el = e.getEnclosingElement();
break;
case METHOD:
case ENUM_CONSTANT:
case FIELD:
isStatic = true;
el = e.getEnclosingElement();
break;
default:
assert false : "Illegal element kind: " + e.getKind(); //NOI18N
}
if (el != null) {
Integer cnt = isStatic ? typeCounts.get((TypeElement)el) : pkgCounts.get((PackageElement)el);
if (cnt == null)
cnt = 0;
if (cnt >= 0) {
if (el == e) {
cnt = -1;
} else {
cnt++;
if (isStatic) {
if (cnt >= staticTreshold)
cnt = -1;
} else if (cnt >= treshold || checkPackagesForStarImport(((PackageElement)el).getQualifiedName().toString(), cs)) {
cnt = -1;
}
}
}
if (isStatic) {
typeCounts.put((TypeElement)el, cnt);
} else {
pkgCounts.put((PackageElement)el, cnt);
}
}
}
List<ImportTree> imports = new ArrayList<ImportTree>(cutImports);
for (ImportTree imp : imports) {
Element e = getImportedElement(cut, imp);
if (!elementsToImport.contains(e)) {
if (imp.isStatic()) {
if (e.getKind().isClass() || e.getKind().isInterface()) {
Element el = e;
while (el != null) {
Integer cnt = typeCounts.get((TypeElement)el);
if (cnt != null && staticTreshold == Integer.MAX_VALUE) {
typeCounts.put((TypeElement)el, -2);
}
TypeMirror tm = ((TypeElement)el).getSuperclass();
el = tm.getKind() == TypeKind.DECLARED ? ((DeclaredType)tm).asElement() : null;
}
} else {
Element el = elementUtilities.enclosingTypeElement(e);
if (el != null) {
Integer cnt = typeCounts.get((TypeElement)el);
if (cnt != null) {
if (cnt >= 0) {
cnt++;
if (cnt >= staticTreshold)
cnt = -1;
}
typeCounts.put((TypeElement)el, cnt);
}
}
}
} else {
Element el = e.getKind() == ElementKind.PACKAGE ? e : (e.getKind().isClass() || e.getKind().isInterface()) && e.getEnclosingElement().getKind() == ElementKind.PACKAGE ? e.getEnclosingElement() : null;
if (el != null) {
Integer cnt = pkgCounts.get((PackageElement)el);
if (cnt != null) {
if (el == e) { // this is only true for package element, that is for package-star import.
if (treshold == Integer.MAX_VALUE) {
// do not touch the star import
cnt = -2;
}
} else if (cnt >= 0) {
cnt++;
if (cnt >= treshold)
cnt = -1;
}
pkgCounts.put((PackageElement)el, cnt);
}
}
}
} else if (treshold == Integer.MAX_VALUE || staticTreshold == Integer.MAX_VALUE) {
// disable any manipulations (optimization) for existing star imports iff the "Count" feature is disabled.
int threshold = imp.isStatic() ? staticTreshold : treshold;
if (isStarImport(imp) && threshold == Integer.MAX_VALUE) {
Map map = imp.isStatic() ? typeCounts : pkgCounts;
Integer cnt = (Integer)map.get(e);
if (cnt != null) {
map.put(e, -2);
}
}
}
}
// remove those star imports that do not satisfy the thresholds
for (Iterator<ImportTree> ii = imports.iterator(); ii.hasNext();) {
ImportTree imp = ii.next();
if (!isStarImport(imp)) {
continue;
}
Element e = getImportedElement(cut, imp);
Integer cnt;
if (imp.isStatic()) {
cnt = typeCounts.get(e);
} else {
cnt = pkgCounts.get(e);
}
if (cnt != null && cnt >= 0) {
ii.remove();
}
}
// check for possible name clashes originating from adding the package imports
Set<Element> explicitNamedImports = new HashSet<Element>();
for (Element element : elementsToImport) {
if (element.getEnclosingElement() != pkg && (element.getKind().isClass() || element.getKind().isInterface())) {
for (Symbol sym : importScope.getSymbolsByName((com.sun.tools.javac.util.Name)element.getSimpleName())) {
if (sym.getKind().isClass() || sym.getKind().isInterface()) {
if (sym != element) {
explicitNamedImports.add(element);
break;// break if explicitNameImport was added
}
}
}
}
}
Map<Name, TypeElement> usedTypes = null;
for (Map.Entry<PackageElement, Integer> entry : pkgCounts.entrySet()) {
if (entry.getValue() == -1) {
for (Element element : entry.getKey().getEnclosedElements()) {
if (element.getKind().isClass() || element.getKind().isInterface()) {
for (Symbol sym : importScope.getSymbolsByName((com.sun.tools.javac.util.Name)element.getSimpleName())) {
if (sym != element) {
TypeElement te = null;
for (Element e : elementsToImport) {
if ((e.getKind().isClass() || e.getKind().isInterface()) && element.getSimpleName() == e.getSimpleName()) {
te = (TypeElement) e;
break;
}
}
if (te != null) {
explicitNamedImports.add(te);
} else {
if (usedTypes == null) {
usedTypes = getUsedTypes(cut);
}
if (te != null) {
explicitNamedImports.add(te);
} else {
if (usedTypes == null) {
usedTypes = getUsedTypes(cut);
}
te = usedTypes.get(element.getSimpleName());
if (te != null) {
elementsToImport.add(te);
explicitNamedImports.add(te);
}
}
}
}
}
}
}
}
if (entry.getValue() < 0 && entry.getKey() instanceof Symbol)
importScope.prependSubScope(((Symbol)entry.getKey()).members());
}
// sort the elements to import
ImportsComparator comparator = new ImportsComparator(cs);
elementsToImport.sort(comparator);
// merge the elements to import with the existing import statemetns
TreeMaker make = copy.getTreeMaker();
int currentToImport = elementsToImport.size() - 1;
int currentExisting = imports.size() - 1;
while (currentToImport >= 0) {
Element currentToImportElement = elementsToImport.get(currentToImport);
boolean isStatic = false;
Element el = null;
switch (currentToImportElement.getKind()) {
case PACKAGE:
el = currentToImportElement;
break;
case ANNOTATION_TYPE:
case CLASS:
case ENUM:
case INTERFACE:
case RECORD:
if (currentToImportElement.getEnclosingElement().getKind() == ElementKind.PACKAGE)
el = currentToImportElement.getEnclosingElement();
break;
case METHOD:
case ENUM_CONSTANT:
case FIELD:
isStatic = true;
el = currentToImportElement.getEnclosingElement();
break;
}
Integer cnt = el == null ? Integer.valueOf(0) : isStatic ? typeCounts.get((TypeElement)el) : pkgCounts.get((PackageElement)el);
if (explicitNamedImports.contains(currentToImportElement))
cnt = 0;
if (cnt == -2) {
currentToImport--;
} else {
if (cnt == -1) {
currentToImportElement = el;
if (isStatic) {
typeCounts.put((TypeElement)el, -2);
} else {
pkgCounts.put((PackageElement)el, -2);
}
}
boolean isStar = currentToImportElement.getKind() == ElementKind.PACKAGE
|| isStatic && (currentToImportElement.getKind().isClass() || currentToImportElement.getKind().isInterface());
ExpressionTree qualIdent = qualIdentFor(currentToImportElement);
if (isStar) {
qualIdent = make.MemberSelect(qualIdent, elements.getName("*")); //NOI18N
}
ImportTree nImport = make.Import(qualIdent, isStatic);
while (currentExisting >= 0) {
ImportTree imp = imports.get(currentExisting);
Element impElement = getImportedElement(cut, imp);
el = imp.isStatic()
? impElement.getKind().isClass() || impElement.getKind().isInterface() ? impElement : elementUtilities.enclosingTypeElement(impElement)
: impElement.getKind() == ElementKind.PACKAGE ? impElement : (impElement.getKind().isClass() || impElement.getKind().isInterface()) && impElement.getEnclosingElement().getKind() == ElementKind.PACKAGE ? impElement.getEnclosingElement() : null;
if (isStatic == imp.isStatic() && (currentToImportElement == impElement || isStar && currentToImportElement == el)) {
imports.remove(currentExisting);
} else {
if (comparator.compare(nImport, imp) > 0) {
break;
}
}
currentExisting--;
}
imports.add(currentExisting + 1, nImport);
currentToImport--;
}
}
// return a copy of the unit with changed imports section
return make.CompilationUnit(cut.getPackage(), imports, cut.getTypeDecls(), cut.getSourceFile());
}