Skip to content
This repository has been archived by the owner on Aug 26, 2021. It is now read-only.

Commit

Permalink
Revert "A few more changes to eliminate reflection."
Browse files Browse the repository at this point in the history
This reverts commit af6ebcd.

Conflicts:
	compiler/pom.xml
  • Loading branch information
cgruber committed Dec 4, 2013
1 parent a3d39b6 commit be9ae34
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@
*/
package dagger.internal.codegen;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering;
import com.squareup.javawriter.JavaWriter;
import dagger.Lazy;
import dagger.Module;
Expand Down Expand Up @@ -71,9 +66,9 @@
import static dagger.internal.codegen.Util.getNoArgsConstructor;
import static dagger.internal.codegen.Util.getPackage;
import static dagger.internal.codegen.Util.isCallableConstructor;
import static dagger.internal.codegen.Util.isInterface;
import static dagger.internal.codegen.Util.typeToString;
import static dagger.internal.loaders.GeneratedAdapters.MODULE_ADAPTER_SUFFIX;
import static java.util.Arrays.asList;
import static javax.lang.model.element.Modifier.ABSTRACT;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PRIVATE;
Expand Down Expand Up @@ -269,33 +264,15 @@ private void generateModuleAdapter(Writer ioWriter, String adapterName, TypeElem
writer.beginType(adapterName, "class", EnumSet.of(PUBLIC, FINAL),
JavaWriter.type(ModuleAdapter.class, typeName));

final List<String> providedTypes = FluentIterable.from(providerMethods)
.transform(new Function<ExecutableElement, String>() {
@Override public String apply(ExecutableElement element) {
return GeneratorKeys.get(element.getReturnType());
}
}).toList();
StringBuilder injectsField = new StringBuilder("{");
Iterable<String> injectsFieldKeys = FluentIterable.<Object>from(asList(injects))
.transform(new Cast<TypeMirror>())
.transformAndConcat(new Function<TypeMirror, Iterable<String>>() {
@Override public Iterable<String> apply(TypeMirror type) {
String key = GeneratorKeys.get(type);
if (!providedTypes.contains(key) && Util.needsMemberInjection(type)) {
String membersKey = GeneratorKeys.rawMembersKey(type);
Iterable<String> keys = ImmutableList.of(membersKey, key);
return keys;
}
return ImmutableList.of(key);
}
})
.transform(new Function<String, String>() {
@Override public String apply(String key) {
return JavaWriter.stringLiteral(key);
}
})
.toSortedSet(Ordering.natural());
Joiner.on(", ").appendTo(injectsField, injectsFieldKeys).append("}");
StringBuilder injectsField = new StringBuilder().append("{ ");
for (Object injectableType : injects) {
TypeMirror typeMirror = (TypeMirror) injectableType;
String key = isInterface(typeMirror)
? GeneratorKeys.get(typeMirror)
: GeneratorKeys.rawMembersKey(typeMirror);
injectsField.append(JavaWriter.stringLiteral(key)).append(", ");
}
injectsField.append("}");
writer.emitField("String[]", "INJECTS", EnumSet.of(PRIVATE, STATIC, FINAL),
injectsField.toString());

Expand Down Expand Up @@ -536,17 +513,4 @@ private String parameterName(Element parameter) {
}
return parameter.getSimpleName().toString();
}

/**
* A function used to perform a cast to a strongly known type. This does not actually
* perform any casting logic, but bridges Java's typesystem. {@link Cast} should only
* be used in circumstances where the cast is bullet-proof and safe.
*/
private static final class Cast<T> implements Function<Object, T> {
@SuppressWarnings("unchecked")
@Override
public T apply(Object o) {
return (T) o;
}
}
}
22 changes: 0 additions & 22 deletions compiler/src/main/java/dagger/internal/codegen/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@
*/
package dagger.internal.codegen;

import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import dagger.internal.Keys;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.AnnotationValueVisitor;
Expand All @@ -34,14 +31,12 @@
import javax.lang.model.element.Modifier;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ErrorType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleAnnotationValueVisitor6;
import javax.lang.model.util.SimpleTypeVisitor6;

Expand Down Expand Up @@ -243,23 +238,6 @@ private static boolean lenientIsInstance(Class<?> expectedClass, Object value) {
}
}

