# HG changeset patch # User Christian Humer # Date 1408815073 -7200 # Node ID d3f282a9e287a4546f59f51674e9d0a7d49e9578 # Parent 09d99d3c0c95b6d0aa34143c6d95c445561056a8 Truffle-DSL: optimize import generation. diff -r 09d99d3c0c95 -r d3f282a9e287 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeImport.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeImport.java Sat Aug 23 19:31:09 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeImport.java Sat Aug 23 19:31:13 2014 +0200 @@ -22,32 +22,32 @@ */ package com.oracle.truffle.dsl.processor.java.model; -import javax.lang.model.type.*; +import java.util.*; public class CodeImport implements Comparable { - private final TypeMirror importType; - private final String importString; + private final String packageName; + private final String symbolName; private final boolean staticImport; - public CodeImport(TypeMirror importedType, String importString, boolean staticImport) { - this.importType = importedType; - this.importString = importString; + public CodeImport(String packageName, String symbolName, boolean staticImport) { + this.packageName = packageName; + this.symbolName = symbolName; this.staticImport = staticImport; } - public TypeMirror getImportType() { - return importType; + public String getPackageName() { + return packageName; + } + + public String getSymbolName() { + return symbolName; } public boolean isStaticImport() { return staticImport; } - public String getImportString() { - return importString; - } - @Override public int compareTo(CodeImport o) { if (staticImport && !o.staticImport) { @@ -55,7 +55,11 @@ } else if (!staticImport && o.staticImport) { return -1; } else { - return importString.compareTo(o.getImportString()); + int result = getPackageName().compareTo(o.getPackageName()); + if (result == 0) { + return getSymbolName().compareTo(o.getSymbolName()); + } + return result; } } @@ -65,36 +69,16 @@ @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((importString == null) ? 0 : importString.hashCode()); - result = prime * result + (staticImport ? 1231 : 1237); - return result; + return Objects.hash(packageName, symbolName, staticImport); } @Override public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; + if (obj instanceof CodeImport) { + CodeImport otherImport = (CodeImport) obj; + return getPackageName().equals(otherImport.getPackageName()) && getSymbolName().equals(otherImport.getSymbolName()) // + && staticImport == otherImport.staticImport; } - CodeImport other = (CodeImport) obj; - if (importString == null) { - if (other.importString != null) { - return false; - } - } else if (!importString.equals(other.importString)) { - return false; - } - if (staticImport != other.staticImport) { - return false; - } - return true; + return super.equals(obj); } - } diff -r 09d99d3c0c95 -r d3f282a9e287 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/OrganizedImports.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/OrganizedImports.java Sat Aug 23 19:31:09 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/OrganizedImports.java Sat Aug 23 19:31:13 2014 +0200 @@ -35,14 +35,8 @@ public final class OrganizedImports { - private final Set staticImportUsage = new HashSet<>(); - - private final Map simpleNamesUsed = new HashMap<>(); - - private final Set declaredStaticMethods = new HashSet<>(); - private final Set declaredStaticFields = new HashSet<>(); - private final Set ambiguousStaticMethods = new HashSet<>(); - private final Set ambiguousStaticFields = new HashSet<>(); + private final Map classImportUsage = new HashMap<>(); + private final Map staticImportUsage = new HashMap<>(); private final Map> autoImportCache = new HashMap<>(); private final CodeTypeElement topLevelClass; @@ -61,22 +55,6 @@ ImportTypeReferenceVisitor reference = new ImportTypeReferenceVisitor(); topLevelClass.accept(reference, null); - processStaticImports(topLevelClass); - List types = ElementUtils.getSuperTypes(topLevelClass); - for (TypeElement typeElement : types) { - processStaticImports(typeElement); - } - - for (TypeMirror type : staticImportUsage) { - TypeElement element = fromTypeMirror(type); - if (element != null) { - // already processed by supertype - if (types.contains(element)) { - continue; - } - processStaticImports(element); - } - } } public String createTypeReference(Element enclosedElement, TypeMirror type) { @@ -105,15 +83,16 @@ } public String createStaticFieldReference(Element enclosedElement, TypeMirror type, String fieldName) { - return createStaticReference(enclosedElement, type, fieldName, ambiguousStaticFields); + return createStaticReference(enclosedElement, type, fieldName); } public String createStaticMethodReference(Element enclosedElement, TypeMirror type, String methodName) { - return createStaticReference(enclosedElement, type, methodName, ambiguousStaticMethods); + return createStaticReference(enclosedElement, type, methodName); } - private String createStaticReference(Element enclosedElement, TypeMirror type, String name, Set ambiguousSymbols) { - if (ambiguousSymbols.contains(name)) { + private String createStaticReference(Element enclosedElement, TypeMirror type, String name) { + String qualifiedName = staticImportUsage.get(name); + if (qualifiedName == null) { // ambiguous import return createTypeReference(enclosedElement, type) + "." + name; } else { @@ -133,18 +112,13 @@ } private String createDeclaredTypeName(Element enclosedElement, DeclaredType type) { - String name; - name = ElementUtils.fixECJBinaryNameIssue(type.asElement().getSimpleName().toString()); + String name = ElementUtils.fixECJBinaryNameIssue(type.asElement().getSimpleName().toString()); + if (classImportUsage.containsKey(name)) { + String qualifiedImport = classImportUsage.get(name); + String qualifiedName = ElementUtils.getEnclosedQualifiedName(type); - if (needsImport(enclosedElement, type)) { - TypeMirror usedByType = simpleNamesUsed.get(name); - if (usedByType == null) { - simpleNamesUsed.put(name, type); - usedByType = type; - } - - if (!typeEquals(type, usedByType)) { - name = getQualifiedName(type); + if (!qualifiedName.equals(qualifiedImport)) { + name = qualifiedName; } } @@ -169,61 +143,12 @@ public Set generateImports() { Set imports = new HashSet<>(); - imports.addAll(generateImports(simpleNamesUsed.values())); + imports.addAll(generateImports(classImportUsage)); imports.addAll(generateStaticImports(staticImportUsage)); return imports; } - boolean processStaticImports(TypeElement element) { - Set importedMethods = new HashSet<>(); - List methods = ElementFilter.methodsIn(element.getEnclosedElements()); - for (ExecutableElement method : methods) { - if (method.getModifiers().contains(Modifier.STATIC)) { - importedMethods.add(method.getSimpleName().toString()); - } - } - - boolean allMethodsAmbiguous = processStaticImportElements(importedMethods, this.ambiguousStaticMethods, this.declaredStaticMethods); - - Set importedFields = new HashSet<>(); - List fields = ElementFilter.fieldsIn(element.getEnclosedElements()); - for (VariableElement field : fields) { - if (field.getModifiers().contains(Modifier.STATIC)) { - importedFields.add(field.getSimpleName().toString()); - } - } - - boolean allFieldsAmbiguous = processStaticImportElements(importedFields, this.ambiguousStaticFields, this.declaredStaticFields); - - return allMethodsAmbiguous && allFieldsAmbiguous; - } - - private static boolean processStaticImportElements(Set newElements, Set ambiguousElements, Set declaredElements) { - boolean allAmbiguous = false; - if (declaredElements.containsAll(newElements)) { - // all types already declared -> we can remove the import completely -> they will all - // get ambiguous - allAmbiguous = true; - } - Set newAmbiguous = new HashSet<>(); - Set newDeclared = new HashSet<>(); - - for (String newElement : newElements) { - if (declaredElements.contains(newElement)) { - newAmbiguous.add(newElement); - } else if (ambiguousElements.contains(newElement)) { - // nothing to do - } else { - newDeclared.add(newElement); - } - } - - ambiguousElements.addAll(newAmbiguous); - declaredElements.addAll(newDeclared); - return allAmbiguous; - } - private boolean needsImport(Element enclosed, TypeMirror importType) { String importPackagName = getPackageName(importType); TypeElement enclosedElement = findNearestEnclosingType(enclosed); @@ -235,18 +160,18 @@ return false; // same package name -> no import } - Set autoImportedTypes = autoImportCache.get(enclosedElement.toString()); + String enclosedElementId = ElementUtils.getUniqueIdentifier(enclosedElement.asType()); + Set autoImportedTypes = autoImportCache.get(enclosedElementId); if (autoImportedTypes == null) { List elements = ElementUtils.getElementHierarchy(enclosedElement); autoImportedTypes = new HashSet<>(); for (Element element : elements) { - if (element.getKind().isClass()) { collectSuperTypeImports((TypeElement) element, autoImportedTypes); collectInnerTypeImports((TypeElement) element, autoImportedTypes); } } - autoImportCache.put(enclosedElement.toString(), autoImportedTypes); + autoImportCache.put(enclosedElementId, autoImportedTypes); } String qualifiedName = getQualifiedName(importType); @@ -257,10 +182,13 @@ return true; } - private static Set generateImports(Collection toGenerate) { + private static Set generateImports(Map symbols) { TreeSet importObjects = new TreeSet<>(); - for (TypeMirror importType : toGenerate) { - importObjects.add(new CodeImport(importType, getQualifiedName(importType), false)); + for (String symbol : symbols.keySet()) { + String packageName = symbols.get(symbol); + if (packageName != null) { + importObjects.add(new CodeImport(packageName, symbol, false)); + } } return importObjects; } @@ -282,7 +210,7 @@ } } - private Set generateStaticImports(Set toGenerate) { + private Set generateStaticImports(Map toGenerate) { Set autoImportedStaticTypes = new HashSet<>(); // if type is declared inside a super type of this class -> no import @@ -290,17 +218,18 @@ autoImportedStaticTypes.addAll(getQualifiedSuperTypeNames(topLevelClass)); TreeSet importObjects = new TreeSet<>(); - for (TypeMirror importType : toGenerate) { - if (getPackageName(importType) == null) { - continue; // no package name -> no import + for (String symbol : toGenerate.keySet()) { + String qualifiedName = toGenerate.get(symbol); + if (qualifiedName == null) { + // ambiguous + continue; } - - String qualifiedName = getQualifiedName(importType); + // not not import if (autoImportedStaticTypes.contains(qualifiedName)) { continue; } - importObjects.add(new CodeImport(importType, qualifiedName + ".*", true)); + importObjects.add(new CodeImport(qualifiedName, symbol, true)); } return importObjects; @@ -309,15 +238,15 @@ private abstract static class TypeReferenceVisitor extends CodeElementScanner { @Override - public void visitTree(CodeTree e, Void p) { + public void visitTree(CodeTree e, Void p, Element enclosing) { if (e.getCodeKind() == CodeTreeKind.STATIC_FIELD_REFERENCE) { - visitStaticFieldReference(e, e.getType(), e.getString()); + visitStaticFieldReference(enclosing, e.getType(), e.getString()); } else if (e.getCodeKind() == CodeTreeKind.STATIC_METHOD_REFERENCE) { - visitStaticMethodReference(e, e.getType(), e.getString()); + visitStaticMethodReference(enclosing, e.getType(), e.getString()); } else if (e.getType() != null) { - visitTypeReference(e, e.getType()); + visitTypeReference(enclosing, e.getType()); } - super.visitTree(e, p); + super.visitTree(e, p, enclosing); } @Override @@ -477,18 +406,69 @@ @Override public void visitStaticFieldReference(Element enclosedType, TypeMirror type, String elementName) { - staticImportUsage.add(type); + registerSymbol(staticImportUsage, ElementUtils.getQualifiedName(type), elementName); } @Override public void visitStaticMethodReference(Element enclosedType, TypeMirror type, String elementName) { - staticImportUsage.add(type); + registerSymbol(staticImportUsage, ElementUtils.getQualifiedName(type), elementName); } @Override public void visitTypeReference(Element enclosedType, TypeMirror type) { if (type != null) { - createTypeReference(enclosedType, type); + switch (type.getKind()) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FLOAT: + case SHORT: + case INT: + case LONG: + case VOID: + return; + case DECLARED: + if (needsImport(enclosedType, type)) { + DeclaredType declard = (DeclaredType) type; + registerSymbol(classImportUsage, ElementUtils.getEnclosedQualifiedName(declard), ElementUtils.getDeclaredName(declard, false)); + } + for (TypeMirror argument : ((DeclaredType) type).getTypeArguments()) { + visitTypeReference(enclosedType, argument); + } + return; + case ARRAY: + visitTypeReference(enclosedType, ((ArrayType) type).getComponentType()); + return; + case WILDCARD: + WildcardType wildcard = (WildcardType) type; + if (wildcard.getExtendsBound() != null) { + visitTypeReference(enclosedType, wildcard.getExtendsBound()); + } else if (wildcard.getSuperBound() != null) { + visitTypeReference(enclosedType, wildcard.getSuperBound()); + } + return; + case TYPEVAR: + return; + default: + throw new RuntimeException("Unknown type specified " + type.getKind() + " mirror: " + type); + } + + } + } + + private void registerSymbol(Map symbolUsage, String elementQualifiedName, String elementName) { + if (symbolUsage.containsKey(elementName)) { + String otherQualifiedName = symbolUsage.get(elementName); + if (otherQualifiedName == null) { + // already registered ambiguous + return; + } + if (!otherQualifiedName.equals(elementQualifiedName)) { + symbolUsage.put(elementName, null); + } + } else { + symbolUsage.put(elementName, elementQualifiedName); } }