Search in sources :

Example 26 with Builder

use of com.squareup.javapoet.TypeSpec.Builder in project tiger by google.

the class NewInjectorGenerator method generateInjectorBuilder.

private void generateInjectorBuilder(ComponentInfo componentInfo, TypeSpec.Builder injectorBuilder) {
    TypeSpec.Builder builderBuilder = TypeSpec.classBuilder("Builder").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
    ClassName injectorClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(componentInfo));
    boolean hasParent = componentTree.get(componentInfo) != null;
    ClassName parentClassName = null;
    // set parent inject methods.
    if (hasParent) {
        parentClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(componentTree.get(componentInfo)));
        Utils.addSetMethod(injectorClassName, builderBuilder, parentClassName);
    }
    /**
     * Set module methods. Theoretically, is a passed module is needed by a injector should be
     * decided by whether it is needed. Here is just a simpler way. All scoped modules go to
     * injector of the same scope. All unscoped modules go to every injector. It is not possible to
     * have modules of different scope in a injector. This way the modules created is a superset of
     * what are required. But that's fine because null can be passed in for modules not needed. This
     * is even unnoticeable when using builder to create injector. The null module is just never
     * referenced. Otherwise it is a bug, sadly it is not caught until runtime. This makes it easier
     * to create wrapper component defined dagger around core injectors. Anyway, passed module is
     * not a good idea and could/should be removed.
     */
    List<TypeElement> allNonNullaryCtorModules = new ArrayList<>();
    allNonNullaryCtorModules.addAll(nonNullaryCtorModules.get(componentInfo));
    allNonNullaryCtorModules.addAll(nonNullaryCtorUnscopedModules);
    for (TypeElement m : allNonNullaryCtorModules) {
        Utils.addSetMethod(injectorClassName, builderBuilder, (ClassName) ClassName.get(m.asType()));
    }
    // build() method.
    MethodSpec.Builder buildMethodBuilder = MethodSpec.methodBuilder("build").addModifiers(Modifier.PUBLIC).returns(injectorClassName);
    StringBuilder returnCodeBuilder = new StringBuilder("return new $T(");
    if (hasParent) {
        String parentInjectorFieldName = Utils.getSourceCodeName(parentClassName);
        returnCodeBuilder.append(parentInjectorFieldName);
        if (!allNonNullaryCtorModules.isEmpty()) {
            returnCodeBuilder.append(", ");
        }
    }
    if (!allNonNullaryCtorModules.isEmpty()) {
        for (TypeElement module : Utils.sortByFullName(allNonNullaryCtorModules)) {
            String moduleFiledName = Utils.getSourceCodeName(TypeName.get(module.asType()));
            returnCodeBuilder.append(moduleFiledName).append(", ");
        }
        int size = returnCodeBuilder.length();
        returnCodeBuilder.delete(size - 2, size);
    }
    returnCodeBuilder.append(");");
    buildMethodBuilder.addCode(returnCodeBuilder.toString(), injectorClassName);
    builderBuilder.addMethod(buildMethodBuilder.build());
    injectorBuilder.addType(builderBuilder.build());
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) ArrayList(java.util.ArrayList) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 27 with Builder

use of com.squareup.javapoet.TypeSpec.Builder in project tiger by google.

the class GeneralInjectorGenerator method createInjectorBuilder.

protected final Builder createInjectorBuilder() {
    String injectorSimpleName = getInjectorSimpleName();
    logger.n("generated component " + injectorSimpleName);
    Builder result = TypeSpec.classBuilder(injectorSimpleName).addModifiers(Modifier.PUBLIC).addAnnotation(AnnotationSpec.builder(Generated.class).addMember("value", "$S", GENERATOR_NAME).build());
    for (TypeName typeName : getSuperInterfaces()) {
        result.addSuperinterface(typeName);
    }
    return result;
}
Also used : ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) Generated(javax.annotation.Generated) Builder(com.squareup.javapoet.TypeSpec.Builder)

Example 28 with Builder

use of com.squareup.javapoet.TypeSpec.Builder in project tiger by google.

the class CoreInjectorGenerator method generateTopLevelInjectors.

