Search in sources :

Example 26 with ExecutableType

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

the class Utils method getCtorDependencies.

public List<BindingKey> getCtorDependencies(SetMultimap<BindingKey, DependencyInfo> dependencies, BindingKey key) {
    TypeElement cls = getClassFromKey(key);
    DeclaredType clsType = (DeclaredType) getTypeFromKey(key);
    ExecutableElement ctor = findInjectedCtor(cls);
    Preconditions.checkNotNull(ctor, String.format("Did not find ctor for %s", cls));
    ExecutableType ctorType = (ExecutableType) types.asMemberOf(clsType, ctor);
    List<BindingKey> dependencyKeys = getDependenciesFromMethod(ctorType, ctor);
    return dependencyKeys;
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) DeclaredType(javax.lang.model.type.DeclaredType)

Example 27 with ExecutableType

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

the class Utils method getProduced.

public Pair<Set<BindingKey>, Set<BindingKey>> getProduced(TypeElement eitherComponent) {
    Set<BindingKey> provided = new HashSet<>();
    Set<BindingKey> injected = new HashSet<>();
    // Set<String> s = new HashSet<>();
    // s.add("PartyHatPromoController");
    // s.add("ReviewAtAPlaceNotificationAdapterRecommend");
    // s.add("ReviewAtAPlaceNotificationAdapterStars");
    DeclaredType eitherComponentType = (DeclaredType) eitherComponent.asType();
    traverseAndDo(types, eitherComponentType, eitherComponent, p -> {
        Element element = p.second;
        // logger.n(element.toString());
        if (!element.getKind().equals(ElementKind.METHOD)) {
            return null;
        }
        ExecutableElement method = (ExecutableElement) element;
        ExecutableType methodType = (ExecutableType) processingEnvironment.getTypeUtils().asMemberOf(eitherComponentType, method);
        // Injection methods.
        if (isInjectionMethod(element)) {
            TypeMirror typeMirror = Iterables.getOnlyElement(methodType.getParameterTypes());
            while (typeMirror != null) {
                if (!((DeclaredType) typeMirror).getTypeArguments().isEmpty()) {
                    logger.w("Inject generic type: %s", typeMirror);
                    typeMirror = types.erasure(typeMirror);
                }
                injected.add(BindingKey.get(typeMirror));
                TypeElement closestInjectedAncestor = getClosestInjectedAncestor((TypeElement) ((DeclaredType) typeMirror).asElement());
                typeMirror = closestInjectedAncestor == null ? null : closestInjectedAncestor.asType();
            }
        // if (typeMirror instanceof DeclaredType) {
        // String qN =
        // ((TypeElement) ((DeclaredType) typeMirror).asElement())
        // .getQualifiedName()
        // .toString();
        // for (String i : s) {
        // if (qN.contains(i)) {
        // for (StackTraceElement j : utils.getStack()) {
        // logger.e("%s.%s", method.getEnclosingElement(), method);
        // }
        // }
        // }
        // }
        } else if (isProvisionMethodInInjector(element)) {
            provided.add(getKeyProvidedByMethod(method));
        } else if (isIrrelevantMethodInInjector(element)) {
        // do nothing
        } else {
            logger.l(Kind.WARNING, "Element %s ignored from injector %s.", element, eitherComponentType);
        }
        return null;
    });
    // addFromComponentDependencies(provided);
    // addBindsInstance(provided);
    // addFromPackagedHubInterfaces(provided);
    // addFromSubcomponentHubInterfaces(provided);
    logger.n("provided: %s\ninjected: %s", provided, injected);
    return Pair.of(provided, injected);
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) PackageElement(javax.lang.model.element.PackageElement) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) HashSet(java.util.HashSet) DeclaredType(javax.lang.model.type.DeclaredType)

Example 28 with ExecutableType

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

the class Utils method getKeyForOnlyParameterOfMethod.

