All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dagger.internal.codegen.binding.AnnotationExpression Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2016 The Dagger Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dagger.internal.codegen.binding;

import static androidx.room.compiler.processing.XTypeKt.isArray;
import static dagger.internal.codegen.binding.SourceFiles.classFileName;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock;
import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock;
import static dagger.internal.codegen.xprocessing.XAnnotationValues.characterLiteralWithSingleQuotes;
import static dagger.internal.codegen.xprocessing.XElements.getSimpleName;
import static dagger.internal.codegen.xprocessing.XTypes.asArray;
import static dagger.internal.codegen.xprocessing.XTypes.isTypeOf;

import androidx.room.compiler.processing.XAnnotation;
import androidx.room.compiler.processing.XAnnotationValue;
import androidx.room.compiler.processing.XType;
import androidx.room.compiler.processing.XTypeElement;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import dagger.internal.codegen.javapoet.TypeNames;

/**
 * Returns an expression creating an instance of the visited annotation type. Its parameter must be
 * a class as generated by {@link dagger.internal.codegen.writing.AnnotationCreatorGenerator}.
 *
 * 

Note that {@code AnnotationValue#toString()} is the source-code representation of the value * when used in an annotation, which is not always the same as the representation needed * when creating the value in a method body. * *

For example, inside an annotation, a nested array of {@code int}s is simply {@code {1, 2, 3}}, * but in code it would have to be {@code new int[] {1, 2, 3}}. */ public final class AnnotationExpression { private final XAnnotation annotation; private final ClassName creatorClass; AnnotationExpression(XAnnotation annotation) { this.annotation = annotation; this.creatorClass = getAnnotationCreatorClassName(annotation.getType().getTypeElement()); } /** * Returns an expression that calls static methods on the annotation's creator class to create an * annotation instance equivalent the annotation passed to the constructor. */ CodeBlock getAnnotationInstanceExpression() { return getAnnotationInstanceExpression(annotation); } private CodeBlock getAnnotationInstanceExpression(XAnnotation annotation) { return CodeBlock.of( "$T.$L($L)", creatorClass, createMethodName(annotation.getType().getTypeElement()), makeParametersCodeBlock( annotation.getAnnotationValues().stream() .map(this::getValueExpression) .collect(toImmutableList()))); } /** * Returns the name of the generated class that contains the static {@code create} methods for an * annotation type. */ public static ClassName getAnnotationCreatorClassName(XTypeElement annotationType) { ClassName annotationTypeName = annotationType.getClassName(); return annotationTypeName .topLevelClassName() .peerClass(classFileName(annotationTypeName) + "Creator"); } public static String createMethodName(XTypeElement annotationType) { return "create" + getSimpleName(annotationType); } /** * Returns an expression that evaluates to a {@code value} of a given type on an {@code * annotation}. */ CodeBlock getValueExpression(XAnnotationValue value) { if (isArray(value.getValueType())) { XType componentType = asArray(value.getValueType()).getComponentType(); return CodeBlock.of( "new $T[] {$L}", // TODO(b/264464791): The KClass -> Class swap can be removed once this bug is fixed. isTypeOf(componentType, TypeNames.KCLASS) ? TypeNames.CLASS : componentType.getRawType().getTypeName(), value.asAnnotationValueList().stream() .map(this::getValueExpression) .collect(toParametersCodeBlock())); } else if (value.hasEnumValue()) { return CodeBlock.of( "$T.$L", value.asEnum().getEnclosingElement().getClassName(), getSimpleName(value.asEnum())); } else if (value.hasAnnotationValue()) { return getAnnotationInstanceExpression(value.asAnnotation()); } else if (value.hasTypeValue()) { return CodeBlock.of("$T.class", value.asType().getTypeElement().getClassName()); } else if (value.hasStringValue()) { return CodeBlock.of("$S", value.asString()); } else if (value.hasByteValue()) { return CodeBlock.of("(byte) $L", value.asByte()); } else if (value.hasCharValue()) { // TODO(bcorso): Replace when https://github.com/square/javapoet/issues/698 is fixed. return CodeBlock.of("$L", characterLiteralWithSingleQuotes(value.asChar())); } else if (value.hasDoubleValue()) { return CodeBlock.of("$LD", value.asDouble()); } else if (value.hasFloatValue()) { return CodeBlock.of("$LF", value.asFloat()); } else if (value.hasLongValue()) { return CodeBlock.of("$LL", value.asLong()); } else if (value.hasShortValue()) { return CodeBlock.of("(short) $L", value.asShort()); } else { return CodeBlock.of("$L", value.getValue()); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy