| /* |
| * 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.base; |
| |
| import static com.google.common.base.Preconditions.checkArgument; |
| import static javax.lang.model.util.ElementFilter.methodsIn; |
| |
| import com.google.auto.common.MoreTypes; |
| import com.google.common.base.Functions; |
| import com.google.common.base.Joiner; |
| import com.google.common.collect.FluentIterable; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.Maps; |
| import java.util.Map; |
| import javax.lang.model.element.AnnotationMirror; |
| import javax.lang.model.element.AnnotationValue; |
| import javax.lang.model.element.ElementKind; |
| import javax.lang.model.element.ExecutableElement; |
| import javax.lang.model.element.TypeElement; |
| import javax.lang.model.type.DeclaredType; |
| |
| /** A representation of an annotation. */ |
| public final class SimpleAnnotationMirror implements AnnotationMirror { |
| private final TypeElement annotationType; |
| private final ImmutableMap<String, ? extends AnnotationValue> namedValues; |
| private final ImmutableMap<ExecutableElement, ? extends AnnotationValue> elementValues; |
| |
| private SimpleAnnotationMirror( |
| TypeElement annotationType, Map<String, ? extends AnnotationValue> namedValues) { |
| checkArgument( |
| annotationType.getKind().equals(ElementKind.ANNOTATION_TYPE), |
| "annotationType must be an annotation: %s", |
| annotationType); |
| checkArgument( |
| FluentIterable.from(methodsIn(annotationType.getEnclosedElements())) |
| .transform(element -> element.getSimpleName().toString()) |
| .toSet() |
| .equals(namedValues.keySet()), |
| "namedValues must have values for exactly the members in %s: %s", |
| annotationType, |
| namedValues); |
| this.annotationType = annotationType; |
| this.namedValues = ImmutableMap.copyOf(namedValues); |
| this.elementValues = |
| Maps.toMap( |
| methodsIn(annotationType.getEnclosedElements()), |
| Functions.compose( |
| Functions.forMap(namedValues), element -> element.getSimpleName().toString())); |
| } |
| |
| @Override |
| public DeclaredType getAnnotationType() { |
| return MoreTypes.asDeclared(annotationType.asType()); |
| } |
| |
| @Override |
| public Map<ExecutableElement, ? extends AnnotationValue> getElementValues() { |
| return elementValues; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder builder = new StringBuilder("@").append(annotationType.getQualifiedName()); |
| if (!namedValues.isEmpty()) { |
| builder |
| .append('(') |
| .append(Joiner.on(", ").withKeyValueSeparator(" = ").join(namedValues)) |
| .append(')'); |
| } |
| return builder.toString(); |
| } |
| |
| /** |
| * An object representing an annotation instance. |
| * |
| * @param annotationType must be an annotation type with no members |
| */ |
| public static AnnotationMirror of(TypeElement annotationType) { |
| return of(annotationType, ImmutableMap.<String, AnnotationValue>of()); |
| } |
| |
| /** |
| * An object representing an annotation instance. |
| * |
| * @param annotationType must be an annotation type |
| * @param namedValues a value for every annotation member, including those with defaults, indexed |
| * by simple name |
| */ |
| private static AnnotationMirror of( |
| TypeElement annotationType, Map<String, ? extends AnnotationValue> namedValues) { |
| return new SimpleAnnotationMirror(annotationType, namedValues); |
| } |
| } |