private void generateTopLevelInjectors() {
    messager.printMessage(Kind.NOTE, "generateTopLevelInjectors");
    SetMultimap<BindingKey, ClassName> keyToPackagedInjectorMap = utils.reverseSetMultimap(generatedBindingsForPackagedInjector);
    for (CoreInjectorInfo coreInjectorInfo : orderedCoreinjectors) {
        TypeSpec.Builder injectorBuilder = TypeSpec.classBuilder(getTopLevelInjectorName(coreInjectorInfo, topLevelInjectorPrefix, topLevelInjectorSuffix)).addAnnotation(AnnotationSpec.builder(Generated.class).addMember("value", "$S", GENERATOR_NAME).build()).addModifiers(Modifier.PUBLIC);
        // method simple name and type.
        Set<Pair<String, TypeName>> injectionMethodsDone = new HashSet<>();
        // Member injector interfaces.
        for (TypeElement injector : coreInjectorToComponentMap.get(coreInjectorInfo)) {
            injectorBuilder.addSuperinterface(TypeName.get(injector.asType()));
        }
        // Ctor
        MethodSpec.Builder ctorBuilder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
        ctorBuilder.addStatement("$T.out.printf($S, $L)", ClassName.get(System.class), "This is tiger: %s\n", "this");
        // Ctor - Containing top level injector.
        // TODO: remove this .
        String containingInjectorName = "containingInjector";
        if (componentTree.get(coreInjectorInfo) != null) {
            ClassName containingInjectorClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(componentTree.get(coreInjectorInfo), topLevelInjectorPrefix, topLevelInjectorSuffix));
            injectorBuilder.addField(containingInjectorClassName, containingInjectorName, Modifier.PRIVATE);
            ctorBuilder.addParameter(containingInjectorClassName, containingInjectorName).addStatement("this.$L = $L", containingInjectorName, containingInjectorName);
        }
        // Ctor - ancester top level injectors.
        CoreInjectorInfo tmp = coreInjectorInfo;
        while (componentTree.get(tmp) != null) {
            tmp = componentTree.get(tmp);
            ClassName className = ClassName.get(topLevelPackageString, getTopLevelInjectorName(tmp, topLevelInjectorPrefix, topLevelInjectorSuffix));
            String sourceCodeName = utils.getSourceCodeName(className);
            injectorBuilder.addField(className, sourceCodeName);
            if (tmp.equals(componentTree.get(coreInjectorInfo))) {
                ctorBuilder.addStatement("this.$L = $L", sourceCodeName, containingInjectorName);
            } else {
                ctorBuilder.addStatement("this.$L = $L.$L", sourceCodeName, containingInjectorName, sourceCodeName);
            }
        }
        // Ctor - Component dependencies
        for (TypeElement dep : utils.sortByFullName(coreInjectorToComponentDependencyMap.get(coreInjectorInfo))) {
            if (utils.isEitherComponent(dep)) {
                continue;
            }
            ClassName className = ClassName.get(dep);
            String sourceCodeName = utils.getSourceCodeName(className);
            injectorBuilder.addField(className, sourceCodeName, Modifier.PUBLIC);
            ctorBuilder.addParameter(className, sourceCodeName).addStatement("this.$L = $L", sourceCodeName, sourceCodeName);
        }
        // Ctor - @BindsInstance
        for (BindingKey key : utils.sortBindingKeys(coreInjectorToBindsInstanceMap.get(coreInjectorInfo))) {
            String sourceCodeName = utils.getSourceCodeNameHandlingBox(key, dependencies);
            injectorBuilder.addField(key.getTypeName(), sourceCodeName, Modifier.PUBLIC);
            ctorBuilder.addParameter(key.getTypeName(), sourceCodeName).addStatement("this.$L = $L", sourceCodeName, sourceCodeName);
        }
        // Ctor - Passed modules.
        Set<TypeElement> allPassedModules = new HashSet<>();
        allPassedModules.addAll(nonNullaryCtorModules.get(coreInjectorInfo));
        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(coreInjectorToComponentMap.get(coreInjectorInfo));
        for (TypeElement injector : allMembersInjectors) {
            for (Element element : processingEnv.getElementUtils().getAllMembers(injector)) {
                messager.printMessage(Kind.NOTE, "method: " + element);
                if (!element.getKind().equals(ElementKind.METHOD)) {
                    continue;
                }
                ExecutableElement method = (ExecutableElement) element;
                ExecutableType methodType = (ExecutableType) processingEnv.getTypeUtils().asMemberOf((DeclaredType) injector.asType(), 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);
                        continue;
                    }
                    TypeMirror typeMirror = Iterables.getOnlyElement(methodType.getParameterTypes());
                    TypeElement cls = (TypeElement) ((DeclaredType) typeMirror).asElement();
                    messager.printMessage(Kind.NOTE, TAG + ".generateTopLevelInjector-injection method : " + methodType);
                    ClassName packagedInjectorClassName = getPackagedInjectorNameOfScope(utils.getPackageString(cls), coreInjectorInfo.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.isComponentProvisionMethod(element)) {
                    messager.printMessage(Kind.ERROR, "Injecting components is not supported: " + element);
                } else if (utils.isSubcomponentProvisionMethod(element)) {
                    generateGetSubcomponentMethod((ExecutableElement) element, injectorBuilder);
                } else if (utils.isProvisionMethodInInjector(element)) {
                    if (!miscMethodNames.add(method.getSimpleName().toString())) {
                        continue;
                    }
                    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().$L()";
                        methodBuilder.addStatement(statement, utils.getGetMethodName(packagedInjectorClassName), 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, injector));
                }
            }
        }
        // Methods to get packaged injectors.
        for (Map.Entry<ClassName, TypeSpec.Builder> entry : packagedInjectorBuilders.entrySet()) {
            ClassName injectorClassName = entry.getKey();
            if (!coreInjectorInfo.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(coreInjectorInfo) != null) {
                ClassName containingPackageInjectorClassName = getInjectorNameOfScope(injectorClassName, componentTree.get(coreInjectorInfo).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());
        }
        // Builder and builder().
        generateInjectorBuilder(coreInjectorInfo, injectorBuilder);
        ClassName builderClassName = getTopLevelInjectorBuilderClassName(coreInjectorInfo);
        MethodSpec.Builder methodSpecBuilder = // "Dagger compatible component will have "builder()", we need a different name.
        MethodSpec.methodBuilder("getBuilder").addModifiers(Modifier.PUBLIC, Modifier.STATIC).returns(builderClassName).addStatement("return new $T()", builderClassName);
        injectorBuilder.addMethod(methodSpecBuilder.build());
        // provision methods for (sub)component builders that can be provided by this core injector.
        for (TypeElement b : coreInjectorToBothBuilderMap.get(coreInjectorInfo)) {
            generateImplicitProvisionMethodForEitherComponentBuilderInTopLevelInjector(injectorBuilder, b);
        }
        // Write
        JavaFile javaFile = JavaFile.builder(topLevelPackageString, injectorBuilder.build()).build();
        try {
            javaFile.writeTo(processingEnv.getFiler());
        } catch (IOException e) {
            messager.printMessage(Kind.ERROR, e.toString());
        }
    }
}
Also used : ExecutableType(javax.lang.model.type.ExecutableType) 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) 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) Pair(com.google.common.base.Pair) HashSet(java.util.HashSet) MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) IOException(java.io.IOException) JavaFile(com.squareup.javapoet.JavaFile) Map(java.util.Map) HashMap(java.util.HashMap) TypeSpec(com.squareup.javapoet.TypeSpec) DeclaredType(javax.lang.model.type.DeclaredType)