public BindingKey getKeyForOnlyParameterOfMethod(Types types, DeclaredType containingType, Element e) {
    ExecutableType method = (ExecutableType) types.asMemberOf(containingType, e);
    VariableElement variableElement = Iterables.getOnlyElement(((ExecutableElement) e).getParameters());
    TypeMirror argumentType = Iterables.getOnlyElement(method.getParameterTypes());
    AnnotationMirror annotationTypeMirror = getQualifier(variableElement);
    return BindingKey.get(argumentType, annotationTypeMirror);
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeMirror(javax.lang.model.type.TypeMirror) VariableElement(javax.lang.model.element.VariableElement)

Example 29 with ExecutableType

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

the class Tiger2InjectorGenerator method doSpecific.

@Override
protected void doSpecific() {
    // TODO: remove this, just and the contracts to trigger generating things when needed.
    // generateImplicitMethods();
    // Injection methods and non-injection methods.
    Set<String> miscMethodNames = new HashSet<>();
    DeclaredType eitherComponentType = (DeclaredType) eitherComponent.asType();
    utils.traverseAndDo(types, eitherComponentType, eitherComponent, p -> {
        Element element = p.second;
        messager.printMessage(Kind.NOTE, "method: " + element);
        if (!element.getKind().equals(ElementKind.METHOD)) {
            return null;
        }
        ExecutableElement method = (ExecutableElement) element;
        ExecutableType methodType = (ExecutableType) processingEnv.getTypeUtils().asMemberOf(eitherComponentType, method);
        // Injection methods.
        if (utils.isInjectionMethod(element)) {
            // TODO: add duplicate check for provision method also.
            if (injectionMethodsDone.add(Pair.of(method.getSimpleName().toString(), TypeName.get(Iterables.getOnlyElement(methodType.getParameterTypes())))) == false) {
                messager.printMessage(Kind.WARNING, "duplicate injection method: " + method);
                return null;
            }
            TypeMirror typeMirror = Iterables.getOnlyElement(methodType.getParameterTypes());
            TypeElement cls = (TypeElement) ((DeclaredType) typeMirror).asElement();
            messager.printMessage(Kind.NOTE, TAG + ".generateTopLevelInjector-injection method : " + methodType);
            injectorBuilder.addMethod(MethodSpec.methodBuilder(method.getSimpleName().toString()).addModifiers(Modifier.PUBLIC).addParameter(ClassName.get(cls), "arg").addStatement("inject(arg)").build());
        } else if (utils.isComponentProvisionMethod(element)) {
            messager.printMessage(Kind.ERROR, "Injecting components is not supported: " + element);
        } else if (utils.isSubcomponentProvisionMethod(element)) {
            /**
             * TODO: handle this in {@link #generateProvisionMethodIfNeeded(BindingKey)}
             */
            generateGetSubcomponentMethod((ExecutableElement) element, injectorBuilder);
        } else if (utils.isProvisionMethodInInjector(element)) {
            if (!miscMethodNames.add(method.getSimpleName().toString())) {
                return null;
            }
            MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getSimpleName().toString()).addModifiers(Modifier.PUBLIC).returns(TypeName.get(method.getReturnType()));
            BindingKey providedKey = utils.getKeyProvidedByMethod(method);
            // ClassName packagedInjectorClassName = null;
            // for (ClassName className : keyToPackagedInjectorMap.get(providedKey)) {
            // if (isInjectorOfScope(className, coreInjectorInfo.getScope())) {
            // packagedInjectorClassName = className;
            // break;
            // }
            // }
            // if (packagedInjectorClassName == null) {
            // messager.printMessage(Kind.WARNING,
            // String.format(
            // "PackagedInjector or multiBindingInjector not found for key: %s "
            // + "from provisionMethod: %s. Probably it is not used.",
            // providedKey, method));
            // // Create a dumb method
            // String statement = "return ";
            // TypeKind typeKind = method.getReturnType().getKind();
            // if (typeKind.equals(TypeKind.BOOLEAN)) {
            // statement += "false";
            // } else if (typeKind.equals(TypeKind.CHAR)) {
            // statement += "\'0\'";
            // } else if (typeKind.isPrimitive()) {
            // statement += "0";
            // } else {
            // statement += "null";
            // }
            // methodBuilder.addStatement(statement);
            // } else {
            String statement = "return $L()";
            methodBuilder.addStatement(statement, Utils.getProvisionMethodName(dependencies, providedKey));
            // }
            // messager.printMessage(Kind.NOTE, "provision method added: " + methodBuilder.build());
            injectorBuilder.addMethod(methodBuilder.build());
        // } else if (utils.isEitherComponentProvisionMethod(element)) {
        // // TODO: support get component method.
        // if(utils.isComponentProvisionMethod(element)) {
        // throw new RuntimeException("component provision method is not suported yet.");
        // }
        // generateGetSubcomponentMethod((ExecutableElement) element, injectorBuilder);
        // } else if (utils.isEitherComponentBuilderProvisionMethod(element)) {
        // /**
        // * TODO: handle it in the way consistent with other {@link DependencySourceType} in
        // * {@link #generateProvisionMethodIfNeeded(BindingKey, TypeElement)}
        // */
        // generateExplicitProvisionMethodForEitherComponentBuilder(
        // (ExecutableElement) element, injectorBuilder);
        } else if (isIrrelevantMethodInInjector(element)) {
        // do nothing
        } else {
            messager.printMessage(Kind.WARNING, String.format("Element %s ignored from injector %s.", element, eitherComponentType));
        }
        return null;
    });
    // Builder.
    TypeElement explicitBuilder = utils.findBuilder(elements, eitherComponent);
    generateInjectorBuilder(explicitBuilder);
    // builder().
    ClassName builderClassName = ClassName.get(utils.getPackageString(eitherComponent), utils.getComponentImplementationSimpleNameFromInterface(eitherComponent), explicitBuilder != null ? explicitBuilder.getSimpleName().toString() : "Builder");
    MethodSpec.Builder builderMethodSpecBuilder = MethodSpec.methodBuilder("builder").addModifiers(Modifier.PUBLIC, Modifier.STATIC).returns(builderClassName);
    boolean isSubcomponent = utils.isSubcomponent(eitherComponent);
    if (isSubcomponent) {
        builderMethodSpecBuilder.addParameter(ClassName.get(parentEitherComponent.asType()), "v");
    }
    builderMethodSpecBuilder.addCode("return new $T($L);", builderClassName, isSubcomponent ? "v" : "");
    injectorBuilder.addMethod(builderMethodSpecBuilder.build());
// provision methods for (sub)component builders that can be provided by this core injector.
// TODO: handle implicit ones here, explicit ones have been handled in {@link
// #generateProvisionMethodForThoseFromTopLevel}.
// generateImplicitProvisionMethodForEitherComponentBuilder(injectorBuilder, builder);
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) MethodSpec(com.squareup.javapoet.MethodSpec) 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) Builder(com.squareup.javapoet.TypeSpec.Builder) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(com.squareup.javapoet.ClassName) HashSet(java.util.HashSet) DeclaredType(javax.lang.model.type.DeclaredType)

