Search in sources :

Example 16 with ClassName

use of com.squareup.javapoet.ClassName in project tiger by google.

the class NewInjectorGenerator method createInjectorTypeSpec.

private TypeSpec.Builder createInjectorTypeSpec(ComponentInfo component, ClassName injectorClassName) {
    ClassName cn = getInjectorNameOfScope(injectorClassName, component.getScope());
    // System.out.println("createPackagedInjectorTypeSpec. name: " +
    // Utilities.getClassCanonicalName(cn));
    TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(cn.simpleName()).addModifiers(Modifier.PUBLIC).addAnnotation(AnnotationSpec.builder(Generated.class).addMember("value", "$S", GENERATOR_NAME).build());
    // Top level injector.
    ClassName topLevelInjectorClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(component));
    typeSpecBuilder.addField(topLevelInjectorClassName, TOP_LEVEL_INJECTOR_FIELD, Modifier.PRIVATE);
    MethodSpec.Builder ctorSpec = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addParameter(topLevelInjectorClassName, TOP_LEVEL_INJECTOR_FIELD);
    ctorSpec.addStatement("this.$N = $N", TOP_LEVEL_INJECTOR_FIELD, TOP_LEVEL_INJECTOR_FIELD);
    // Containing packaged injector.
    if (componentTree.get(component) != null) {
        ClassName containingInjectorClassName = getInjectorNameOfScope(injectorClassName, componentTree.get(component).getScope());
        typeSpecBuilder.addField(containingInjectorClassName, CONTAINING_PACKAGED_INJECTOR_FIELD, Modifier.PRIVATE);
        ctorSpec.addParameter(containingInjectorClassName, CONTAINING_PACKAGED_INJECTOR_FIELD);
        ctorSpec.addStatement("this.$N = $N", CONTAINING_PACKAGED_INJECTOR_FIELD, CONTAINING_PACKAGED_INJECTOR_FIELD);
    }
    typeSpecBuilder.addMethod(ctorSpec.build());
    return typeSpecBuilder;
}
Also used : Generated(javax.annotation.Generated) MethodSpec(com.squareup.javapoet.MethodSpec) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 17 with ClassName

use of com.squareup.javapoet.ClassName in project tiger by google.

the class NewInjectorGenerator method generateUniqueTypeProvisionMethodFromModule.

private void generateUniqueTypeProvisionMethodFromModule(NewBindingKey key, String suffix) {
    NewDependencyInfo dependencyInfo = Iterables.getOnlyElement(dependencies.get(key));
    Preconditions.checkNotNull(dependencyInfo.getProvisionMethodElement());
    TypeMirror returnType = dependencyInfo.getProvisionMethodElement().getReturnType();
    ClassName injectorClassName = getPackagedInjectorForNewDependencyInfo(key, dependencyInfo);
    TypeSpec.Builder componentSpecBuilder = getInjectorTypeSpecBuilder(injectorClassName);
    NewBindingKey returnKey = NewBindingKey.get(returnType, key.getQualifier());
    MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(getProvisionMethodName(returnKey) + suffix);
    methodSpecBuilder.addModifiers(suffix.isEmpty() ? Modifier.PUBLIC : Modifier.PRIVATE).returns(TypeName.get(returnType));
    methodSpecBuilder.addStatement("$T result", returnType);
    addNewStatementToMethodSpec(key, dependencyInfo, injectorClassName, methodSpecBuilder, "result");
    methodSpecBuilder.addStatement("return result");
    componentSpecBuilder.addMethod(methodSpecBuilder.build());
// messager.printMessage(Kind.NOTE, String.format(
// "generateUniqueTypeProvisionMethodFromModule: \n key: %s, \n injector: %s, \n method: %s.",
// key, injectorClassName, methodSpecBuilder.build()));
}
Also used : TypeMirror(javax.lang.model.type.TypeMirror) MethodSpec(com.squareup.javapoet.MethodSpec) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 18 with ClassName

use of com.squareup.javapoet.ClassName in project tiger by google.

the class NewInjectorGenerator method generateSetTypeProvisionMethodForPackage.

