Refactoring: dependency computations isolated in a separate class

This commit is contained in:
Andrey Breslav
2013-03-05 18:35:18 +04:00
parent 89407fdcb2
commit 70f44244f9
@@ -45,11 +45,11 @@ public class DependencyInjectorGenerator {
private static final String LOCK_NAME = "__lock__"; private static final String LOCK_NAME = "__lock__";
private final boolean lazy; private final boolean lazy;
private final Multimap<DiType, Field> typeToField = HashMultimap.create();
private final Set<Field> satisfied = Sets.newHashSet();
private final Set<Field> fields = Sets.newLinkedHashSet(); private final Set<Field> fields = Sets.newLinkedHashSet();
private final Set<Parameter> parameters = Sets.newLinkedHashSet(); private final Set<Parameter> parameters = Sets.newLinkedHashSet();
private final Dependencies dependencies = new Dependencies();
private final Set<Field> backsParameter = Sets.newHashSet(); private final Set<Field> backsParameter = Sets.newHashSet();
private final List<Class<?>> implementsList = Lists.newArrayList(); private final List<Class<?>> implementsList = Lists.newArrayList();
@@ -85,9 +85,7 @@ public class DependencyInjectorGenerator {
PrintStream out = new PrintStream(fileOutputStream); PrintStream out = new PrintStream(fileOutputStream);
try { try {
for (Field field : Lists.newArrayList(fields)) { fields.addAll(dependencies.satisfyDependencies());
satisfyDependenciesFor(field, field);
}
String copyright = "injector-generator/copyright.txt"; String copyright = "injector-generator/copyright.txt";
out.println(FileUtil.loadFile(new File(copyright))); out.println(FileUtil.loadFile(new File(copyright)));
@@ -190,7 +188,7 @@ public class DependencyInjectorGenerator {
parameters.add(parameter); parameters.add(parameter);
field.setInitialization(new ParameterExpression(parameter)); field.setInitialization(new ParameterExpression(parameter));
backsParameter.add(field); backsParameter.add(field);
typeToField.put(type, field); dependencies.addSatisfiedField(field);
} }
public Field addPublicField(Class<?> type) { public Field addPublicField(Class<?> type) {
@@ -221,7 +219,7 @@ public class DependencyInjectorGenerator {
public Field addField(boolean isPublic, DiType type, @Nullable String name, @Nullable Expression init) { public Field addField(boolean isPublic, DiType type, @Nullable String name, @Nullable Expression init) {
Field field = Field.create(isPublic, type, name == null ? var(type) : name, init); Field field = Field.create(isPublic, type, name == null ? var(type) : name, init);
fields.add(field); fields.add(field);
typeToField.put(type, field); dependencies.addField(field);
return field; return field;
} }
@@ -436,9 +434,33 @@ public class DependencyInjectorGenerator {
} }
} }
private static class Dependencies {
private final Set<Field> allFields = Sets.newLinkedHashSet();
private final Set<Field> satisfied = Sets.newHashSet();
private final Multimap<DiType, Field> typeToFields = HashMultimap.create();
private final Set<Field> newFields = Sets.newLinkedHashSet();
public void addField(@NotNull Field field) {
allFields.add(field);
typeToFields.put(field.getType(), field);
}
public void addSatisfiedField(@NotNull Field field) {
addField(field);
satisfied.add(field);
}
public Field addNewField(@NotNull DiType type) {
Field field = Field.create(false, type, var(type), null);
addField(field);
newFields.add(field);
return field;
}
private void satisfyDependenciesFor(Field field, Field neededFor) { private void satisfyDependenciesFor(Field field, Field neededFor) {
if (!satisfied.add(field)) return; if (!satisfied.add(field)) return;
if (backsParameter.contains(field)) return;
Expression initialization = field.getInitialization(); Expression initialization = field.getInitialization();
if (initialization instanceof InstantiateType) { if (initialization instanceof InstantiateType) {
@@ -462,7 +484,7 @@ public class DependencyInjectorGenerator {
Type parameterType = method.getGenericParameterTypes()[0]; Type parameterType = method.getGenericParameterTypes()[0];
Field dependency = findDependencyOfType(DiType.fromReflectionType(parameterType), field + ": " + method + ": " + fields, field); Field dependency = findDependencyOfType(DiType.fromReflectionType(parameterType), field + ": " + method + ": " + allFields, field);
field.getDependencies().add(new SetterDependency(field, method.getName(), dependency)); field.getDependencies().add(new SetterDependency(field, method.getName(), dependency));
} }
@@ -470,13 +492,12 @@ public class DependencyInjectorGenerator {
private Field findDependencyOfType(DiType parameterType, String errorMessage, Field neededFor) { private Field findDependencyOfType(DiType parameterType, String errorMessage, Field neededFor) {
List<Field> fields = Lists.newArrayList(); List<Field> fields = Lists.newArrayList();
for (Map.Entry<DiType, Field> entry : typeToField.entries()) { for (Map.Entry<DiType, Field> entry : typeToFields.entries()) {
if (parameterType.isAssignableFrom(entry.getKey())) { if (parameterType.isAssignableFrom(entry.getKey())) {
fields.add(entry.getValue()); fields.add(entry.getValue());
} }
} }
Field dependency;
if (fields.isEmpty()) { if (fields.isEmpty()) {
if (parameterType.getClazz().isPrimitive() || parameterType.getClazz().getPackage().getName().equals("java.lang")) { if (parameterType.getClazz().isPrimitive() || parameterType.getClazz().getPackage().getName().equals("java.lang")) {
@@ -484,16 +505,16 @@ public class DependencyInjectorGenerator {
"cannot declare magic field of type " + parameterType + ": " + errorMessage); "cannot declare magic field of type " + parameterType + ": " + errorMessage);
} }
dependency = addField(parameterType); Field dependency = addNewField(parameterType);
satisfyDependenciesFor(dependency, neededFor); satisfyDependenciesFor(dependency, neededFor);
return dependency;
} }
else if (fields.size() == 1) { else if (fields.size() == 1) {
dependency = fields.iterator().next(); return fields.iterator().next();
} }
else { else {
throw new IllegalArgumentException("Ambiguous dependency: " + errorMessage + " needed for " + neededFor); throw new IllegalArgumentException("Ambiguous dependency: " + errorMessage + " needed for " + neededFor);
} }
return dependency;
} }
private void initializeByConstructorCall(Field field, Field neededFor) { private void initializeByConstructorCall(Field field, Field neededFor) {
@@ -530,7 +551,19 @@ public class DependencyInjectorGenerator {
field.setInitialization(dependency); field.setInitialization(dependency);
} }
private String var(@NotNull DiType type) { public Collection<Field> satisfyDependencies() {
for (Field field : Lists.newArrayList(allFields)) {
satisfyDependenciesFor(field, field);
}
return newFields;
}
public Set<Field> getNewFields() {
return newFields;
}
}
private static String var(@NotNull DiType type) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(StringUtil.decapitalize(type.getClazz().getSimpleName().replaceFirst("(?<=.)Impl$", ""))); sb.append(StringUtil.decapitalize(type.getClazz().getSimpleName().replaceFirst("(?<=.)Impl$", "")));
if (type.getTypeParameters().size() > 0) { if (type.getTypeParameters().size() > 0) {