Imports are tracked when types are used
This commit is contained in:
@@ -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<Field> fields = Sets.newLinkedHashSet();
|
||||
private final Set<Parameter> parameters = Sets.newLinkedHashSet();
|
||||
private final Set<Field> backsParameter = Sets.newHashSet();
|
||||
private final Set<FactoryMethod> factoryMethods = Sets.newLinkedHashSet();
|
||||
private final List<Class<?>> implementsList = Lists.newArrayList();
|
||||
|
||||
private final Dependencies dependencies = new Dependencies();
|
||||
|
||||
private final Set<Field> backsParameter = Sets.newHashSet();
|
||||
|
||||
private final List<Class<?>> implementsList = Lists.newArrayList();
|
||||
private final Collection<Class<?>> 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<DiType> 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;
|
||||
|
||||
@@ -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<String, Class<?>> 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<Class<?>> 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<DiType> iterator = type.getTypeParameters().iterator(); iterator.hasNext(); ) {
|
||||
p.print(render(iterator.next()));
|
||||
if (iterator.hasNext()) {
|
||||
p.print(", ");
|
||||
}
|
||||
}
|
||||
p.print(">");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -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<Field> 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<Field> 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<Field> fields) {
|
||||
protected void generate(@NotNull Printer p, @NotNull Collection<Field> fields) {
|
||||
// Initialize fields
|
||||
for (Field field : fields) {
|
||||
//if (!backsParameter.contains(field) || field.isPublic()) {
|
||||
|
||||
Reference in New Issue
Block a user