// If dependencyInfo is not null, then it is a contributor to set binding.
private void generateSetTypeProvisionMethodForPackage(NewBindingKey key, Set<NewDependencyInfo> dependencyInfos, String suffix) {
    Preconditions.checkArgument(!dependencyInfos.isEmpty(), String.format("Empty dependencyInfo for key: %s", key));
    NewDependencyInfo dependencyInfo = Iterables.getFirst(dependencyInfos, null);
    TypeName returnType = key.getTypeName();
    ClassName injectorClassName = getPackagedInjectorForNewDependencyInfo(key, dependencyInfo);
    TypeSpec.Builder componentSpecBuilder = getInjectorTypeSpecBuilder(injectorClassName);
    MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(getProvisionMethodName(key) + suffix);
    methodSpecBuilder.addModifiers(Modifier.PUBLIC).returns(returnType);
    methodSpecBuilder.addStatement("$T result = new $T<>()", returnType, HashSet.class);
    for (NewDependencyInfo di : dependencyInfos) {
        methodSpecBuilder.beginControlFlow("");
        Preconditions.checkNotNull(di.getProvisionMethodElement());
        TypeName contributorType = TypeName.get(di.getProvisionMethodElement().getReturnType());
        methodSpecBuilder.addStatement("$T contributor", contributorType);
        addNewStatementToMethodSpec(key, di, injectorClassName, methodSpecBuilder, "contributor");
        if (di.getType().equals(Type.SET)) {
            methodSpecBuilder.addStatement("result.add(contributor)");
        } else {
            Preconditions.checkState(di.getType().equals(Type.SET_VALUES));
            methodSpecBuilder.addStatement("result.addAll(contributor)");
        }
        methodSpecBuilder.endControlFlow();
    }
    methodSpecBuilder.addStatement("return result");
    componentSpecBuilder.addMethod(methodSpecBuilder.build());
// messager.printMessage(Kind.NOTE, String.format(
// "generateSetTypeProvisionMethodFromModule: \n key: %s, \n injector: %s, \n method: %s.",
// key, injectorClassName, methodSpecBuilder.build()));
}
Also used : ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) MethodSpec(com.squareup.javapoet.MethodSpec) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 19 with ClassName

use of com.squareup.javapoet.ClassName in project tiger by google.

the class NewInjectorGenerator method getInjectorFor.

/**
   * For all bindings but single contributor of a multi-binding, which is handled by
   * {@link #getPackagedInjectorForNewDependencyInfo(NewBindingKey, NewDependencyInfo)} . For
   * generic binding, package of referencing class has access to both raw type and parameter types,
   * though the provision method generated for it will be duplicated in each such package.
   */