Example 30 with ExecutableType

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

the class Tiger2Processor method completeComponents.

/**
 * Find all the (sub)eitherComponents in question. {@link Component}s are from annotation already. But
 * some {@link Subcomponent}s can only be traced by provision methods for them or their builders.
 */
private void completeComponents(Set<TypeElement> components) {
    Set<TypeElement> work = Sets.newHashSet(components);
    Set<TypeElement> done = Sets.newHashSet();
    while (!work.isEmpty()) {
        TypeElement c = Preconditions.checkNotNull(Iterables.getFirst(work, null));
        work.remove(c);
        done.add(c);
        utils.traverseAndDo(types, (DeclaredType) c.asType(), c, pair -> {
            TypeMirror type = pair.getFirst();
            Element element = pair.getSecond();
            if (utils.isEitherComponentProvisionMethod(element) || utils.isEitherComponentBuilderProvisionMethod(element)) {
                TypeElement newFound = (TypeElement) ((DeclaredType) ((ExecutableType) type).getReturnType()).asElement();
                if (utils.isEitherComponentBuilder(newFound)) {
                    newFound = (TypeElement) newFound.getEnclosingElement();
                }
                if (components.add(newFound)) {
                    messager.printMessage(Kind.NOTE, TAG + ".completeComponents found new " + newFound + "component: " + c + " method: " + element);
                }
                if (!done.contains(newFound)) {
                    work.add(newFound);
                }
            }
            return null;
        });
    }
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element)

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