Search in sources :

Example 21 with ExecutableType

use of javax.lang.model.type.ExecutableType in project tiger by google.

the class DependencyCollector method collectFromInjectedMembersRecursively.

/**
 * Collects dependencies of the give {@link TypeElement} from the injected
 * members, either fields or methods, of the {@link TypeElement}.
 */
private Set<BindingKey> collectFromInjectedMembersRecursively(TypeElement classElement, DeclaredType declaredType) {
    if (utils.findInjectedCtor(classElement) != null) {
        logger.w(String.format("class %s is injected and should not have injected ctor", classElement));
    }
    Set<BindingKey> dependencies = new HashSet<>();
    TypeMirror superMirror = classElement.getSuperclass();
    if (!superMirror.getKind().equals(TypeKind.NONE)) {
        TypeElement parent = (TypeElement) ((DeclaredType) superMirror).asElement();
        Set<BindingKey> keys = collectFromInjectedMembersRecursively(parent, declaredType);
        dependencies.addAll(keys);
    }
    for (TypeMirror typeMirror : classElement.getInterfaces()) {
        TypeElement typeElement = (TypeElement) ((DeclaredType) typeMirror).asElement();
        Set<BindingKey> keys = collectFromInjectedMembersRecursively(typeElement, declaredType);
        dependencies.addAll(keys);
    }
    for (Element element : classElement.getEnclosedElements()) {
        // for (Element element : elements.getAllMembers(classElement)) {
        TypeMirror typeMirror = types.asMemberOf((DeclaredType) classElement.asType(), element);
        // + typeMirror);
        if (element.getKind().equals(ElementKind.FIELD) && utils.isInjected(element)) {
            // logger.n(
            // TAG
            // + ".collectFromInjectedMembersRecursively:"
            // + " found element: "
            // + element
            // + " kind: "
            // + element.getKind()
            // + " type: "
            // + typeMirror);
            dependencies.add(BindingKey.get(typeMirror, utils.getQualifier(element)));
        }
        if (element.getKind().equals(ElementKind.METHOD) && utils.isInjected(element)) {
            // logger.n(
            // TAG
            // + ".collectFromInjectedMembersRecursively:"
            // + " found element: "
            // + element
            // + " kind: "
            // + element.getKind()
            // + " type: "
            // + typeMirror);
            dependencies.addAll(getDependenciesFrom((ExecutableElement) element, (ExecutableType) typeMirror));
        }
    }
    if (!dependencies.isEmpty() && !classElement.getModifiers().contains(Modifier.PUBLIC)) {
        logger.w("non-public injected class? %s", classElement);
    }
    return dependencies;
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) HashSet(java.util.HashSet)

Example 22 with ExecutableType

use of javax.lang.model.type.ExecutableType in project tiger by google.

the class DependencyCollector method getRequiredKeys.

/**
 * Returns all the required {@link BindingKey}s by the provision methods and injection methods
 * included in the given class directly.
 */
private Set<BindingKey> getRequiredKeys(TypeElement component) {
    Set<BindingKey> result = new HashSet<>();
    TypeMirror superType = component.getSuperclass();
    logger.n(TAG + ".getRequiredKeys:  component: " + component + " superType " + superType);
    utils.traverseAndDo(types, (DeclaredType) component.asType(), component, x -> {
        TypeMirror type = x.getFirst();
        Element element = x.getSecond();
        logger.n(TAG + ".getRequiredKeys: element: " + element + " type: " + type);
        if (!element.getKind().equals(ElementKind.METHOD)) {
            return null;
        }
        if (!element.getModifiers().contains(Modifier.ABSTRACT)) {
            return null;
        }
        ExecutableElement method = (ExecutableElement) element;
        logger.n(TAG + ".getRequiredKeys: method: " + method);
        ExecutableType methodType = (ExecutableType) type;
        AnnotationMirror qualifier = utils.getQualifier(method);
        if (utils.isProvisionMethodInInjector(method)) {
            result.add(BindingKey.get(methodType.getReturnType(), qualifier));
        }
        if (utils.isInjectionMethod(method)) {
            DeclaredType injectedType = ((DeclaredType) Iterables.getOnlyElement(methodType.getParameterTypes()));
            TypeElement injectedElement = (TypeElement) injectedType.asElement();
            result.addAll(collectRequiredKeysFromInjectedClass(injectedElement));
        }
        return null;
    });
    return result;
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) HashSet(java.util.HashSet) DeclaredType(javax.lang.model.type.DeclaredType)

Example 23 with ExecutableType

use of javax.lang.model.type.ExecutableType in project tiger by google.

the class GeneralInjectorGenerator method generateProvisionMethodFromClass.

