use of javax.lang.model.element.ExecutableElement 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);
}
}
}
use of javax.lang.model.element.ExecutableElement 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();
}
use of javax.lang.model.element.ExecutableElement in project tiger by google.
the class NewDependencyCollector method collectFromInjectedMembersRecursively.
/**
* Collects dependencies of the give {@link TypeElement} from the injected
* members, either fields or methods, of the {@link TypeElement}.
*/
private Set<NewBindingKey> collectFromInjectedMembersRecursively(TypeElement classElement) {
Preconditions.checkArgument(Utils.findInjectedCtor(classElement, env) == null, String.format("class %s should not have injected ctor", classElement));
Set<NewBindingKey> dependencies = new HashSet<>();
TypeMirror superMirror = classElement.getSuperclass();
if (!superMirror.getKind().equals(TypeKind.NONE)) {
TypeElement parent = (TypeElement) ((DeclaredType) superMirror).asElement();
dependencies = collectFromInjectedMembersRecursively(parent);
}
for (Element element : classElement.getEnclosedElements()) {
if (element.getKind().equals(ElementKind.FIELD) && Utils.isInjected(element, env)) {
dependencies.add(NewBindingKey.get(element.asType(), Utils.getQualifier(element)));
}
if (element.getKind().equals(ElementKind.METHOD) && Utils.isInjected(element, env)) {
dependencies.addAll(getDependenciesFrom((ExecutableElement) element));
}
}
return dependencies;
}
use of javax.lang.model.element.ExecutableElement in project tiger by google.
the class NewDependencyCollector method collectFromModule.
/**
* Collects dependencies from a given {@link dagger.Module}. Type.SET and
* Type.SET_VALUES are put together with Key.get(Set<elementType>, annotation)
* for easier later processing.
*/
private Collection<NewDependencyInfo> collectFromModule(TypeElement module) {
Collection<NewDependencyInfo> result = new HashSet<>();
for (Element e : module.getEnclosedElements()) {
if (!Utils.isProvidesMethod(e, env)) {
continue;
}
ExecutableElement executableElement = (ExecutableElement) e;
TypeMirror returnType = executableElement.getReturnType();
TypeKind returnTypeKind = returnType.getKind();
Preconditions.checkState(returnTypeKind.isPrimitive() || returnTypeKind.equals(TypeKind.DECLARED) || returnTypeKind.equals(TypeKind.ARRAY), String.format("Unexpected type %s from method %s in module %s.", returnTypeKind, executableElement, module));
if (!Utils.isBindableType(returnType)) {
errors.add(String.format("Unbindable type found: %s from module %s by method %s", returnType, module, executableElement));
}
AnnotationMirror annotation = Utils.getQualifier(executableElement);
NewBindingKey key = NewBindingKey.get(returnType, annotation);
List<NewBindingKey> keys = Utils.getDependenciesFromExecutableElement(executableElement);
Provides.Type provideType = Utils.getProvidesType(executableElement);
if (Provides.Type.SET.equals(provideType)) {
key = NewBindingKey.get(ParameterizedTypeName.get(ClassName.get(Set.class), key.getTypeName()), annotation);
} else if (Provides.Type.MAP.equals(provideType)) {
AnnotationMirror mapKeyedMirror = Preconditions.checkNotNull(Utils.getMapKey(executableElement), String.format("Map binding %s missed MapKey.", executableElement));
AnnotationMirror mapKeyMirror = Utils.getAnnotationMirror(mapKeyedMirror.getAnnotationType().asElement(), MapKey.class);
AnnotationValue unwrapValue = Utils.getAnnotationValue(mapKeyMirror, "unwrapValue");
if (unwrapValue != null && !((Boolean) unwrapValue.getValue())) {
messager.printMessage(Kind.ERROR, String.format("MapKey with unwrapValue false is not supported, yet. Biding: %s", executableElement));
}
TypeMirror keyTypeMirror = Preconditions.checkNotNull(Utils.getElementTypeMirror(mapKeyedMirror, "value"), String.format("Get key type failed for binding %s", executableElement));
TypeMirror valueTypeMirror = executableElement.getReturnType();
AnnotationMirror qualifier = Utils.getQualifier(executableElement);
key = NewBindingKey.get(ParameterizedTypeName.get(ClassName.get(Map.class), TypeName.get(keyTypeMirror), TypeName.get(valueTypeMirror)), qualifier);
}
NewDependencyInfo newDependencyInfo = new NewDependencyInfo(key, Sets.newHashSet(keys), module, executableElement, provideType);
result.add(newDependencyInfo);
}
// messager.printMessage(Kind.NOTE, String.format("collectFromModule: result: %s", result));
return result;
}
use of javax.lang.model.element.ExecutableElement in project j2objc by google.
the class ElementReferenceMapper method endVisit.
//TODO(malvania): Add the field type class to reference classes.
//Currently, jdt only supports well known types. Soon, we can get type mirror from field
//and resolve the type by its name using a resolve method in the parser environment.
@Override
public void endVisit(VariableDeclarationFragment fragment) {
//TODO(malvania): Add field to elementReferenceMap when field detection is enabled and the
// ElementUtil.getBinaryName() method doesn't break when called on a static block's
// ExecutableElement.
//String fieldID = stitchFieldIdentifier(fragment);
//elementReferenceMap.putIfAbsent(fieldID, new FieldReferenceNode(fragment));
Element element = fragment.getVariableElement().getEnclosingElement();
if (element instanceof TypeElement) {
TypeElement type = (TypeElement) element;
if (ElementUtil.isPublic(fragment.getVariableElement())) {
ClassReferenceNode node = (ClassReferenceNode) elementReferenceMap.get(stitchClassIdentifier(type));
if (node == null) {
node = new ClassReferenceNode(type);
}
node.containsPublicField = true;
elementReferenceMap.putIfAbsent(stitchClassIdentifier(type), node);
}
}
}
Aggregations