private ClassName getInjectorFor(NewBindingKey key, TypeElement referencingClass) {
    ClassName result = null;
    TypeElement scope = scopeCalculator.calculate(key);
    NewDependencyInfo dependencyInfo = Iterables.getFirst(Utils.getDependencyInfo(dependencies, key), null);
    // System.out.println("getInjectorFor: " + key + " dependencyInfo: "
    // + dependencyInfo);
    String packageString = null;
    boolean isMultiBinding = false;
    if (dependencyInfo != null) {
        isMultiBinding = dependencyInfo.isMultiBinding();
        packageString = Utils.getPackage(dependencyInfo.getSourceClassElement()).getQualifiedName().toString();
    } else if (Utils.hasBuiltinBinding(key)) {
        result = getInjectorFor(Utils.getElementKeyForBuiltinBinding(key), referencingClass);
    } else {
        NewDependencyInfo genericNewDependencyInfo = Utils.getDependencyInfoByGeneric(dependencies, key);
        if (genericNewDependencyInfo != null) {
            packageString = Utils.getPackageString(referencingClass);
        } else {
            errors.add(String.format("Cannot resolve %s.", key));
            throw new RuntimeException(errors.toString());
        }
    }
    if (result == null) {
        String simpleName = isMultiBinding ? Utils.getMultiBindingInjectorSimpleName(scope) : Utils.getPackagedInjectorSimpleName(scope);
        result = ClassName.get(isMultiBinding ? topLevelPackageString : packageString, simpleName);
    }
    return result;
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ClassName(com.squareup.javapoet.ClassName)

Example 20 with ClassName

use of com.squareup.javapoet.ClassName in project tiger by google.

the class NewInjectorGenerator method generateTopLevelInjectors.

private void generateTopLevelInjectors() {
    SetMultimap<NewBindingKey, ClassName> keyToPackagedInjectorMap = Utils.reverseSetMultimap(generatedBindingsForPackagedInjector);
    // messager.printMessage(Kind.NOTE,
    // "generatedBindingsForPackagedInjector: " + generatedBindingsForPackagedInjector);
    // messager.printMessage(Kind.NOTE, "keyToPackagedInjectorMap: " + keyToPackagedInjectorMap);
    Set<ClassName> topLevelInjectedClassNames = new HashSet<>();
    for (ComponentInfo component : orderedComponents) {
        TypeSpec.Builder injectorBuilder = TypeSpec.classBuilder(getTopLevelInjectorName(component)).addAnnotation(AnnotationSpec.builder(Generated.class).addMember("value", "$S", GENERATOR_NAME).build()).addModifiers(Modifier.PUBLIC);
        // Member injector interfaces.
        for (TypeElement injector : memberInjectors.get(component)) {
            injectorBuilder.addSuperinterface(TypeName.get(injector.asType()));
        }
        MethodSpec.Builder ctorBuilder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
        // Containing top level injector.
        String containingInjectorName = "containingInjector";
        if (componentTree.get(component) != null) {
            ClassName containingInjectorClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(componentTree.get(component)));
            injectorBuilder.addField(containingInjectorClassName, containingInjectorName, Modifier.PRIVATE);
            ctorBuilder.addParameter(containingInjectorClassName, containingInjectorName).addStatement("this.$L = $L", containingInjectorName, containingInjectorName);
        }
        // Passed modules.
        Set<TypeElement> allPassedModules = new HashSet<>();
        allPassedModules.addAll(nonNullaryCtorModules.get(component));
        allPassedModules.addAll(nonNullaryCtorUnscopedModules);
        for (TypeElement passedModule : Utils.sortByFullName(allPassedModules)) {
            String moduleName = Utils.getSourceCodeName(passedModule);
            ClassName moduleTypeName = (ClassName) TypeName.get(passedModule.asType());
            ctorBuilder.addParameter(moduleTypeName, moduleName).addStatement("this.$N = $N", moduleName, moduleName);
            injectorBuilder.addField(moduleTypeName, moduleName, Modifier.PRIVATE).addMethod(MethodSpec.methodBuilder(Utils.getGetMethodName(moduleTypeName)).addModifiers(Modifier.PUBLIC).returns(moduleTypeName).addStatement("return $N", moduleName).build());
        }
        injectorBuilder.addMethod(ctorBuilder.build());
        // Injection methods and non-injection methods.
        Set<String> miscMethodNames = new HashSet<>();
        Set<TypeElement> allMembersInjectors = Sets.newHashSet(memberInjectors.get(component));
        while (!allMembersInjectors.isEmpty()) {
            TypeElement injector = Iterables.getFirst(allMembersInjectors, null);
            Preconditions.checkNotNull(injector, String.format("Empty allMembersInjector."));
            allMembersInjectors.remove(injector);
            for (TypeMirror parentInterface : injector.getInterfaces()) {
                allMembersInjectors.add((TypeElement) ((DeclaredType) parentInterface).asElement());
            }
            for (Element element : injector.getEnclosedElements()) {
                if (!element.getKind().equals(ElementKind.METHOD)) {
                    continue;
                }
                // Injection methods.
                if (Utils.isInjectionMethod(element)) {
                    ExecutableElement method = (ExecutableElement) element;
                    TypeMirror typeMirror = Iterables.getOnlyElement(method.getParameters()).asType();
                    if (typeMirror.getKind().equals(TypeKind.TYPEVAR)) {
                        // TODO(freeman): support generic injection method.
                        continue;
                    }
                    TypeElement cls = (TypeElement) ((DeclaredType) typeMirror).asElement();
                    if (!topLevelInjectedClassNames.add(ClassName.get(cls))) {
                        continue;
                    }
                    ClassName packagedInjectorClassName = getPackagedInjectorNameOfScope(Utils.getPackageString(cls), component.getScope());
                    injectorBuilder.addMethod(MethodSpec.methodBuilder(method.getSimpleName().toString()).addModifiers(Modifier.PUBLIC).addParameter(ClassName.get(cls), "arg").addStatement("$L().inject(arg)", Utils.getGetMethodName(packagedInjectorClassName)).build());
                } else if (Utils.isProvisionMethodInInjector(element)) {
                    // non-injection methods, provision methods or getSubComponent method in
                    // editors. NOTE(freeman): subcomponent should be converted to component.
                    ExecutableElement method = (ExecutableElement) element;
                    if (!miscMethodNames.add(method.getSimpleName().toString())) {
                        continue;
                    }
                    MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getSimpleName().toString()).addModifiers(Modifier.PUBLIC).returns(TypeName.get(method.getReturnType()));
                    NewBindingKey providedKey = Utils.getKeyProvidedByMethod(method);
                    ClassName packagedInjectorClassName = null;
                    for (ClassName className : keyToPackagedInjectorMap.get(providedKey)) {
                        if (isInjectorOfScope(className, component.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().$L()";
                        methodBuilder.addStatement(statement, Utils.getGetMethodName(packagedInjectorClassName), getProvisionMethodName(providedKey));
                    }
                    // System.out.println("provision method added: " + methodBuilder.build());
                    injectorBuilder.addMethod(methodBuilder.build());
                } else {
                    messager.printMessage(Kind.WARNING, String.format("Element %s ignored from injector %s.", element, injector));
                }
            }
        }
        // Methods to get injectors.
        for (Map.Entry<ClassName, TypeSpec.Builder> entry : packagedInjectorBuilders.entrySet()) {
            ClassName injectorClassName = entry.getKey();
            if (!component.equals(getComponentFromPackagedInjectorClassName(injectorClassName))) {
                continue;
            }
            String packagedInjectorSourceCodeName = Utils.getSourceCodeName(injectorClassName);
            injectorBuilder.addField(injectorClassName, packagedInjectorSourceCodeName, Modifier.PRIVATE);
            MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(Utils.getGetMethodName(injectorClassName)).addModifiers(Modifier.PUBLIC).returns(injectorClassName).addStatement("$T result = $N", injectorClassName, packagedInjectorSourceCodeName).beginControlFlow("if (result == null)");
            StringBuilder stringBuilder = new StringBuilder("result = $N = new $T(this");
            if (componentTree.get(component) != null) {
                ClassName containingPackageInjectorClassName = getInjectorNameOfScope(injectorClassName, componentTree.get(component).getScope());
                stringBuilder.append(", ").append(containingInjectorName).append(".").append(Utils.getGetMethodName(containingPackageInjectorClassName)).append("()");
            }
            stringBuilder.append(")");
            methodSpecBuilder.addStatement(stringBuilder.toString(), packagedInjectorSourceCodeName, injectorClassName);
            methodSpecBuilder.endControlFlow().addStatement("return result");
            injectorBuilder.addMethod(methodSpecBuilder.build());
        }
        generateInjectorBuilder(component, injectorBuilder);
        JavaFile javaFile = JavaFile.builder(topLevelPackageString, injectorBuilder.build()).build();
        try {
            javaFile.writeTo(processingEnv.getFiler());
        } catch (IOException e) {
            Throwables.propagate(e);
        }
    }
}
Also used : PackageElement(javax.lang.model.element.PackageElement) 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) TypeKind(javax.lang.model.type.TypeKind) TypeMirror(javax.lang.model.type.TypeMirror) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) HashSet(java.util.HashSet) MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) IOException(java.io.IOException) JavaFile(com.squareup.javapoet.JavaFile) HashMap(java.util.HashMap) Map(java.util.Map) TypeSpec(com.squareup.javapoet.TypeSpec) DeclaredType(javax.lang.model.type.DeclaredType)

Aggregations

ClassName (com.squareup.javapoet.ClassName)99 TypeSpec (com.squareup.javapoet.TypeSpec)60 MethodSpec (com.squareup.javapoet.MethodSpec)41 TypeElement (javax.lang.model.element.TypeElement)37 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)35 TypeName (com.squareup.javapoet.TypeName)30 Element (javax.lang.model.element.Element)19 TypeMirror (javax.lang.model.type.TypeMirror)17 Builder (com.squareup.javapoet.TypeSpec.Builder)16 FieldSpec (com.squareup.javapoet.FieldSpec)15 ArrayList (java.util.ArrayList)15 CodeBlock (com.squareup.javapoet.CodeBlock)11 ExecutableElement (javax.lang.model.element.ExecutableElement)11 NotNull (org.jetbrains.annotations.NotNull)10 VariableElement (javax.lang.model.element.VariableElement)9 JavaFile (com.squareup.javapoet.JavaFile)8 Map (java.util.Map)8 WildcardTypeName (com.squareup.javapoet.WildcardTypeName)7 IOException (java.io.IOException)7 HashMap (java.util.HashMap)7