Search in sources :

Example 21 with DeclaredType

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

the class TigerDaggerGeneratorProcessor method getScopeForComponent.

/**
   * Returns scope for the give dagger Component, null is unscoped. The result is either
   * explicitly specified or implicitly inherited from one of the ancestors.
   */
@Nullable
private TypeElement getScopeForComponent(TypeElement component) {
    DeclaredType scope = Utils.getScopeType(component);
    if (scope != null) {
        return (TypeElement) scope.asElement();
    }
    AnnotationMirror componentAnnotationMirror = Utils.getAnnotationMirror(component, Component.class);
    List<AnnotationValue> dependencies = (List<AnnotationValue>) Utils.getAnnotationValue(componentAnnotationMirror, "dependencies");
    if (dependencies == null) {
        return null;
    }
    Set<TypeElement> parentScopes = new HashSet<>();
    for (AnnotationValue dependency : dependencies) {
        DeclaredType dependencyClass = (DeclaredType) dependency.getValue();
        TypeElement parentScope = getScopeForComponent((TypeElement) dependencyClass.asElement());
        if (parentScope != null) {
            parentScopes.add(parentScope);
        }
    }
    if (parentScopes.isEmpty()) {
        return null;
    }
    if (parentScopes.size() > 1) {
        messager.printMessage(Kind.ERROR, String.format("Component %s depends on more than one scoped components. The scopes are: %s", component, parentScopes));
    }
    return Iterables.getOnlyElement(parentScopes);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeElement(javax.lang.model.element.TypeElement) AnnotationValue(javax.lang.model.element.AnnotationValue) ArrayList(java.util.ArrayList) List(java.util.List) DeclaredType(javax.lang.model.type.DeclaredType) HashSet(java.util.HashSet) Nullable(javax.annotation.Nullable)

Example 22 with DeclaredType

use of javax.lang.model.type.DeclaredType 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)

Example 23 with DeclaredType

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

the class NewInjectorGenerator method generateAll.

private void generateAll() {
    for (ComponentInfo component : orderedComponents) {
        Set<ClassName> injected = 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 method : injector.getEnclosedElements()) {
                if (Utils.isInjectionMethod(method)) {
                    VariableElement var = Iterables.getOnlyElement(((ExecutableElement) method).getParameters());
                    if (var.asType().getKind().equals(TypeKind.TYPEVAR)) {
                        // TODO(freeman): support generic injection method.
                        continue;
                    }
                    TypeElement varTypeElement = (TypeElement) ((DeclaredType) var.asType()).asElement();
                    if (!injected.add(ClassName.get(varTypeElement))) {
                        continue;
                    }
                    generateInjectionMethod(varTypeElement, component.getScope());
                } else if (Utils.isProvisionMethodInInjector(method)) {
                    generateProvisionMethodIfNeeded(Utils.getKeyProvidedByMethod((ExecutableElement) method), injector);
                } else {
                    messager.printMessage(Kind.WARNING, String.format("Unknown element %s from injector %s.", method, injector));
                }
            }
        }
    }
    for (ComponentInfo component : orderedComponents) {
        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);
        }
    }
    for (ComponentInfo component : orderedComponents) {
        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);
        }
    }
    generateTopLevelInjectors();
}
Also used : TypeElement(javax.lang.model.element.TypeElement) 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) Builder(com.squareup.javapoet.TypeSpec.Builder) VariableElement(javax.lang.model.element.VariableElement) IOException(java.io.IOException) TypeMirror(javax.lang.model.type.TypeMirror) Builder(com.squareup.javapoet.TypeSpec.Builder) ClassName(com.squareup.javapoet.ClassName) JavaFile(com.squareup.javapoet.JavaFile) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet) DeclaredType(javax.lang.model.type.DeclaredType) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 24 with DeclaredType

use of javax.lang.model.type.DeclaredType in project j2objc by google.

the class TypeUtil method getSuperclass.

public DeclaredType getSuperclass(TypeMirror t) {
    List<? extends TypeMirror> supertypes = directSupertypes(t);
    if (supertypes.isEmpty()) {
        return null;
    }
    TypeMirror first = supertypes.get(0);
    if (getDeclaredTypeKind(first).isClass()) {
        return (DeclaredType) first;
    }
    return null;
}
Also used : AbstractTypeMirror(com.google.devtools.j2objc.types.AbstractTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) DeclaredType(javax.lang.model.type.DeclaredType)

Example 25 with DeclaredType

use of javax.lang.model.type.DeclaredType in project j2objc by google.

the class EnhancedForRewriter method boxLoopVariable.

private void boxLoopVariable(EnhancedForStatement node, TypeMirror expressionType, VariableElement loopVariable) {
    DeclaredType iterableType = typeUtil.findSupertype(expressionType, "java.lang.Iterable");
    List<? extends TypeMirror> typeArgs = iterableType.getTypeArguments();
    assert typeArgs.size() == 1 && typeUtil.isBoxedType(typeArgs.get(0));
    VariableElement boxVariable = GeneratedVariableElement.newLocalVar("boxed__", typeArgs.get(0), null);
    node.setParameter(new SingleVariableDeclaration(boxVariable));
    makeBlock(node.getBody()).addStatement(0, new VariableDeclarationStatement(loopVariable, new SimpleName(boxVariable)));
}
Also used : SingleVariableDeclaration(com.google.devtools.j2objc.ast.SingleVariableDeclaration) SimpleName(com.google.devtools.j2objc.ast.SimpleName) VariableDeclarationStatement(com.google.devtools.j2objc.ast.VariableDeclarationStatement) VariableElement(javax.lang.model.element.VariableElement) GeneratedVariableElement(com.google.devtools.j2objc.types.GeneratedVariableElement) DeclaredType(javax.lang.model.type.DeclaredType)

Aggregations

DeclaredType (javax.lang.model.type.DeclaredType)138 TypeElement (javax.lang.model.element.TypeElement)82 TypeMirror (javax.lang.model.type.TypeMirror)75 ExecutableElement (javax.lang.model.element.ExecutableElement)38 Element (javax.lang.model.element.Element)28 VariableElement (javax.lang.model.element.VariableElement)26 AnnotationMirror (javax.lang.model.element.AnnotationMirror)19 Test (org.junit.Test)19 ArrayType (javax.lang.model.type.ArrayType)15 ArrayList (java.util.ArrayList)14 List (java.util.List)10 Map (java.util.Map)9 AbstractJClass (com.helger.jcodemodel.AbstractJClass)8 HashSet (java.util.HashSet)8 AnnotationValue (javax.lang.model.element.AnnotationValue)8 HashMap (java.util.HashMap)6 TypeParameterElement (javax.lang.model.element.TypeParameterElement)6 Types (javax.lang.model.util.Types)6 Name (javax.lang.model.element.Name)5 PackageElement (javax.lang.model.element.PackageElement)5