/**
 * Generic is handled.
 */
protected final void generateProvisionMethodFromClass(BindingKey key, String suffix) {
    // logger.n("key: " + key + " referencingClass: " +
    // referencingClass);
    TypeElement cls = utils.getClassFromKey(key);
    DeclaredType clsType = (DeclaredType) utils.getTypeFromKey(key);
    ExecutableElement ctor = utils.findInjectedCtor(cls);
    Preconditions.checkNotNull(ctor, String.format("Did not find ctor for %s", cls));
    ExecutableType ctorType = (ExecutableType) types.asMemberOf(clsType, ctor);
    List<BindingKey> dependencyKeys = utils.getDependenciesFromMethod(ctorType, ctor);
    // TODO: clean this.
    // if (key.getTypeName() instanceof ParameterizedTypeName) {
    // logger.n("be here :" + key);
    // List<BindingKey> specializedKeys = new ArrayList<>();
    // Map<TypeVariableName, TypeName> map =
    // utils.getMapFromTypeVariableToSpecialized((ParameterizedTypeName) key.getTypeName(),
    // (ParameterizedTypeName) TypeName.get(cls.asType()));
    // for (BindingKey k : dependencyKeys) {
    // specializedKeys.add(utils.specializeIfNeeded(k, map));
    // }
    // dependencyKeys = specializedKeys;
    // }
    // logger.n("dependencyKeys: " +
    // dependencyKeys);
    MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(getProvisionMethodName(key) + suffix);
    methodSpecBuilder.addModifiers(suffix.isEmpty() ? Modifier.PUBLIC : Modifier.PRIVATE).returns(key.getTypeName());
    onProvisionMethodStart(methodSpecBuilder, key);
    methodSpecBuilder.addStatement("$T result", key.getTypeName());
    addNewStatementToMethodSpec(methodSpecBuilder, Iterables.getOnlyElement(dependencies.get(key)), "result");
    if (shouldInjectAfterCreation() && !utils.isGenericNotSpecialized(cls.asType()) && utils.hasInjectedFieldsOrMethodsRecursively(cls, processingEnv)) {
        // logger.n("hasInjected");
        generateInjectionMethod(key);
        methodSpecBuilder.addStatement("inject(result)");
    }
    methodSpecBuilder.addStatement("return result");
    onProvisionMethodEnd(methodSpecBuilder, key);
    injectorBuilder.addMethod(methodSpecBuilder.build());
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) DeclaredType(javax.lang.model.type.DeclaredType)

Example 24 with ExecutableType

use of javax.lang.model.type.ExecutableType in project tiger by google.

the class GeneralInjectorGenerator4 method generateProvisionMethodFromClass.

/**
 * Generic is handled.
 */
protected final void generateProvisionMethodFromClass(BindingKey key, String suffix) {
    // logger.n("key: " + key + " referencingClass: " +
    // referencingClass);
    TypeElement cls = utils.getClassFromKey(key);
    DeclaredType clsType = (DeclaredType) utils.getTypeFromKey(key);
    ExecutableElement ctor = utils.findInjectedCtor(cls);
    Preconditions.checkNotNull(ctor, String.format("Did not find ctor for %s", cls));
    ExecutableType ctorType = (ExecutableType) types.asMemberOf(clsType, ctor);
    List<BindingKey> dependencyKeys = utils.getDependenciesFromMethod(ctorType, ctor);
    // TODO: clean this.
    // if (key.getTypeName() instanceof ParameterizedTypeName) {
    // logger.n("be here :" + key);
    // List<BindingKey> specializedKeys = new ArrayList<>();
    // Map<TypeVariableName, TypeName> map =
    // utils.getMapFromTypeVariableToSpecialized((ParameterizedTypeName) key.getTypeName(),
    // (ParameterizedTypeName) TypeName.get(cls.asType()));
    // for (BindingKey k : dependencyKeys) {
    // specializedKeys.add(utils.specializeIfNeeded(k, map));
    // }
    // dependencyKeys = specializedKeys;
    // }
    // logger.n("dependencyKeys: " +
    // dependencyKeys);
    MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(getProvisionMethodName(key) + suffix);
    TypeName returnTypeName = getAccessibleTypeName(key);
    methodSpecBuilder.addModifiers(suffix.isEmpty() ? Modifier.PUBLIC : Modifier.PRIVATE).returns(returnTypeName);
    onProvisionMethodStart(methodSpecBuilder, key);
    methodSpecBuilder.addStatement("$T result", returnTypeName);
    addNewStatementToMethodSpec(methodSpecBuilder, Iterables.getOnlyElement(dependencies.get(key)), "result");
    if (shouldInjectAfterCreation() && !utils.isGenericNotSpecialized(cls.asType()) && utils.hasInjectedFieldsOrMethodsRecursively(cls, processingEnv)) {
        // logger.n("hasInjected");
        generateInjectionMethod(utils.getClassFromKey(key), Utils.getInjectionMethodName(key));
        methodSpecBuilder.addStatement("$L(result)", Utils.getInjectionMethodName(key));
    }
    methodSpecBuilder.addStatement("return result");
    onProvisionMethodEnd(methodSpecBuilder, key);
    injectorBuilder.addMethod(methodSpecBuilder.build());
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) DeclaredType(javax.lang.model.type.DeclaredType)

