diff options
Diffstat (limited to 'src/main/java/com/squareup/javapoet')
-rw-r--r-- | src/main/java/com/squareup/javapoet/AnnotationSpec.java | 60 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/ClassName.java | 63 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/CodeBlock.java | 8 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/CodeWriter.java | 51 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/FieldSpec.java | 16 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/JavaFile.java | 10 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/JavaPoet.java | 6 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/MethodSpec.java | 34 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/ParameterSpec.java | 15 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/TypeSpec.java | 119 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/Types.java | 44 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/Util.java | 93 |
12 files changed, 288 insertions, 231 deletions
diff --git a/src/main/java/com/squareup/javapoet/AnnotationSpec.java b/src/main/java/com/squareup/javapoet/AnnotationSpec.java index c70783b..721fce6 100644 --- a/src/main/java/com/squareup/javapoet/AnnotationSpec.java +++ b/src/main/java/com/squareup/javapoet/AnnotationSpec.java @@ -15,33 +15,25 @@ */ package com.squareup.javapoet; -import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableListMultimap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; import java.io.IOException; import java.io.StringWriter; import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Collection; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.TreeMap; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.getOnlyElement; +import static com.squareup.javapoet.Util.checkNotNull; /** A generated annotation on a declaration. */ public final class AnnotationSpec { public final Type type; - public final ImmutableMultimap<String, CodeBlock> members; + public final Map<String, List<CodeBlock>> members; private AnnotationSpec(Builder builder) { this.type = builder.type; - this.members = ImmutableListMultimap.copyOf(builder.members); + this.members = Util.immutableMultimap(builder.members); } void emit(CodeWriter codeWriter, boolean inline) throws IOException { @@ -50,10 +42,10 @@ public final class AnnotationSpec { if (members.isEmpty()) { // @Singleton codeWriter.emit("@$T", type); - } else if (members.keySet().equals(ImmutableSet.of("value"))) { + } else if (members.size() == 1 && members.containsKey("value")) { // @Named("foo") codeWriter.emit("@$T(", type); - emitAnnotationValue(codeWriter, whitespace, memberSeparator, members.values()); + emitAnnotationValues(codeWriter, whitespace, memberSeparator, members.get("value")); codeWriter.emit(")"); } else { // Inline: @@ -66,11 +58,11 @@ public final class AnnotationSpec { // ) codeWriter.emit("@$T(" + whitespace, type); codeWriter.indent(2); - for (Iterator<Map.Entry<String, Collection<CodeBlock>>> i - = members.asMap().entrySet().iterator(); i.hasNext();) { - Map.Entry<String, Collection<CodeBlock>> entry = i.next(); + for (Iterator<Map.Entry<String, List<CodeBlock>>> i + = members.entrySet().iterator(); i.hasNext();) { + Map.Entry<String, List<CodeBlock>> entry = i.next(); codeWriter.emit("$L = ", entry.getKey()); - emitAnnotationValue(codeWriter, whitespace, memberSeparator, entry.getValue()); + emitAnnotationValues(codeWriter, whitespace, memberSeparator, entry.getValue()); if (i.hasNext()) codeWriter.emit(memberSeparator); } codeWriter.unindent(2); @@ -78,11 +70,11 @@ public final class AnnotationSpec { } } - private void emitAnnotationValue(CodeWriter codeWriter, String whitespace, String memberSeparator, - Collection<CodeBlock> value) throws IOException { - if (value.size() == 1) { + private void emitAnnotationValues(CodeWriter codeWriter, String whitespace, + String memberSeparator, List<CodeBlock> values) throws IOException { + if (values.size() == 1) { codeWriter.indent(2); - codeWriter.emit(getOnlyElement(value)); + codeWriter.emit(values.get(0)); codeWriter.unindent(2); return; } @@ -90,7 +82,7 @@ public final class AnnotationSpec { codeWriter.emit("{" + whitespace); codeWriter.indent(2); boolean first = true; - for (CodeBlock codeBlock : value) { + for (CodeBlock codeBlock : values) { if (!first) codeWriter.emit(memberSeparator); codeWriter.emit(codeBlock); first = false; @@ -127,15 +119,23 @@ public final class AnnotationSpec { public static final class Builder { private final Type type; - private final Multimap<String, CodeBlock> members = Multimaps.newListMultimap( - new TreeMap<String, Collection<CodeBlock>>(), AnnotationSpec.<CodeBlock>listSupplier()); + private final Map<String, List<CodeBlock>> members = new LinkedHashMap<>(); private Builder(Type type) { this.type = type; } public Builder addMember(String name, String format, Object... args) { - members.put(name, CodeBlock.builder().add(format, args).build()); + return addMember(name, CodeBlock.builder().add(format, args).build()); + } + + public Builder addMember(String name, CodeBlock codeBlock) { + List<CodeBlock> values = members.get(name); + if (values == null) { + values = new ArrayList<>(); + members.put(name, values); + } + values.add(codeBlock); return this; } @@ -143,12 +143,4 @@ public final class AnnotationSpec { return new AnnotationSpec(this); } } - - private static <T> Supplier<List<T>> listSupplier() { - return new Supplier<List<T>>() { - @Override public List<T> get() { - return new ArrayList<>(); - } - }; - } } diff --git a/src/main/java/com/squareup/javapoet/ClassName.java b/src/main/java/com/squareup/javapoet/ClassName.java index 91dc3fa..310557d 100644 --- a/src/main/java/com/squareup/javapoet/ClassName.java +++ b/src/main/java/com/squareup/javapoet/ClassName.java @@ -15,13 +15,6 @@ */ package com.squareup.javapoet; -import com.google.common.base.Ascii; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; @@ -30,12 +23,11 @@ import java.util.Map; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; -import javax.lang.model.element.NestingKind; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.squareup.javapoet.Util.checkArgument; +import static com.squareup.javapoet.Util.checkNotNull; import static javax.lang.model.element.NestingKind.MEMBER; import static javax.lang.model.element.NestingKind.TOP_LEVEL; @@ -44,17 +36,17 @@ public final class ClassName implements Type, Comparable<ClassName> { public static final ClassName OBJECT = ClassName.get(Object.class); /** From top to bottom. This will be ["java.util", "Map", "Entry"] for {@link Map.Entry}. */ - final ImmutableList<String> names; + final List<String> names; final String canonicalName; private ClassName(List<String> names) { for (int i = 1; i < names.size(); i++) { checkArgument(SourceVersion.isName(names.get(i)), "part '%s' is keyword", names.get(i)); } - this.names = ImmutableList.copyOf(names); - this.canonicalName = Joiner.on(".").join(names.get(0).isEmpty() - ? names.subList(1, names.size()) - : names); + this.names = Util.immutableList(names); + this.canonicalName = names.get(0).isEmpty() + ? Util.join(".", names.subList(1, names.size())) + : Util.join(".", names); } /** Returns the package name, like {@code "java.util"} for {@code Map.Entry}. */ @@ -77,13 +69,13 @@ public final class ClassName implements Type, Comparable<ClassName> { */ public ClassName nestedClass(String name) { checkNotNull(name, "name == null"); - return new ClassName(new ImmutableList.Builder<String>() - .addAll(names) - .add(name) - .build()); + List<String> result = new ArrayList<>(names.size() + 1); + result.addAll(names); + result.add(name); + return new ClassName(result); } - public ImmutableList<String> simpleNames() { + public List<String> simpleNames() { return names.subList(1, names.size()); } @@ -93,15 +85,14 @@ public final class ClassName implements Type, Comparable<ClassName> { * it is equivalent to {@code get(packageName(), name)}. */ public ClassName peerClass(String name) { - return new ClassName(new ImmutableList.Builder<String>() - .addAll(names.subList(0, names.size() - 1)) - .add(name) - .build()); + List<String> result = new ArrayList<>(names); + result.set(result.size() - 1, name); + return new ClassName(result); } /** Returns the simple name of this class, like {@code "Entry"} for {@link Map.Entry}. */ public String simpleName() { - return Iterables.getLast(names); + return names.get(names.size() - 1); } public static ClassName get(Class<?> clazz) { @@ -131,15 +122,15 @@ public final class ClassName implements Type, Comparable<ClassName> { // Add the package name, like "java.util.concurrent", or "" for no package. int p = 0; - while (p < classNameString.length() && Ascii.isLowerCase(classNameString.charAt(p))) { + while (p < classNameString.length() && Util.isLowerCase(classNameString.charAt(p))) { p = classNameString.indexOf('.', p) + 1; checkArgument(p != 0, "couldn't make a guess for %s", classNameString); } names.add(p != 0 ? classNameString.substring(0, p - 1) : ""); // Add the class names, like "Map" and "Entry". - for (String part : Splitter.on('.').split(classNameString.substring(p))) { - checkArgument(!part.isEmpty() && Ascii.isUpperCase(part.charAt(0)), + for (String part : classNameString.substring(p).split("\\.", -1)) { + checkArgument(!part.isEmpty() && Util.isUpperCase(part.charAt(0)), "couldn't make a guess for %s", classNameString); names.add(part); } @@ -153,22 +144,20 @@ public final class ClassName implements Type, Comparable<ClassName> { * {@code "java.util"} and simple names {@code "Map"}, {@code "Entry"} yields {@link Map.Entry}. */ public static ClassName get(String packageName, String simpleName, String... simpleNames) { - return new ClassName(new ImmutableList.Builder<String>() - .add(packageName) - .add(simpleName) - .add(simpleNames) - .build()); + List<String> result = new ArrayList<>(); + result.add(packageName); + result.add(simpleName); + Collections.addAll(result, simpleNames); + return new ClassName(result); } - private static final ImmutableSet<NestingKind> ACCEPTABLE_NESTING_KINDS = - Sets.immutableEnumSet(TOP_LEVEL, MEMBER); - /** Returns the class name for {@code element}. */ public static ClassName get(TypeElement element) { checkNotNull(element, "element == null"); List<String> names = new ArrayList<>(); for (Element e = element; isClassOrInterface(e); e = e.getEnclosingElement()) { - checkArgument(ACCEPTABLE_NESTING_KINDS.contains(element.getNestingKind())); + checkArgument(element.getNestingKind() == TOP_LEVEL || element.getNestingKind() == MEMBER, + "unexpected type testing"); names.add(e.getSimpleName().toString()); } names.add(getPackage(element).getQualifiedName().toString()); diff --git a/src/main/java/com/squareup/javapoet/CodeBlock.java b/src/main/java/com/squareup/javapoet/CodeBlock.java index 989ee58..997a35a 100644 --- a/src/main/java/com/squareup/javapoet/CodeBlock.java +++ b/src/main/java/com/squareup/javapoet/CodeBlock.java @@ -21,8 +21,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; +import static com.squareup.javapoet.Util.checkArgument; +import static com.squareup.javapoet.Util.checkState; /** * A fragment of a .java file, potentially containing declarations, statements, and documentation. @@ -60,8 +60,8 @@ public final class CodeBlock { final List<Object> args; private CodeBlock(Builder builder) { - this.formatParts = Collections.unmodifiableList(new ArrayList<>(builder.formatParts)); - this.args = Collections.unmodifiableList(new ArrayList<>(builder.args)); + this.formatParts = Util.immutableList(builder.formatParts); + this.args = Util.immutableList(builder.args); } public boolean isEmpty() { diff --git a/src/main/java/com/squareup/javapoet/CodeWriter.java b/src/main/java/com/squareup/javapoet/CodeWriter.java index d3d3ad7..62729ee 100644 --- a/src/main/java/com/squareup/javapoet/CodeWriter.java +++ b/src/main/java/com/squareup/javapoet/CodeWriter.java @@ -15,12 +15,6 @@ */ package com.squareup.javapoet; -import com.google.common.base.Ascii; -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedMap; import java.io.IOException; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; @@ -28,21 +22,24 @@ import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumSet; import java.util.Formatter; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.TreeMap; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; import javax.lang.model.type.TypeMirror; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; +import static com.squareup.javapoet.Util.checkArgument; +import static com.squareup.javapoet.Util.checkNotNull; +import static com.squareup.javapoet.Util.checkState; /** * Converts a {@link JavaFile} to a string suitable to both human- and javac-consumption. This @@ -57,7 +54,7 @@ final class CodeWriter { private boolean comment = false; private String packageName; private final List<TypeSpec> typeSpecStack = new ArrayList<>(); - private final ImmutableMap<ClassName, String> importedTypes; + private final Map<ClassName, String> importedTypes; private final Set<ClassName> importableTypes = new LinkedHashSet<>(); private boolean trailingNewline; @@ -73,16 +70,16 @@ final class CodeWriter { } public CodeWriter(Appendable out, String indent) { - this(out, indent, ImmutableMap.<ClassName, String>of()); + this(out, indent, Collections.<ClassName, String>emptyMap()); } - public CodeWriter(Appendable out, String indent, ImmutableMap<ClassName, String> importedTypes) { + public CodeWriter(Appendable out, String indent, Map<ClassName, String> importedTypes) { this.out = checkNotNull(out, "out == null"); this.indent = checkNotNull(indent, "indent == null"); this.importedTypes = checkNotNull(importedTypes, "importedTypes == null"); } - public ImmutableMap<ClassName, String> importedTypes() { + public Map<ClassName, String> importedTypes() { return importedTypes; } @@ -151,8 +148,7 @@ final class CodeWriter { emit(" */\n"); } - public void emitAnnotations(ImmutableList<AnnotationSpec> annotations, boolean inline) - throws IOException { + public void emitAnnotations(List<AnnotationSpec> annotations, boolean inline) throws IOException { for (AnnotationSpec annotationSpec : annotations) { annotationSpec.emit(this, inline); emit(inline ? " " : "\n"); @@ -168,20 +164,20 @@ final class CodeWriter { if (modifiers.isEmpty()) return; for (Modifier modifier : EnumSet.copyOf(modifiers)) { if (implicitModifiers.contains(modifier)) continue; - emitAndIndent(Ascii.toLowerCase(modifier.name())); + emitAndIndent(modifier.name().toLowerCase(Locale.US)); emitAndIndent(" "); } } - public void emitModifiers(ImmutableSet<Modifier> modifiers) throws IOException { - emitModifiers(modifiers, ImmutableSet.<Modifier>of()); + public void emitModifiers(Set<Modifier> modifiers) throws IOException { + emitModifiers(modifiers, Collections.<Modifier>emptySet()); } /** * Emit type variables with their bounds. This should only be used when declaring type variables; * everywhere else bounds are omitted. */ - public void emitTypeVariables(ImmutableList<TypeVariable<?>> typeVariables) throws IOException { + public void emitTypeVariables(List<TypeVariable<?>> typeVariables) throws IOException { if (typeVariables.isEmpty()) return; emit("<"); @@ -264,7 +260,7 @@ final class CodeWriter { private void emitLiteral(Object o) throws IOException { if (o instanceof TypeSpec) { TypeSpec typeSpec = (TypeSpec) o; - typeSpec.emit(this, null, ImmutableSet.<Modifier>of()); + typeSpec.emit(this, null, Collections.<Modifier>emptySet()); } else if (o instanceof AnnotationSpec) { AnnotationSpec annotationSpec = (AnnotationSpec) o; annotationSpec.emit(this, true); @@ -305,7 +301,7 @@ final class CodeWriter { if (superBounds.length == 1) { return emit("? super $T", superBounds[0]); } - checkArgument(extendsBounds.length == 1); + checkArgument(extendsBounds.length == 1, "unexpected extends bounds: %s", type); return isObject(extendsBounds[0]) ? emit("?") : emit("? extends $T", extendsBounds[0]); @@ -358,13 +354,13 @@ final class CodeWriter { } // Look for the longest common prefix, which we can omit. - ImmutableList<String> classNames = className.simpleNames(); + List<String> classNames = className.simpleNames(); int prefixLength = commonPrefixLength(classNames); if (prefixLength == classNames.size()) { return className.simpleName(); // Special case: a class referring to itself! } - return Joiner.on('.').join(classNames.subList(prefixLength, classNames.size())); + return Util.join(".", classNames.subList(prefixLength, classNames.size())); } /** @@ -387,7 +383,7 @@ final class CodeWriter { * List}, 1 for {@code AbstractMap}, 1 for {@code AbstractMap.SimpleImmutableEntry}, and 2 for * {@code AbstractMap.SimpleEntry} itself. */ - private int commonPrefixLength(ImmutableList<String> classNames) { + private int commonPrefixLength(List<String> classNames) { int size = Math.min(classNames.size(), typeSpecStack.size()); for (int i = 0; i < size; i++) { String a = classNames.get(i); @@ -470,7 +466,7 @@ final class CodeWriter { * Returns the types that should have been imported for this code. If there were any simple name * collisions, that type's first use is imported. */ - ImmutableMap<ClassName, String> suggestedImports() { + Map<ClassName, String> suggestedImports() { // Find the simple names that can be imported, and the classes that they target. Map<String, ClassName> simpleNameToType = new LinkedHashMap<>(); for (Type type : importableTypes) { @@ -481,8 +477,7 @@ final class CodeWriter { } // Invert the map. - ImmutableSortedMap.Builder<ClassName, String> typeToSimpleName - = ImmutableSortedMap.naturalOrder(); + TreeMap<ClassName, String> typeToSimpleName = new TreeMap<>(); for (Map.Entry<String, ClassName> entry : simpleNameToType.entrySet()) { typeToSimpleName.put(entry.getValue(), entry.getKey()); } @@ -490,7 +485,7 @@ final class CodeWriter { // TODO(jwilson): omit imports from java.lang, unless their simple names is also present in the // current class's package. (Yuck.) - return typeToSimpleName.build(); + return typeToSimpleName; } /** Returns the string literal representing {@code data}, including wrapping quotes. */ diff --git a/src/main/java/com/squareup/javapoet/FieldSpec.java b/src/main/java/com/squareup/javapoet/FieldSpec.java index 4bf1ef3..8158084 100644 --- a/src/main/java/com/squareup/javapoet/FieldSpec.java +++ b/src/main/java/com/squareup/javapoet/FieldSpec.java @@ -15,8 +15,6 @@ */ package com.squareup.javapoet; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.io.StringWriter; import java.lang.reflect.Type; @@ -27,24 +25,24 @@ import java.util.Set; import javax.lang.model.SourceVersion; import javax.lang.model.element.Modifier; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.squareup.javapoet.Util.checkArgument; +import static com.squareup.javapoet.Util.checkNotNull; /** A generated field declaration. */ public final class FieldSpec { public final Type type; public final String name; public final CodeBlock javadoc; - public final ImmutableList<AnnotationSpec> annotations; - public final ImmutableSet<Modifier> modifiers; + public final List<AnnotationSpec> annotations; + public final Set<Modifier> modifiers; public final CodeBlock initializer; private FieldSpec(Builder builder) { this.type = checkNotNull(builder.type, "type == null"); this.name = checkNotNull(builder.name, "name == null"); this.javadoc = builder.javadoc.build(); - this.annotations = ImmutableList.copyOf(builder.annotations); - this.modifiers = ImmutableSet.copyOf(builder.modifiers); + this.annotations = Util.immutableList(builder.annotations); + this.modifiers = Util.immutableSet(builder.modifiers); this.initializer = builder.initializer.build(); } @@ -68,7 +66,7 @@ public final class FieldSpec { StringWriter out = new StringWriter(); try { CodeWriter codeWriter = new CodeWriter(out); - emit(codeWriter, ImmutableSet.<Modifier>of()); + emit(codeWriter, Collections.<Modifier>emptySet()); return out.toString(); } catch (IOException e) { throw new AssertionError(); diff --git a/src/main/java/com/squareup/javapoet/JavaFile.java b/src/main/java/com/squareup/javapoet/JavaFile.java index e7eebe4..ae588be 100644 --- a/src/main/java/com/squareup/javapoet/JavaFile.java +++ b/src/main/java/com/squareup/javapoet/JavaFile.java @@ -15,12 +15,12 @@ */ package com.squareup.javapoet; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import java.io.IOException; +import java.util.Collections; +import java.util.Map; import javax.lang.model.element.Modifier; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.squareup.javapoet.Util.checkNotNull; /** A Java file containing a single top level class. */ public final class JavaFile { @@ -50,7 +50,7 @@ public final class JavaFile { // First pass: emit the entire class, just to collect the types we'll need to import. CodeWriter importsCollector = new CodeWriter(NULL_APPENDABLE, indent); emit(importsCollector); - ImmutableMap<ClassName, String> suggestedImports = importsCollector.suggestedImports(); + Map<ClassName, String> suggestedImports = importsCollector.suggestedImports(); // Second pass: write the code, taking advantage of the imports. CodeWriter codeWriter = new CodeWriter(out, indent, suggestedImports); @@ -76,7 +76,7 @@ public final class JavaFile { codeWriter.emit("\n"); } - typeSpec.emit(codeWriter, null, ImmutableSet.<Modifier>of()); + typeSpec.emit(codeWriter, null, Collections.<Modifier>emptySet()); codeWriter.popPackage(); } diff --git a/src/main/java/com/squareup/javapoet/JavaPoet.java b/src/main/java/com/squareup/javapoet/JavaPoet.java index 2754471..a61a31a 100644 --- a/src/main/java/com/squareup/javapoet/JavaPoet.java +++ b/src/main/java/com/squareup/javapoet/JavaPoet.java @@ -15,7 +15,6 @@ */ package com.squareup.javapoet; -import com.google.common.collect.Iterables; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; @@ -28,7 +27,7 @@ import javax.annotation.processing.Filer; import javax.lang.model.element.Element; import javax.tools.JavaFileObject; -import static com.google.common.base.Preconditions.checkArgument; +import static com.squareup.javapoet.Util.checkArgument; /** Writes generated types to a filesystem using the standard directory structure. */ public final class JavaPoet { @@ -79,8 +78,9 @@ public final class JavaPoet { String fileName = javaFile.packageName.isEmpty() ? javaFile.typeSpec.name : javaFile.packageName + "." + javaFile.typeSpec.name; + List<Element> originatingElements = javaFile.typeSpec.originatingElements; JavaFileObject filerSourceFile = filer.createSourceFile(fileName, - Iterables.toArray(javaFile.typeSpec.originatingElements, Element.class)); + originatingElements.toArray(new Element[originatingElements.size()])); try (Writer writer = filerSourceFile.openWriter()) { javaFile.emit(writer, indent); } catch (Exception e) { diff --git a/src/main/java/com/squareup/javapoet/MethodSpec.java b/src/main/java/com/squareup/javapoet/MethodSpec.java index 4741402..cd6b045 100644 --- a/src/main/java/com/squareup/javapoet/MethodSpec.java +++ b/src/main/java/com/squareup/javapoet/MethodSpec.java @@ -15,8 +15,6 @@ */ package com.squareup.javapoet; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.io.StringWriter; import java.lang.reflect.Type; @@ -29,10 +27,9 @@ import java.util.Set; import javax.lang.model.SourceVersion; import javax.lang.model.element.Modifier; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.Iterables.getLast; +import static com.squareup.javapoet.Util.checkArgument; +import static com.squareup.javapoet.Util.checkNotNull; +import static com.squareup.javapoet.Util.checkState; /** A generated constructor or method declaration. */ public final class MethodSpec { @@ -40,13 +37,13 @@ public final class MethodSpec { public final String name; public final CodeBlock javadoc; - public final ImmutableList<AnnotationSpec> annotations; - public final ImmutableSet<Modifier> modifiers; - public final ImmutableList<TypeVariable<?>> typeVariables; + public final List<AnnotationSpec> annotations; + public final Set<Modifier> modifiers; + public final List<TypeVariable<?>> typeVariables; public final Type returnType; - public final ImmutableList<ParameterSpec> parameters; + public final List<ParameterSpec> parameters; public final boolean varargs; - public final ImmutableList<Type> exceptions; + public final List<Type> exceptions; public final CodeBlock code; private MethodSpec(Builder builder) { @@ -58,18 +55,19 @@ public final class MethodSpec { this.name = checkNotNull(builder.name, "name == null"); this.javadoc = builder.javadoc.build(); - this.annotations = ImmutableList.copyOf(builder.annotations); - this.modifiers = ImmutableSet.copyOf(builder.modifiers); - this.typeVariables = ImmutableList.copyOf(builder.typeVariables); + this.annotations = Util.immutableList(builder.annotations); + this.modifiers = Util.immutableSet(builder.modifiers); + this.typeVariables = Util.immutableList(builder.typeVariables); this.returnType = builder.returnType; - this.parameters = ImmutableList.copyOf(builder.parameters); + this.parameters = Util.immutableList(builder.parameters); this.varargs = builder.varargs; - this.exceptions = ImmutableList.copyOf(builder.exceptions); + this.exceptions = Util.immutableList(builder.exceptions); this.code = code; } private boolean lastParameterIsArray(List<ParameterSpec> parameters) { - return !parameters.isEmpty() && Types.arrayComponent(getLast(parameters).type) != null; + return !parameters.isEmpty() + && Types.arrayComponent(parameters.get(parameters.size() - 1).type) != null; } void emit(CodeWriter codeWriter, String enclosingName, Set<Modifier> implicitModifiers) @@ -137,7 +135,7 @@ public final class MethodSpec { StringWriter out = new StringWriter(); try { CodeWriter codeWriter = new CodeWriter(out); - emit(codeWriter, "Constructor", ImmutableSet.<Modifier>of()); + emit(codeWriter, "Constructor", Collections.<Modifier>emptySet()); return out.toString(); } catch (IOException e) { throw new AssertionError(); diff --git a/src/main/java/com/squareup/javapoet/ParameterSpec.java b/src/main/java/com/squareup/javapoet/ParameterSpec.java index eaeece0..8686790 100644 --- a/src/main/java/com/squareup/javapoet/ParameterSpec.java +++ b/src/main/java/com/squareup/javapoet/ParameterSpec.java @@ -15,31 +15,30 @@ */ package com.squareup.javapoet; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.io.StringWriter; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import javax.lang.model.SourceVersion; import javax.lang.model.element.Modifier; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.squareup.javapoet.Util.checkArgument; +import static com.squareup.javapoet.Util.checkNotNull; /** A generated parameter declaration. */ public final class ParameterSpec { public final String name; - public final ImmutableList<AnnotationSpec> annotations; - public final ImmutableSet<Modifier> modifiers; + public final List<AnnotationSpec> annotations; + public final Set<Modifier> modifiers; public final Type type; private ParameterSpec(Builder builder) { this.name = checkNotNull(builder.name, "name == null"); - this.annotations = ImmutableList.copyOf(builder.annotations); - this.modifiers = ImmutableSet.copyOf(builder.modifiers); + this.annotations = Util.immutableList(builder.annotations); + this.modifiers = Util.immutableSet(builder.modifiers); this.type = checkNotNull(builder.type, "type == null"); } diff --git a/src/main/java/com/squareup/javapoet/TypeSpec.java b/src/main/java/com/squareup/javapoet/TypeSpec.java index ada52d0..715946e 100644 --- a/src/main/java/com/squareup/javapoet/TypeSpec.java +++ b/src/main/java/com/squareup/javapoet/TypeSpec.java @@ -15,30 +15,26 @@ */ package com.squareup.javapoet; -import com.google.common.base.Ascii; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; import java.io.IOException; import java.io.StringWriter; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.Iterables.getOnlyElement; +import static com.squareup.javapoet.Util.checkArgument; +import static com.squareup.javapoet.Util.checkNotNull; +import static com.squareup.javapoet.Util.checkState; /** A generated class, interface, or enum declaration. */ public final class TypeSpec { @@ -46,38 +42,38 @@ public final class TypeSpec { public final String name; public final CodeBlock anonymousTypeArguments; public final CodeBlock javadoc; - public final ImmutableList<AnnotationSpec> annotations; - public final ImmutableSet<Modifier> modifiers; - public final ImmutableList<TypeVariable<?>> typeVariables; + public final List<AnnotationSpec> annotations; + public final Set<Modifier> modifiers; + public final List<TypeVariable<?>> typeVariables; public final Type superclass; - public final ImmutableList<Type> superinterfaces; - public final ImmutableMap<String, TypeSpec> enumConstants; - public final ImmutableList<FieldSpec> fieldSpecs; - public final ImmutableList<MethodSpec> methodSpecs; - public final ImmutableList<TypeSpec> typeSpecs; - public final ImmutableList<Element> originatingElements; + public final List<Type> superinterfaces; + public final Map<String, TypeSpec> enumConstants; + public final List<FieldSpec> fieldSpecs; + public final List<MethodSpec> methodSpecs; + public final List<TypeSpec> typeSpecs; + public final List<Element> originatingElements; private TypeSpec(Builder builder) { this.kind = builder.kind; this.name = builder.name; this.anonymousTypeArguments = builder.anonymousTypeArguments; this.javadoc = builder.javadoc.build(); - this.annotations = ImmutableList.copyOf(builder.annotations); - this.modifiers = ImmutableSet.copyOf(builder.modifiers); - this.typeVariables = ImmutableList.copyOf(builder.typeVariables); + this.annotations = Util.immutableList(builder.annotations); + this.modifiers = Util.immutableSet(builder.modifiers); + this.typeVariables = Util.immutableList(builder.typeVariables); this.superclass = builder.superclass; - this.superinterfaces = ImmutableList.copyOf(builder.superinterfaces); - this.enumConstants = ImmutableMap.copyOf(builder.enumConstants); - this.fieldSpecs = ImmutableList.copyOf(builder.fieldSpecs); - this.methodSpecs = ImmutableList.copyOf(builder.methodSpecs); - this.typeSpecs = ImmutableList.copyOf(builder.typeSpecs); - - ImmutableList.Builder<Element> originatingElementsBuilder = ImmutableList.builder(); - originatingElementsBuilder.addAll(builder.originatingElements); + this.superinterfaces = Util.immutableList(builder.superinterfaces); + this.enumConstants = Util.immutableMap(builder.enumConstants); + this.fieldSpecs = Util.immutableList(builder.fieldSpecs); + this.methodSpecs = Util.immutableList(builder.methodSpecs); + this.typeSpecs = Util.immutableList(builder.typeSpecs); + + List<Element> originatingElementsMutable = new ArrayList<>(); + originatingElementsMutable.addAll(builder.originatingElements); for (TypeSpec typeSpec : builder.typeSpecs) { - originatingElementsBuilder.addAll(typeSpec.originatingElements); + originatingElementsMutable.addAll(typeSpec.originatingElements); } - this.originatingElements = originatingElementsBuilder.build(); + this.originatingElements = Util.immutableList(originatingElementsMutable); } public boolean hasModifier(Modifier modifier) { @@ -122,25 +118,26 @@ public final class TypeSpec { } codeWriter.emit(" {\n"); } else if (anonymousTypeArguments != null) { - codeWriter.emit("new $T(", getOnlyElement(superinterfaces, superclass)); + Type supertype = !superinterfaces.isEmpty() ? superinterfaces.get(0) : superclass; + codeWriter.emit("new $T(", supertype); codeWriter.emit(anonymousTypeArguments); codeWriter.emit(") {\n"); } else { codeWriter.emitJavadoc(javadoc); codeWriter.emitAnnotations(annotations, false); - codeWriter.emitModifiers(modifiers, Sets.union(implicitModifiers, kind.asMemberModifiers)); - codeWriter.emit("$L $L", Ascii.toLowerCase(kind.name()), name); + codeWriter.emitModifiers(modifiers, Util.union(implicitModifiers, kind.asMemberModifiers)); + codeWriter.emit("$L $L", kind.name().toLowerCase(Locale.US), name); codeWriter.emitTypeVariables(typeVariables); List<Type> extendsTypes; List<Type> implementsTypes; if (kind == Kind.INTERFACE) { extendsTypes = superinterfaces; - implementsTypes = ImmutableList.of(); + implementsTypes = Collections.emptyList(); } else { extendsTypes = superclass.equals(ClassName.OBJECT) - ? ImmutableList.<Type>of() - : ImmutableList.of(superclass); + ? Collections.<Type>emptyList() + : Collections.singletonList(superclass); implementsTypes = superinterfaces; } @@ -175,7 +172,7 @@ public final class TypeSpec { Map.Entry<String, TypeSpec> enumConstant = i.next(); if (!firstMember) codeWriter.emit("\n"); enumConstant.getValue() - .emit(codeWriter, enumConstant.getKey(), ImmutableSet.<Modifier>of()); + .emit(codeWriter, enumConstant.getKey(), Collections.<Modifier>emptySet()); firstMember = false; if (i.hasNext()) { codeWriter.emit(",\n"); @@ -241,7 +238,7 @@ public final class TypeSpec { StringWriter out = new StringWriter(); try { CodeWriter codeWriter = new CodeWriter(out); - emit(codeWriter, null, ImmutableSet.<Modifier>of()); + emit(codeWriter, null, Collections.<Modifier>emptySet()); return out.toString(); } catch (IOException e) { throw new AssertionError(); @@ -250,32 +247,32 @@ public final class TypeSpec { private enum Kind { CLASS( - ImmutableSet.<Modifier>of(), - ImmutableSet.<Modifier>of(), - ImmutableSet.<Modifier>of(), - ImmutableSet.<Modifier>of()), + Collections.<Modifier>emptySet(), + Collections.<Modifier>emptySet(), + Collections.<Modifier>emptySet(), + Collections.<Modifier>emptySet()), INTERFACE( - ImmutableSet.of(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL), - ImmutableSet.of(Modifier.PUBLIC, Modifier.ABSTRACT), - ImmutableSet.of(Modifier.PUBLIC, Modifier.STATIC), - ImmutableSet.of(Modifier.STATIC)), + Util.immutableSet(Arrays.asList(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)), + Util.immutableSet(Arrays.asList(Modifier.PUBLIC, Modifier.ABSTRACT)), + Util.immutableSet(Arrays.asList(Modifier.PUBLIC, Modifier.STATIC)), + Util.immutableSet(Arrays.asList(Modifier.STATIC))), ENUM( - ImmutableSet.<Modifier>of(), - ImmutableSet.<Modifier>of(), - ImmutableSet.<Modifier>of(), - ImmutableSet.of(Modifier.STATIC)); - - private final ImmutableSet<Modifier> implicitFieldModifiers; - private final ImmutableSet<Modifier> implicitMethodModifiers; - private final ImmutableSet<Modifier> implicitTypeModifiers; - private final ImmutableSet<Modifier> asMemberModifiers; - - private Kind(ImmutableSet<Modifier> implicitFieldModifiers, - ImmutableSet<Modifier> implicitMethodModifiers, - ImmutableSet<Modifier> implicitTypeModifiers, - ImmutableSet<Modifier> asMemberModifiers) { + Collections.<Modifier>emptySet(), + Collections.<Modifier>emptySet(), + Collections.<Modifier>emptySet(), + Collections.singleton(Modifier.STATIC)); + + private final Set<Modifier> implicitFieldModifiers; + private final Set<Modifier> implicitMethodModifiers; + private final Set<Modifier> implicitTypeModifiers; + private final Set<Modifier> asMemberModifiers; + + private Kind(Set<Modifier> implicitFieldModifiers, + Set<Modifier> implicitMethodModifiers, + Set<Modifier> implicitTypeModifiers, + Set<Modifier> asMemberModifiers) { this.implicitFieldModifiers = implicitFieldModifiers; this.implicitMethodModifiers = implicitMethodModifiers; this.implicitTypeModifiers = implicitTypeModifiers; diff --git a/src/main/java/com/squareup/javapoet/Types.java b/src/main/java/com/squareup/javapoet/Types.java index 84f3d05..275313e 100644 --- a/src/main/java/com/squareup/javapoet/Types.java +++ b/src/main/java/com/squareup/javapoet/Types.java @@ -15,10 +15,6 @@ */ package com.squareup.javapoet; -import com.google.common.base.Function; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import java.io.IOException; import java.lang.reflect.GenericArrayType; import java.lang.reflect.InvocationHandler; @@ -30,6 +26,8 @@ import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -44,21 +42,14 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.SimpleTypeVisitor6; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.squareup.javapoet.Util.checkArgument; +import static com.squareup.javapoet.Util.checkNotNull; /** Static methods for working with types. */ // Forked from a similar class in Gson. public final class Types { private static final Type[] EMPTY_TYPE_ARRAY = new Type[] {}; - private static final Function<TypeMirror, Type> FOR_TYPE_MIRROR = - new Function<TypeMirror, Type>() { - @Override public Type apply(TypeMirror input) { - return get(input); - } - }; - static final Type NULL = new Type() { @Override public String toString() { return "null"; @@ -89,8 +80,8 @@ public final class Types { * Returns a new parameterized type, applying {@code typeArguments} to {@code rawType} and * with no enclosing owner type. */ - public static ParameterizedType parameterizedType(Type rawType, Iterable<Type> typeArguments) { - return parameterizedType(rawType, Iterables.toArray(typeArguments, Type.class)); + public static ParameterizedType parameterizedType(Type rawType, Collection<Type> typeArguments) { + return parameterizedType(rawType, typeArguments.toArray(new Type[typeArguments.size()])); } /** Returns an array type whose elements are all instances of {@code componentType}. */ @@ -182,10 +173,15 @@ public final class Types { } private static Type get(DeclaredType t) { - return t.getTypeArguments().isEmpty() - ? ClassName.get((TypeElement) t.asElement()) - : parameterizedType(ClassName.get((TypeElement) t.asElement()), - FluentIterable.from(t.getTypeArguments()).transform(FOR_TYPE_MIRROR)); + List<? extends TypeMirror> typeArguments = t.getTypeArguments(); + if (typeArguments.isEmpty()) { + return ClassName.get((TypeElement) t.asElement()); + } + List<Type> typeParameters = new ArrayList<>(); + for (TypeMirror typeMirror : typeArguments) { + typeParameters.add(get(typeMirror)); + } + return parameterizedType(ClassName.get((TypeElement) t.asElement()), typeParameters); } private static TypeVariable<?> get(javax.lang.model.type.TypeVariable mirror) { @@ -226,14 +222,14 @@ public final class Types { if (upperBound.getKind() == TypeKind.DECLARED) { TypeElement upperBoundElement = (TypeElement) ((DeclaredType) upperBound).asElement(); if (upperBoundElement.getNestingKind() == NestingKind.ANONYMOUS) { - return ImmutableList.<TypeMirror>builder() - .add(upperBoundElement.getSuperclass()) - .addAll(upperBoundElement.getInterfaces()) - .build(); + List<TypeMirror> result = new ArrayList<>(); + result.add(upperBoundElement.getSuperclass()); + result.addAll(upperBoundElement.getInterfaces()); + return result; } } - return ImmutableList.of(upperBound); + return Collections.singletonList(upperBound); } private static Type get(javax.lang.model.type.WildcardType mirror) { diff --git a/src/main/java/com/squareup/javapoet/Util.java b/src/main/java/com/squareup/javapoet/Util.java new file mode 100644 index 0000000..d99501e --- /dev/null +++ b/src/main/java/com/squareup/javapoet/Util.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2015 Square, Inc. + * + * 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 com.squareup.javapoet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Like Guava, but worse and standalone. This makes it easier to mix JavaPoet with libraries that + * bring their own version of Guava. + */ +final class Util { + private Util() { + } + + public static <K, V> Map<K, List<V>> immutableMultimap(Map<K, List<V>> multimap) { + LinkedHashMap<K, List<V>> result = new LinkedHashMap<>(); + for (Map.Entry<K, List<V>> entry : multimap.entrySet()) { + if (entry.getValue().isEmpty()) continue; + result.put(entry.getKey(), immutableList(entry.getValue())); + } + return Collections.unmodifiableMap(result); + } + + public static <K, V> Map<K, V> immutableMap(Map<K, V> map) { + return Collections.unmodifiableMap(new LinkedHashMap<>(map)); + } + + public static void checkArgument(boolean condition, String format, Object... args) { + if (!condition) throw new IllegalArgumentException(String.format(format, args)); + } + + public static <T> T checkNotNull(T reference, String format, Object... args) { + if (reference == null) throw new NullPointerException(String.format(format, args)); + return reference; + } + + public static void checkState(boolean condition, String format, Object... args) { + if (!condition) throw new IllegalStateException(String.format(format, args)); + } + + public static <T> List<T> immutableList(List<T> list) { + return Collections.unmodifiableList(new ArrayList<>(list)); + } + + public static <T> Set<T> immutableSet(Collection<T> set) { + return Collections.unmodifiableSet(new LinkedHashSet<>(set)); + } + + public static String join(String separator, List<String> parts) { + if (parts.isEmpty()) return ""; + StringBuilder result = new StringBuilder(); + result.append(parts.get(0)); + for (int i = 1; i < parts.size(); i++) { + result.append(separator).append(parts.get(i)); + } + return result.toString(); + } + + public static boolean isLowerCase(char c) { + return c >= 'a' && c <= 'z'; + } + + public static boolean isUpperCase(char c) { + return c >= 'A' && c <= 'Z'; + } + + public static <T> Set<T> union(Set<T> a, Set<T> b) { + Set<T> result = new LinkedHashSet<>(); + result.addAll(a); + result.addAll(b); + return result; + } +} |