Generate Injectors: add ability to specify that a field is a context
Context field's properties can injected into other components Use it in GenerateInjectors.kt
This commit is contained in:
@@ -19,7 +19,9 @@ package org.jetbrains.jet.di;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.utils.Printer;
|
||||
@@ -154,8 +156,8 @@ public class DependencyInjectorGenerator {
|
||||
implementsList.add(superInterface);
|
||||
}
|
||||
|
||||
public void addParameter(boolean reexport, @NotNull DiType type, @Nullable String name, boolean required) {
|
||||
Field field = addField(reexport, type, name, null);
|
||||
public void addParameter(boolean reexport, @NotNull DiType type, @Nullable String name, boolean required, boolean useAsContext) {
|
||||
Field field = addField(reexport, type, name, null, useAsContext);
|
||||
Parameter parameter = new Parameter(type, name, field, required);
|
||||
parameters.add(parameter);
|
||||
field.setInitialization(new ParameterExpression(parameter));
|
||||
@@ -163,11 +165,20 @@ public class DependencyInjectorGenerator {
|
||||
dependencies.addSatisfiedField(field);
|
||||
}
|
||||
|
||||
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, boolean useAsContext) {
|
||||
Field field = Field.create(isPublic, type, name == null ? var(type) : name, init);
|
||||
addField(field);
|
||||
if (useAsContext) {
|
||||
for (Field accessibleViaGetter : field.getFieldsAccessibleViaGetters()) {
|
||||
addField(accessibleViaGetter);
|
||||
}
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
private void addField(@NotNull Field field) {
|
||||
fields.add(field);
|
||||
dependencies.addField(field);
|
||||
return field;
|
||||
}
|
||||
|
||||
public void addFactoryMethod(@NotNull Class<?> returnType, Class<?>... parameterTypes) {
|
||||
@@ -203,11 +214,21 @@ public class DependencyInjectorGenerator {
|
||||
}
|
||||
|
||||
private void generateFields(Printer out) {
|
||||
for (Field field : fields) {
|
||||
for (Field field : getUsedFields()) {
|
||||
out.println("private final " + type(InjectorGeneratorUtil.getEffectiveFieldType(field)) + " " + field.getName() + ";");
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<Field> getUsedFields() {
|
||||
return ContainerUtil.filter(fields, new Condition<Field>() {
|
||||
@Override
|
||||
public boolean value(Field field) {
|
||||
return dependencies.getUsedFields().contains(field) || field.isPublic();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void generateConstructor(String injectorClassName, Printer p) {
|
||||
// Constructor parameters
|
||||
if (parameters.isEmpty()) {
|
||||
@@ -220,7 +241,7 @@ public class DependencyInjectorGenerator {
|
||||
|
||||
p.pushIndent();
|
||||
|
||||
InjectionLogicGenerator.generateForFields(p, fields);
|
||||
InjectionLogicGenerator.generateForFields(p, getUsedFields());
|
||||
|
||||
p.popIndent();
|
||||
p.println("}");
|
||||
|
||||
@@ -21,7 +21,13 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import static org.jetbrains.jet.di.InjectorGeneratorUtil.var;
|
||||
|
||||
class Field {
|
||||
|
||||
@@ -113,4 +119,36 @@ class Field {
|
||||
result = 31 * result + name.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Field> getFieldsAccessibleViaGetters() {
|
||||
Class<?> clazz = type.getClazz();
|
||||
List<Field> result = Lists.newArrayList();
|
||||
for (Method method : allGetters(clazz)) {
|
||||
DiType type = DiType.fromReflectionType(method.getGenericReturnType());
|
||||
result.add(create(false, type, var(type), new GivenExpression(this.getName() + "." + method.getName() + "()")));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<Method> allGetters(@NotNull Class clazz) {
|
||||
Map<String, Method> getters = new TreeMap<String, Method>();
|
||||
for (Method method : clazz.getMethods()) {
|
||||
if (method.getDeclaringClass() == Object.class) {
|
||||
continue;
|
||||
}
|
||||
if (isGetter(method)) {
|
||||
if (!getters.containsKey(method.getName())) {
|
||||
getters.put(method.getName(), method);
|
||||
}
|
||||
}
|
||||
}
|
||||
return getters.values();
|
||||
}
|
||||
|
||||
private static boolean isGetter(@NotNull Method method) {
|
||||
String name = method.getName();
|
||||
return name.startsWith("get") && name.length() > 3 && method.getParameterTypes().length == 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,17 +32,19 @@ public fun generator(
|
||||
public fun DependencyInjectorGenerator.field(
|
||||
fieldType: Class<*>,
|
||||
name: String = defaultName(fieldType),
|
||||
init: Expression? = null
|
||||
init: Expression? = null,
|
||||
useAsContext: Boolean = false
|
||||
) {
|
||||
addField(false, DiType(fieldType), name, init)
|
||||
addField(false, DiType(fieldType), name, init, useAsContext)
|
||||
}
|
||||
|
||||
public fun DependencyInjectorGenerator.publicField(
|
||||
fieldType: Class<*>,
|
||||
name: String = defaultName(fieldType),
|
||||
init: Expression? = null
|
||||
init: Expression? = null,
|
||||
useAsContext: Boolean = false
|
||||
) {
|
||||
addField(true, DiType(fieldType), name, init)
|
||||
addField(true, DiType(fieldType), name, init, useAsContext)
|
||||
}
|
||||
|
||||
public fun DependencyInjectorGenerator.fields(vararg types: Class<*>): Unit = types.forEach { field(it) }
|
||||
@@ -50,16 +52,18 @@ public fun DependencyInjectorGenerator.publicFields(vararg types: Class<*>): Uni
|
||||
|
||||
public fun DependencyInjectorGenerator.parameter(
|
||||
parameterType: Class<*>,
|
||||
name: String = defaultName(parameterType)
|
||||
name: String = defaultName(parameterType),
|
||||
useAsContext: Boolean = false
|
||||
) {
|
||||
addParameter(false, DiType(parameterType), name, true)
|
||||
addParameter(false, DiType(parameterType), name, true, useAsContext)
|
||||
}
|
||||
|
||||
public fun DependencyInjectorGenerator.publicParameter(
|
||||
parameterType: Class<*>,
|
||||
name: String = defaultName(parameterType)
|
||||
name: String = defaultName(parameterType),
|
||||
useAsContext: Boolean = false
|
||||
) {
|
||||
addParameter(true, DiType(parameterType), name, true)
|
||||
addParameter(true, DiType(parameterType), name, true, useAsContext)
|
||||
}
|
||||
|
||||
public fun DependencyInjectorGenerator.parameters(vararg types: Class<*>): Unit = types.forEach { parameter(it) }
|
||||
|
||||
Reference in New Issue
Block a user