1 /* 2 * Copyright (C) 2015 Square, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.squareup.javapoet; 17 18 import java.io.IOException; 19 import java.lang.reflect.Type; 20 import java.util.ArrayList; 21 import java.util.Collections; 22 import java.util.List; 23 import java.util.Set; 24 import javax.lang.model.SourceVersion; 25 import javax.lang.model.element.ExecutableElement; 26 import javax.lang.model.element.Modifier; 27 import javax.lang.model.element.VariableElement; 28 29 import static com.squareup.javapoet.Util.checkArgument; 30 import static com.squareup.javapoet.Util.checkNotNull; 31 32 /** A generated parameter declaration. */ 33 public final class ParameterSpec { 34 public final String name; 35 public final List<AnnotationSpec> annotations; 36 public final Set<Modifier> modifiers; 37 public final TypeName type; 38 ParameterSpec(Builder builder)39 private ParameterSpec(Builder builder) { 40 this.name = checkNotNull(builder.name, "name == null"); 41 this.annotations = Util.immutableList(builder.annotations); 42 this.modifiers = Util.immutableSet(builder.modifiers); 43 this.type = checkNotNull(builder.type, "type == null"); 44 } 45 hasModifier(Modifier modifier)46 public boolean hasModifier(Modifier modifier) { 47 return modifiers.contains(modifier); 48 } 49 emit(CodeWriter codeWriter, boolean varargs)50 void emit(CodeWriter codeWriter, boolean varargs) throws IOException { 51 codeWriter.emitAnnotations(annotations, true); 52 codeWriter.emitModifiers(modifiers); 53 if (varargs) { 54 TypeName.asArray(type).emit(codeWriter, true); 55 } else { 56 type.emit(codeWriter); 57 } 58 codeWriter.emit(" $L", name); 59 } 60 equals(Object o)61 @Override public boolean equals(Object o) { 62 if (this == o) return true; 63 if (o == null) return false; 64 if (getClass() != o.getClass()) return false; 65 return toString().equals(o.toString()); 66 } 67 hashCode()68 @Override public int hashCode() { 69 return toString().hashCode(); 70 } 71 toString()72 @Override public String toString() { 73 StringBuilder out = new StringBuilder(); 74 try { 75 CodeWriter codeWriter = new CodeWriter(out); 76 emit(codeWriter, false); 77 return out.toString(); 78 } catch (IOException e) { 79 throw new AssertionError(); 80 } 81 } 82 get(VariableElement element)83 public static ParameterSpec get(VariableElement element) { 84 TypeName type = TypeName.get(element.asType()); 85 String name = element.getSimpleName().toString(); 86 return ParameterSpec.builder(type, name) 87 .addModifiers(element.getModifiers()) 88 .build(); 89 } 90 parametersOf(ExecutableElement method)91 static List<ParameterSpec> parametersOf(ExecutableElement method) { 92 List<ParameterSpec> result = new ArrayList<>(); 93 for (VariableElement parameter : method.getParameters()) { 94 result.add(ParameterSpec.get(parameter)); 95 } 96 return result; 97 } 98 builder(TypeName type, String name, Modifier... modifiers)99 public static Builder builder(TypeName type, String name, Modifier... modifiers) { 100 checkNotNull(type, "type == null"); 101 checkArgument(SourceVersion.isName(name), "not a valid name: %s", name); 102 return new Builder(type, name) 103 .addModifiers(modifiers); 104 } 105 builder(Type type, String name, Modifier... modifiers)106 public static Builder builder(Type type, String name, Modifier... modifiers) { 107 return builder(TypeName.get(type), name, modifiers); 108 } 109 toBuilder()110 public Builder toBuilder() { 111 return toBuilder(type, name); 112 } 113 toBuilder(TypeName type, String name)114 Builder toBuilder(TypeName type, String name) { 115 Builder builder = new Builder(type, name); 116 builder.annotations.addAll(annotations); 117 builder.modifiers.addAll(modifiers); 118 return builder; 119 } 120 121 public static final class Builder { 122 private final TypeName type; 123 private final String name; 124 125 private final List<AnnotationSpec> annotations = new ArrayList<>(); 126 private final List<Modifier> modifiers = new ArrayList<>(); 127 Builder(TypeName type, String name)128 private Builder(TypeName type, String name) { 129 this.type = type; 130 this.name = name; 131 } 132 addAnnotations(Iterable<AnnotationSpec> annotationSpecs)133 public Builder addAnnotations(Iterable<AnnotationSpec> annotationSpecs) { 134 checkArgument(annotationSpecs != null, "annotationSpecs == null"); 135 for (AnnotationSpec annotationSpec : annotationSpecs) { 136 this.annotations.add(annotationSpec); 137 } 138 return this; 139 } 140 addAnnotation(AnnotationSpec annotationSpec)141 public Builder addAnnotation(AnnotationSpec annotationSpec) { 142 this.annotations.add(annotationSpec); 143 return this; 144 } 145 addAnnotation(ClassName annotation)146 public Builder addAnnotation(ClassName annotation) { 147 this.annotations.add(AnnotationSpec.builder(annotation).build()); 148 return this; 149 } 150 addAnnotation(Class<?> annotation)151 public Builder addAnnotation(Class<?> annotation) { 152 return addAnnotation(ClassName.get(annotation)); 153 } 154 addModifiers(Modifier... modifiers)155 public Builder addModifiers(Modifier... modifiers) { 156 Collections.addAll(this.modifiers, modifiers); 157 return this; 158 } 159 addModifiers(Iterable<Modifier> modifiers)160 public Builder addModifiers(Iterable<Modifier> modifiers) { 161 checkNotNull(modifiers, "modifiers == null"); 162 for (Modifier modifier : modifiers) { 163 this.modifiers.add(modifier); 164 } 165 return this; 166 } 167 build()168 public ParameterSpec build() { 169 return new ParameterSpec(this); 170 } 171 } 172 } 173