Example 29 with Builder

use of com.squareup.javapoet.TypeSpec.Builder in project tiger by google.

the class CoreInjectorGenerator method generatePackagedInjectors.

private void generatePackagedInjectors() {
    for (CoreInjectorInfo coreInjectorInfo : orderedCoreinjectors) {
        Set<ClassName> injected = new HashSet<>();
        Set<TypeElement> components = Sets.newHashSet(coreInjectorToComponentMap.get(coreInjectorInfo));
        for (TypeElement c : components) {
            for (Element e : elements.getAllMembers(c)) {
                messager.printMessage(Kind.NOTE, "generatePackagedInjectors: element: " + e);
                if (!utils.isMethod(e)) {
                    continue;
                }
                ExecutableElement method = (ExecutableElement) e;
                ExecutableType methodType = ((ExecutableType) types.asMemberOf(((DeclaredType) c.asType()), e));
                if (utils.isInjectionMethod(method)) {
                    TypeElement injectedTypeElement = (TypeElement) ((DeclaredType) Iterables.getOnlyElement(methodType.getParameterTypes())).asElement();
                    if (!injected.add(ClassName.get(injectedTypeElement))) {
                        continue;
                    }
                    messager.printMessage(Kind.NOTE, TAG + ".generatePackagedInjectors: injection method for: " + injectedTypeElement);
                    generateInjectionMethod(injectedTypeElement, coreInjectorInfo.getScope());
                } else if (utils.isProvisionMethodInInjector(method)) {
                    generateProvisionMethodIfNeeded(utils.getKeyProvidedByMethod((ExecutableElement) method), c);
                } else {
                    // TODO: ignore known elements like builders.
                    messager.printMessage(Kind.WARNING, String.format("Unknown element %s from injector %s.", method, c));
                }
            }
        }
    }
    messager.printMessage(Kind.NOTE, TAG + ".generatePackagedInjectors. packagedInjectorBuilders: " + packagedInjectorBuilders);
    // Inherited provision methods.
    for (CoreInjectorInfo component : orderedCoreinjectors) {
        if (componentTree.get(component) == null) {
            continue;
        }
        for (Map.Entry<ClassName, TypeSpec.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, TypeSpec.Builder> entry : packagedInjectorBuilders.entrySet()) {
            ClassName packagedInjectorClassName = entry.getKey();
            if (!component.equals(getComponentFromPackagedInjectorClassName(packagedInjectorClassName))) {
                continue;
            }
            generateInheritedInjectionMethods(packagedInjectorClassName);
        }
    }
    for (Map.Entry<ClassName, TypeSpec.Builder> entry : packagedInjectorBuilders.entrySet()) {
        String packageString = entry.getKey().packageName();
        TypeSpec.Builder builder = entry.getValue();
        JavaFile javaFile = JavaFile.builder(packageString, builder.build()).build();
        // messager.printMessage(Kind.NOTE, String.format("java 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) 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) Builder(com.squareup.javapoet.TypeSpec.Builder) IOException(java.io.IOException) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) JavaFile(com.squareup.javapoet.JavaFile) Map(java.util.Map) HashMap(java.util.HashMap) HashSet(java.util.HashSet) DeclaredType(javax.lang.model.type.DeclaredType) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 30 with Builder

use of com.squareup.javapoet.TypeSpec.Builder in project tiger by google.

the class CoreInjectorGenerator method generateInjectorBuilder.

private void generateInjectorBuilder(CoreInjectorInfo coreInjectorInfo, TypeSpec.Builder injectorBuilder) {
    TypeSpec.Builder builderBuilder = TypeSpec.classBuilder("Builder").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
    ClassName injectorClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(coreInjectorInfo, topLevelInjectorPrefix, topLevelInjectorSuffix));
    boolean hasParent = componentTree.get(coreInjectorInfo) != null;
    ClassName parentClassName = null;
    // set parent inject methods.
    if (hasParent) {
        parentClassName = ClassName.get(topLevelPackageString, getTopLevelInjectorName(componentTree.get(coreInjectorInfo), topLevelInjectorPrefix, topLevelInjectorSuffix));
        utils.addSetMethod(types, elements, injectorClassName, builderBuilder, parentClassName, getParentComponentSetterName(componentTree.get(coreInjectorInfo)));
    }
    for (TypeElement dep : coreInjectorToComponentDependencyMap.get(coreInjectorInfo)) {
        utils.addSetMethod(types, elements, injectorClassName, builderBuilder, (ClassName) ClassName.get(dep.asType()));
    }
    for (BindingKey key : coreInjectorToBindsInstanceMap.get(coreInjectorInfo)) {
        utils.addSetMethod(types, elements, injectorClassName, builderBuilder, key.getTypeName(), utils.getSourceCodeNameHandlingBox(key, dependencies));
    }
    /**
     * Set module methods. Theoretically, is a passed module is needed by a injector should be
     * decided by whether it is needed. Here is just a simpler way. All scoped modules go to
     * injector of the same scope. All unscoped modules go to every injector. It is not possible to
     * have modules of different scope in a injector. This way the modules created is a superset of
     * what are required. But that's fine because null can be passed in for modules not needed. This
     * is even unnoticeable when using builder to create injector. The null module is just never
     * referenced. Otherwise it is a bug, sadly it is not caught until runtime. This makes it easier
     * to create wrapper component defined dagger around core injectors. Anyway, passed module is
     * not a good idea and could/should be removed.
     */
    List<TypeElement> allNonNullaryCtorModules = new ArrayList<>();
    allNonNullaryCtorModules.addAll(nonNullaryCtorModules.get(coreInjectorInfo));
    allNonNullaryCtorModules.addAll(nonNullaryCtorUnscopedModules);
    for (TypeElement m : allNonNullaryCtorModules) {
        utils.addSetMethod(types, elements, injectorClassName, builderBuilder, (ClassName) ClassName.get(m.asType()));
    }
    // build() method.
    MethodSpec.Builder buildMethodBuilder = MethodSpec.methodBuilder("build").addModifiers(Modifier.PUBLIC).returns(injectorClassName);
    StringBuilder returnCodeBuilder = new StringBuilder("return new $T(");
    boolean needLeadingComma = false;
    if (hasParent) {
        needLeadingComma = true;
        String parentInjectorFieldName = utils.getSourceCodeName(parentClassName);
        returnCodeBuilder.append(parentInjectorFieldName);
    }
    Set<TypeElement> deps = coreInjectorToComponentDependencyMap.get(coreInjectorInfo);
    if (!deps.isEmpty()) {
        if (needLeadingComma) {
            returnCodeBuilder.append(", ");
        }
        needLeadingComma = true;
        for (TypeElement dep : utils.sortByFullName(deps)) {
            String parameterName = utils.getSourceCodeName(TypeName.get(dep.asType()));
            returnCodeBuilder.append(parameterName).append(", ");
        }
        int size = returnCodeBuilder.length();
        returnCodeBuilder.delete(size - 2, size);
    }
    Set<BindingKey> keys = coreInjectorToBindsInstanceMap.get(coreInjectorInfo);
    if (!keys.isEmpty()) {
        if (needLeadingComma) {
            returnCodeBuilder.append(", ");
        }
        needLeadingComma = true;
        for (BindingKey key : utils.sortBindingKeys(keys)) {
            String parameterName = utils.getSourceCodeNameHandlingBox(key, dependencies);
            returnCodeBuilder.append(parameterName).append(", ");
        }
        int size = returnCodeBuilder.length();
        returnCodeBuilder.delete(size - 2, size);
    }
    if (!allNonNullaryCtorModules.isEmpty()) {
        if (needLeadingComma) {
            returnCodeBuilder.append(", ");
        }
        needLeadingComma = true;
        for (TypeElement module : utils.sortByFullName(allNonNullaryCtorModules)) {
            String parameterName = utils.getSourceCodeName(TypeName.get(module.asType()));
            returnCodeBuilder.append(parameterName).append(", ");
        }
        int size = returnCodeBuilder.length();
        returnCodeBuilder.delete(size - 2, size);
    }
    returnCodeBuilder.append(");");
    buildMethodBuilder.addCode(returnCodeBuilder.toString(), injectorClassName);
    builderBuilder.addMethod(buildMethodBuilder.build());
    injectorBuilder.addType(builderBuilder.build());
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) TypeSpec(com.squareup.javapoet.TypeSpec)

Aggregations

Builder (com.squareup.javapoet.TypeSpec.Builder)42 ClassName (com.squareup.javapoet.ClassName)28 MethodSpec (com.squareup.javapoet.MethodSpec)25 TypeSpec (com.squareup.javapoet.TypeSpec)18 TypeElement (javax.lang.model.element.TypeElement)16 TypeName (com.squareup.javapoet.TypeName)14 ExecutableElement (javax.lang.model.element.ExecutableElement)13 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)12 IOException (java.io.IOException)7 PackageElement (javax.lang.model.element.PackageElement)7 VariableElement (javax.lang.model.element.VariableElement)7 TypeMirror (javax.lang.model.type.TypeMirror)7 JavaFile (com.squareup.javapoet.JavaFile)6 ArrayList (java.util.ArrayList)6 DeclaredType (javax.lang.model.type.DeclaredType)6 Element (javax.lang.model.element.Element)5 HashSet (java.util.HashSet)4 BindTypeBuilder (com.abubusoft.kripton.processor.bind.BindTypeBuilder)3 PrefsProperty (com.abubusoft.kripton.processor.sharedprefs.model.PrefsProperty)3 HashMap (java.util.HashMap)3