Example 25 with ExecutableType

use of javax.lang.model.type.ExecutableType in project tiger by google.

the class HubInjectorGenerator4 method generateImplicitMethods.

/**
 * Generates those methods that are not declared in the (sub)component interface.
 */
protected void generateImplicitMethods() {
    utils.traverseAndDo(types, (DeclaredType) eitherComponent.asType(), eitherComponent, p -> {
        Element e = p.second;
        // logger.n("element: " + e);
        if (!utils.isMethod(e)) {
            return null;
        }
        ExecutableElement method = (ExecutableElement) e;
        ExecutableType methodType = (ExecutableType) p.first;
        if (utils.isInjectionMethod(method)) {
            TypeElement injectedTypeElement = (TypeElement) ((DeclaredType) Iterables.getOnlyElement(methodType.getParameterTypes())).asElement();
            logger.l(Kind.NOTE, "injection method for: " + injectedTypeElement);
            generateInjectionMethod(injectedTypeElement, "inject");
        } else if (utils.isProvisionMethodInInjector(method)) {
            generateProvisionMethodIfNeeded(utils.getKeyProvidedByMethod(method));
        } else {
            // TODO: ignore known elements like builders.
            logger.w("Unknown element %s from injector %s.", method, eitherComponent);
        }
        return null;
    });
// logger.n("packagedInjectorBuilders: " + packagedInjectorBuilders);
// Inherited provision methods.
// for (CoreInjectorInfo component : orderedCoreinjectors) {
// if (componentTree.get(component) == null) {
// continue;
// }
// for (Map.Entry<ClassName, Builder> entry : packagedInjectorBuilders.entrySet()) {
// ClassName packagedInjectorClassName = entry.getKey();
// if (!component
// .equals(getComponentFromPackagedInjectorClassName(packagedInjectorClassName))) {
// continue;
// }
// generateInheritedProvisionMethods(packagedInjectorClassName);
// }
// }
// Inherited injection methods.
// for (CoreInjectorInfo component : orderedCoreinjectors) {
// if (componentTree.get(component) == null) {
// continue;
// }
// for (Map.Entry<ClassName, Builder> entry : packagedInjectorBuilders.entrySet()) {
// ClassName packagedInjectorClassName = entry.getKey();
// if (!component
// .equals(getComponentFromPackagedInjectorClassName(packagedInjectorClassName))) {
// continue;
// }
// generateInheritedInjectionMethods(packagedInjectorClassName);
// }
// }
// JavaFile javaFile =
// JavaFile.builder(utils.getPackage(eitherComponent).getQualifiedName().toString(),
// builder.build()).build();
// logger.l(    //     Kind.NOTE, "javaFile for: " + builder.build() + "\n" + javaFile.toString());
// logger.n("file: %s", javaFile));
// try {
// // javaFile.writeTo(processingEnv.getFiler());
// } catch (IOException e) {
// Throwables.propagate(e);
// }
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement)

Aggregations

ExecutableType (javax.lang.model.type.ExecutableType)68 ExecutableElement (javax.lang.model.element.ExecutableElement)53 DeclaredType (javax.lang.model.type.DeclaredType)41 TypeElement (javax.lang.model.element.TypeElement)39 TypeMirror (javax.lang.model.type.TypeMirror)39 Element (javax.lang.model.element.Element)29 VariableElement (javax.lang.model.element.VariableElement)27 TypeSpec (com.squareup.javapoet.TypeSpec)13 Nonnull (javax.annotation.Nonnull)13 PackageElement (javax.lang.model.element.PackageElement)13 HashMap (java.util.HashMap)12 Map (java.util.Map)12 MethodSpec (com.squareup.javapoet.MethodSpec)11 AnnotationMirror (javax.lang.model.element.AnnotationMirror)11 IOException (java.io.IOException)10 ArrayList (java.util.ArrayList)10 HashSet (java.util.HashSet)10 Nullable (javax.annotation.Nullable)10 JavaFile (com.squareup.javapoet.JavaFile)9 List (java.util.List)9