diff --git a/injector-generator/src/org/jetbrains/jet/di/DependencyInjectorGenerator.java b/injector-generator/src/org/jetbrains/jet/di/DependencyInjectorGenerator.java index 051f0c38220..467932f1860 100644 --- a/injector-generator/src/org/jetbrains/jet/di/DependencyInjectorGenerator.java +++ b/injector-generator/src/org/jetbrains/jet/di/DependencyInjectorGenerator.java @@ -16,14 +16,15 @@ package org.jetbrains.jet.di; -import com.google.common.collect.*; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.utils.Printer; -import javax.annotation.PreDestroy; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -39,14 +40,13 @@ public class DependencyInjectorGenerator { private final Set fields = Sets.newLinkedHashSet(); private final Set parameters = Sets.newLinkedHashSet(); + private final Set backsParameter = Sets.newHashSet(); private final Set factoryMethods = Sets.newLinkedHashSet(); + private final List> implementsList = Lists.newArrayList(); private final Dependencies dependencies = new Dependencies(); - private final Set backsParameter = Sets.newHashSet(); - - private final List> implementsList = Lists.newArrayList(); - private final Collection> imports = Sets.newHashSet(); + private final ImportManager importManager = new ImportManager(); public DependencyInjectorGenerator() { } @@ -75,6 +75,7 @@ public class DependencyInjectorGenerator { FileOutputStream fileOutputStream = new FileOutputStream(tmpfile); System.out.println("File opened: " + tmpfile.getAbsolutePath()); + PrintStream out = new PrintStream(fileOutputStream); try { fields.addAll(dependencies.satisfyDependencies()); @@ -129,7 +130,7 @@ public class DependencyInjectorGenerator { if (!superInterface.isInterface()) { throw new IllegalArgumentException("Only interfaces are supported as supertypes"); } - out.print(superInterface.getSimpleName()); + out.print(type(superInterface)); if (iterator.hasNext()) { out.print(", "); } @@ -230,58 +231,25 @@ public class DependencyInjectorGenerator { for (DiType type : parameterTypes) { parameters.add(new Parameter(type, var(type), null, false)); } - factoryMethods.add(new FactoryMethod("create" + returnType.getSimpleName(), returnType, parameters)); + factoryMethods.add(new FactoryMethod("create" + type(returnType), returnType, parameters)); } private void generateImports(PrintStream out, String injectorPackageName) { - for (Field field : fields) { - generateImportDirectives(out, field.getType(), injectorPackageName); - - DiType implType = field.getInitialization().getType(); - if (implType != null) { - generateImportDirectives(out, implType, injectorPackageName); - } - for (DiType typeToImport : field.getInitialization().getTypesToImport()) { - generateImportDirective(out, typeToImport.getClazz(), injectorPackageName); + for (Class importedClass : importManager.getImportedClasses()) { + if (importedClass.isPrimitive()) continue; + String importedPackageName = importedClass.getPackage().getName(); + if ("java.lang".equals(importedPackageName) + || injectorPackageName.equals(importedPackageName)) { + continue; } + out.println("import " + importedClass.getCanonicalName() + ";"); } - for (Class superInterface : implementsList) { - generateImportDirective(out, superInterface, injectorPackageName); - } - for (Parameter parameter : parameters) { - generateImportDirectives(out, parameter.getType(), injectorPackageName); - } - for (Parameter parameter : parameters) { - if (parameter.isRequired()) { - generateImportDirective(out, NotNull.class, injectorPackageName); - break; - } - } - generateImportDirective(out, PreDestroy.class, injectorPackageName); - } - - private void generateImportDirectives(PrintStream out, DiType type, String injectorPackageName) { - generateImportDirective(out, type.getClazz(), injectorPackageName); - for (DiType typeParameter : type.getTypeParameters()) { - generateImportDirectives(out, typeParameter, injectorPackageName); - } - } - - private void generateImportDirective(PrintStream out, Class type, String injectorPackageName) { - if (type.isPrimitive()) return; - String importedPackageName = type.getPackage().getName(); - if ("java.lang".equals(importedPackageName) - || injectorPackageName.equals(importedPackageName) - || !imports.add(type)) { - return; - } - out.println("import " + type.getCanonicalName() + ";"); } private void generateFields(PrintStream out) { for (Field field : fields) { String _final = backsParameter.contains(field) ? "final " : ""; - out.println(" private " + _final + InjectorGeneratorUtil.getEffectiveFieldType(field).getSimpleName() + " " + field.getName() + ";"); + out.println(" private " + _final + type(InjectorGeneratorUtil.getEffectiveFieldType(field)) + " " + field.getName() + ";"); } } @@ -302,7 +270,7 @@ public class DependencyInjectorGenerator { if (parameter.isRequired()) { p.printWithNoIndent("@NotNull "); } - p.printWithNoIndent(parameter.getType().getSimpleName(), " ", parameter.getName()); + p.printWithNoIndent(type(parameter.getType()), " ", parameter.getName()); if (iterator.hasNext()) { p.printlnWithNoIndent(","); } @@ -314,7 +282,7 @@ public class DependencyInjectorGenerator { p.pushIndent(); - InjectionLogicGenerator.FIELDS.generate(p, fields); + InjectionLogicGenerator.generateForFields(p, fields); p.popIndent(); p.println("}"); @@ -343,7 +311,7 @@ public class DependencyInjectorGenerator { for (Field field : fields) { if (!field.isPublic()) continue; String visibility = field.isPublic() ? "public" : "private"; - out.println(indent0 + visibility + " " + field.getTypeName() + " " + field.getGetterName() + "() {"); + out.println(indent0 + visibility + " " + type(field.getType()) + " " + field.getGetterName() + "() {"); out.println(indent1 + "return this." + field.getName() + ";"); out.println(indent0 + "}"); @@ -393,7 +361,7 @@ public class DependencyInjectorGenerator { p.println(") {"); p.pushIndent(); - InjectionLogicGenerator.LOCAL_VARIABLES.generate(p, fields); + InjectionLogicGenerator.generateForLocalVariables(importManager, p, fields); p.println("return ", resultField.getName(), ";"); @@ -401,7 +369,11 @@ public class DependencyInjectorGenerator { p.println("}"); } - private String type(DiType type) { - return type.getSimpleName(); + private CharSequence type(DiType type) { + return importManager.render(type); + } + + private CharSequence type(Class type) { + return type(DiType.fromReflectionType(type)); } } diff --git a/injector-generator/src/org/jetbrains/jet/di/DiType.java b/injector-generator/src/org/jetbrains/jet/di/DiType.java index cb8a5d8c50a..3cc469640f7 100644 --- a/injector-generator/src/org/jetbrains/jet/di/DiType.java +++ b/injector-generator/src/org/jetbrains/jet/di/DiType.java @@ -21,9 +21,7 @@ import org.jetbrains.annotations.NotNull; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.List; public class DiType { @@ -64,25 +62,6 @@ public class DiType { return this.typeParameters.equals(that.typeParameters); } - @NotNull - public String getSimpleName() { - StringBuilder sb = new StringBuilder(); - sb.append(clazz.getSimpleName()); - Iterator typeParameterIterator = typeParameters.iterator(); - if (typeParameterIterator.hasNext()) { - sb.append("<"); - if (typeParameterIterator.hasNext()) { - sb.append(typeParameterIterator.next().getSimpleName()); - } - while (typeParameterIterator.hasNext()) { - sb.append(", "); - sb.append(typeParameterIterator.next().getSimpleName()); - } - sb.append(">"); - } - return sb.toString(); - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/injector-generator/src/org/jetbrains/jet/di/ImportManager.java b/injector-generator/src/org/jetbrains/jet/di/ImportManager.java new file mode 100644 index 00000000000..22362915426 --- /dev/null +++ b/injector-generator/src/org/jetbrains/jet/di/ImportManager.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.di; + +import com.google.common.collect.Maps; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.utils.Printer; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + +public class ImportManager { + + private final Map> classes = Maps.newLinkedHashMap(); + + public boolean addClass(@NotNull Class classToImport) { + String simpleName = classToImport.getSimpleName(); + + Class imported = classes.get(simpleName); + if (imported != null) return classToImport.equals(imported); + + classes.put(simpleName, classToImport); + return true; + } + + @NotNull + public Collection> getImportedClasses() { + return classes.values(); + } + + @NotNull + public CharSequence render(@NotNull DiType type) { + StringBuilder out = new StringBuilder(); + Printer p = new Printer(out); + if (addClass(type.getClazz())) { + p.print(type.getClazz().getSimpleName()); + } + else { + p.print(type.getClazz().getCanonicalName()); + } + + if (!type.getTypeParameters().isEmpty()) { + p.print("<"); + for (Iterator iterator = type.getTypeParameters().iterator(); iterator.hasNext(); ) { + p.print(render(iterator.next())); + if (iterator.hasNext()) { + p.print(", "); + } + } + p.print(">"); + } + return out; + } +} diff --git a/injector-generator/src/org/jetbrains/jet/di/InjectionLogicGenerator.java b/injector-generator/src/org/jetbrains/jet/di/InjectionLogicGenerator.java index ca7a2b079e6..dfd4dd1088d 100644 --- a/injector-generator/src/org/jetbrains/jet/di/InjectionLogicGenerator.java +++ b/injector-generator/src/org/jetbrains/jet/di/InjectionLogicGenerator.java @@ -23,43 +23,51 @@ import java.lang.reflect.Method; import java.util.Collection; import java.util.List; -abstract class InjectionLogicGenerator { +public abstract class InjectionLogicGenerator { - public static final InjectionLogicGenerator FIELDS = new InjectionLogicGenerator() { - @Override - public String prefixForPostConstructorCall(Field field) { - return ""; - } + public static void generateForFields(@NotNull Printer p, @NotNull Collection fields) { + new InjectionLogicGenerator() { + @Override + public String prefixForPostConstructorCall(Field field) { + return ""; + } - @Override - public String prefixForSetterCall(Field field) { - return field.isPublic() ? "this." : ""; - } + @Override + public String prefixForSetterCall(Field field) { + return field.isPublic() ? "this." : ""; + } - @Override - public String prefixForInitialization(Field field) { - return "this."; - } - }; + @Override + public String prefixForInitialization(Field field) { + return "this."; + } + }.generate(p, fields); + } - public static final InjectionLogicGenerator LOCAL_VARIABLES = new InjectionLogicGenerator() { - @Override - public String prefixForPostConstructorCall(Field field) { - return ""; - } + public static void generateForLocalVariables( + @NotNull final ImportManager importManager, + @NotNull Printer p, + @NotNull Collection fields + ) { + new InjectionLogicGenerator() { + @Override + public String prefixForPostConstructorCall(Field field) { + return ""; + } - @Override - public String prefixForSetterCall(Field field) { - return ""; - } + @Override + public String prefixForSetterCall(Field field) { + return ""; + } - @Override - public String prefixForInitialization(Field field) { - return field.getType() + " "; - } - }; + @Override + public String prefixForInitialization(Field field) { + return importManager.render(field.getType()) + " "; + } + }.generate(p, fields); + } - public final void generate(@NotNull Printer p, @NotNull Collection fields) { + protected void generate(@NotNull Printer p, @NotNull Collection fields) { // Initialize fields for (Field field : fields) { //if (!backsParameter.contains(field) || field.isPublic()) {