/**
* Returns true if the type reflected by this TypeMirror contains @Inject fields.
*/
public static boolean needsMemberInjection(TypeMirror type) {
return type.accept(new SimpleTypeVisitor6<Boolean, Void>() {
@Override public Boolean visitDeclared(DeclaredType declaredType, Void v) {
List<? extends Element> enclosed = declaredType.asElement().getEnclosedElements();
return FluentIterable.<VariableElement>from(ElementFilter.fieldsIn(enclosed))
.anyMatch(new Predicate<VariableElement>() {
@Override public boolean apply(VariableElement e) {
return e.getAnnotation(Inject.class) != null;
}
});
}
}, null);
}

// TODO(sgoldfed): better format for other types of elements?
static String elementToString(Element element) {
switch (element.getKind()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public final class InjectAdapterGenerationTest {
"import dagger.internal.ModuleAdapter;",
"public final class Basic$AModule$$ModuleAdapter",
" extends ModuleAdapter<Basic.AModule> {",
" private static final String[] INJECTS = {\"Basic$A\"};",
" private static final String[] INJECTS = {\"members/Basic$A\"};",
" private static final Class<?>[] STATIC_INJECTIONS = {};",
" private static final Class<?>[] INCLUDES = {};",
" public Basic$AModule$$ModuleAdapter() {",
Expand Down Expand Up @@ -99,7 +99,7 @@ public final class InjectAdapterGenerationTest {
"import javax.inject.Inject;",
"class Field {",
" static class A { final String name; @Inject A(String name) { this.name = name; }}",
" @Module(injects = { A.class, String.class })",
" @Module(injects = A.class)",
" static class AModule { @Provides String name() { return \"foo\"; }}",
"}"));

Expand All @@ -111,8 +111,7 @@ public final class InjectAdapterGenerationTest {
"import javax.inject.Provider;",
"public final class Field$AModule$$ModuleAdapter",
" extends ModuleAdapter<Field.AModule> {",
" private static final String[] INJECTS = ",
" {\"Field$A\", \"java.lang.String\"};",
" private static final String[] INJECTS = {\"members/Field$A\"};",
" private static final Class<?>[] STATIC_INJECTIONS = {};",
" private static final Class<?>[] INCLUDES = {};",
" public Field$AModule$$ModuleAdapter() {",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,123 +23,13 @@
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
import static dagger.tests.integration.ProcessorTestUtils.daggerProcessors;
import static java.util.Arrays.asList;
import static org.truth0.Truth.ASSERT;

@RunWith(JUnit4.class)
public final class ModuleAdapterGenerationTest {
@Test public void injectsMembersInjectedAndProvidedAndConstructedTypes() {
JavaFileObject sourceFile = JavaFileObjects.forSourceString("Field", Joiner.on("\n").join(
"import dagger.Module;",
"import dagger.Provides;",
"import javax.inject.Inject;",
"class Field {",
" static class A { final String name; @Inject A(String name) { this.name = name; }}",
" static class B { @Inject String name; }",
" @Module(injects = { A.class, String.class, B.class })",
" static class AModule { @Provides String name() { return \"foo\"; }}",
"}"));

JavaFileObject expectedModuleAdapter =
JavaFileObjects.forSourceString("Field$AModule$$ModuleAdapter", Joiner.on("\n").join(
"import dagger.internal.Binding;",
"import dagger.internal.ModuleAdapter;",
"import java.util.Map;",
"import javax.inject.Provider;",
"public final class Field$AModule$$ModuleAdapter extends ModuleAdapter<Field.AModule> {",
" private static final String[] INJECTS = ",
" {\"Field$A\", \"Field$B\", \"java.lang.String\", \"members/Field$B\"};",
" private static final Class<?>[] STATIC_INJECTIONS = {};",
" private static final Class<?>[] INCLUDES = {};",
" public Field$AModule$$ModuleAdapter() {",
" super(Field.AModule.class, INJECTS, STATIC_INJECTIONS, false, INCLUDES, true, false);",
" }",
" @Override public Field.AModule newModule() {",
" return new Field.AModule();",
" }",
" @Override public void getBindings(Map<String, Binding<?>> map, Field.AModule module) {",
" map.put(\"java.lang.String\", new NameProvidesAdapter(module));", // eager new!
" }",
" public static final class NameProvidesAdapter", // corresponds to method name
" extends Binding<String> implements Provider<String> {",
" private final Field.AModule module;",
" public NameProvidesAdapter(Field.AModule module) {",
" super(\"java.lang.String\", null, NOT_SINGLETON, \"Field.AModule.name()\");",
" this.module = module;",
" setLibrary(false);",
" }",
" @Override public String get() {",
" return module.name();", // corresponds to @Provides method
" }",
" }",
"}"));

JavaFileObject expectedInjectAdapterA =
JavaFileObjects.forSourceString("Field$A$$InjectAdapter", Joiner.on("\n").join(
"import dagger.internal.Binding;",
"import dagger.internal.Linker;",
"import java.util.Set;",
"import javax.inject.Provider;",
"public final class Field$A$$InjectAdapter",
" extends Binding<Field.A> implements Provider<Field.A> {",
" private Binding<String> name;", // For Constructor.
" public Field$A$$InjectAdapter() {",
" super(\"Field$A\", \"members/Field$A\", NOT_SINGLETON, Field.A.class);",
" }",
" @Override @SuppressWarnings(\"unchecked\")",
" public void attach(Linker linker) {",
" name = (Binding<String>)linker.requestBinding(",
" \"java.lang.String\", Field.A.class, getClass().getClassLoader());",
" }",
" @Override public void getDependencies(",
" Set<Binding<?>> getBindings, Set<Binding<?>> injectMembersBindings) {",
" getBindings.add(name);", // Name is added to dependencies.
" }",
" @Override public Field.A get() {",
" Field.A result = new Field.A(name.get());", // Adds constructor parameter.
" return result;",
" }",
"}"));

JavaFileObject expectedInjectAdapterB =
JavaFileObjects.forSourceString("Field$B$$InjectAdapter", Joiner.on("\n").join(
"import dagger.MembersInjector;",
"import dagger.internal.Binding;",
"import dagger.internal.Linker;",
"import java.util.Set;",
"import javax.inject.Provider;",
"public final class Field$B$$InjectAdapter",
" extends Binding<Field.B> implements Provider<Field.B>, MembersInjector<Field.B> {",
" private Binding<String> name;", // For field.
" public Field$B$$InjectAdapter() {",
" super(\"Field$B\", \"members/Field$B\", NOT_SINGLETON, Field.B.class);",
" }",
" @Override @SuppressWarnings(\"unchecked\")",
" public void attach(Linker linker) {",
" name = (Binding<String>)linker.requestBinding(",
" \"java.lang.String\", Field.B.class, getClass().getClassLoader());",
" }",
" @Override public void getDependencies(",
" Set<Binding<?>> getBindings, Set<Binding<?>> injectMembersBindings) {",
" injectMembersBindings.add(name);", // Name is added to dependencies.
" }",
" @Override public Field.B get() {",
" Field.B result = new Field.B();",
" injectMembers(result);",
" return result;",
" }",
" @Override public void injectMembers(Field.B object) {",
" object.name = name.get();", // Inject field.
" }",
"}"));
ASSERT.about(javaSource()).that(sourceFile).processedWith(daggerProcessors())
.compilesWithoutError()
.and()
.generatesSources(expectedModuleAdapter, expectedInjectAdapterA, expectedInjectAdapterB);
}

@Test public void providesHasParameterNamedModule() {
JavaFileObject a = JavaFileObjects.forSourceString("A", Joiner.on("\n").join(
Expand All @@ -152,10 +42,12 @@ public final class ModuleAdapterGenerationTest {
JavaFileObject module = JavaFileObjects.forSourceString("BModule", Joiner.on("\n").join(
"import dagger.Module;",
"import dagger.Provides;",
"import javax.inject.Inject;",
"@Module(injects = B.class)",
"class BModule { @Provides B b(A module) { return new B(); }}"));

ASSERT.about(javaSources()).that(asList(a, b, module)).processedWith(daggerProcessors())
.compilesWithoutError();
}

}

0 comments on commit be9ae34

Please sign in to comment.