diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-08 16:00:53 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-08 16:00:53 +0000 |
commit | f52887364cc220a466b2897fb70ec4b1382c8bf9 (patch) | |
tree | 30c2007cb1e35fbd658e5add767815e7ffe4af50 | |
parent | c7402b591b71ce533d12a996fdc3d85304e6da11 (diff) | |
parent | b3ebb5d8c63cdda55bb74b23d436a36a55191f68 (diff) | |
download | javapoet-aml_tz2_305400500.tar.gz |
Snap for 8426163 from b3ebb5d8c63cdda55bb74b23d436a36a55191f68 to mainline-tzdata2-releaseandroid-mainline-12.0.0_r112aml_tz2_305400500aml_tz2_305400300aml_tz2_305400100aml_tz2_304500300aml_tz2_303900110aml_tz2_303900102aml_tz2_303800002aml_tz2_303800001aml_tz2_303200001android12-mainline-tzdata2-releaseaml_tz2_305400100
Change-Id: Ic273b370af9bca768deb52246f8e267679552500
32 files changed, 143 insertions, 1632 deletions
diff --git a/.buildscript/deploy_snapshot.sh b/.buildscript/deploy_snapshot.sh index f25e18d..395a873 100755 --- a/.buildscript/deploy_snapshot.sh +++ b/.buildscript/deploy_snapshot.sh @@ -6,7 +6,7 @@ # https://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/ SLUG="square/javapoet" -JDK="openjdk8" +JDK="oraclejdk8" BRANCH="master" set -e diff --git a/.travis.yml b/.travis.yml index af37274..4e0a881 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,27 @@ language: java matrix: include: - - jdk: openjdk8 - - jdk: openjdk11 + - env: JDK='Oracle JDK 8' + jdk: oraclejdk8 + - env: JDK='Oracle JDK 9' + jdk: oraclejdk9 + - env: JDK='Oracle JDK 10' + install: . ./install-jdk.sh -F 10 -L BCL + - env: JDK='OpenJDK 10' + install: . ./install-jdk.sh -F 10 -L GPL + - env: JDK='Oracle JDK 11' + install: . ./install-jdk.sh -F 11 -L BCL + - env: JDK='OpenJDK 11' + install: . ./install-jdk.sh -F 11 -L GPL allow_failures: - - jdk: openjdk11 + # ErrorProne/javac is not yet working on JDK 11 + - env: JDK='Oracle JDK 11' + - env: JDK='OpenJDK 11' +# Direct usage of `install-jdk.sh` might be superseded by https://github.com/travis-ci/travis-build/pull/1347 before_install: - unset _JAVA_OPTIONS + - wget https://github.com/sormuras/bach/raw/1.0.1/install-jdk.sh after_success: - .buildscript/deploy_snapshot.sh @@ -25,6 +39,8 @@ branches: notifications: email: false +sudo: false + cache: directories: - $HOME/.m2 @@ -13,23 +13,6 @@ // limitations under the License. // -package { - default_applicable_licenses: ["external_javapoet_license"], -} - -// Added automatically by a large-scale-change -// See: http://go/android-license-faq -license { - name: "external_javapoet_license", - visibility: [":__subpackages__"], - license_kinds: [ - "SPDX-license-identifier-Apache-2.0", - ], - license_text: [ - "LICENSE.txt", - ], -} - java_library_host { name: "javapoet", srcs: ["src/main/java/**/*.java"], diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b88c59..3933dd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,43 +1,6 @@ Change Log ========== -JavaPoet 1.13.0 *(2020-06-18)* ------------------------------ - - * New: Add support for explicit receiver parameters. - * Fix: Don't copy parameter annotations when creating a `ParameterSpec`. - - -JavaPoet 1.12.1 *(2020-01-20)* ------------------------------ - - * Fix: Ignore parameter annotations in `MethodSpec.overriding()`. - - -JavaPoet 1.12.0 *(2020-01-09)* ------------------------------ - - * New: Add `JavaFile.writeToPath()` and `JavaFile.writeToFile()` methods that return paths to the - generated file as `Path` and `File` respectively. - * New: Add `TypeSpec.alwaysQualify()` API to avoid clashes involving nested type names. - * New: Add overloads accepting `CodeBlock`s to `MethodSpec`'s control flow methods. - * New: Make list fields of all `Builder` types mutable. - * New: Add `CodeBlock.clear()`. - * New: Allow passing a custom `Charset` to `JavaFile.writeTo()`. - * New: Improved performance of `ClassName.simpleNames()` by memoizing results. - * New: Significant performance improvements for `CodeWriter.resolve()` as all nested simple names - of a `TypeSpec` get pre-computed. - * New: Add `TypeName.Builder.setName()` to allow overriding names passed in the constructor. - * New: Add `TypeName.canonicalName()`. - * Fix: Use `\\R` instead of `\n` as line separator in `CodeWriter.emitAndIndent()`. - * Fix: Copy originating elements in `TypeSpec.toBuilder()`. - * Fix: Ensure trailing newlines in Javadocs and method bodies. - * Fix: Copy annotations when creating a `ParameterSpec` from a `VariableElement`. - * Fix: Properly handle classes located in empty packages in `ClassName`. - * Fix: Only allow `final` modifier on a `ParameterSpec`. - * Fix: Use fully-qualified names for type names that are masked by type variable names. - - JavaPoet 1.11.1 *(2018-05-16)* ----------------------------- @@ -1,5 +1,7 @@ name: "JavaPoet" -description: "A Java API for generating .java source files" +description: + "A Java API for generating .java source files" + third_party { url { type: HOMEPAGE @@ -9,11 +11,7 @@ third_party { type: GIT value: "https://github.com/square/javapoet.git" } - version: "javapoet-1.13.0" - license_type: NOTICE - last_upgrade_date { - year: 2020 - month: 7 - day: 10 - } + version: "javapoet-1.11.1" + last_upgrade_date { year: 2018 month: 11 day: 19 } } + @@ -0,0 +1 @@ +LICENSE
\ No newline at end of file @@ -128,60 +128,6 @@ int multiply10to20() { Methods generating methods! And since JavaPoet generates source instead of bytecode, you can read through it to make sure it's right. -Some control flow statements, such as `if/else`, can have unlimited control flow possibilities. -You can handle those options using `nextControlFlow()`: - -```java -MethodSpec main = MethodSpec.methodBuilder("main") - .addStatement("long now = $T.currentTimeMillis()", System.class) - .beginControlFlow("if ($T.currentTimeMillis() < now)", System.class) - .addStatement("$T.out.println($S)", System.class, "Time travelling, woo hoo!") - .nextControlFlow("else if ($T.currentTimeMillis() == now)", System.class) - .addStatement("$T.out.println($S)", System.class, "Time stood still!") - .nextControlFlow("else") - .addStatement("$T.out.println($S)", System.class, "Ok, time still moving forward") - .endControlFlow() - .build(); -``` - -Which generates: - -```java -void main() { - long now = System.currentTimeMillis(); - if (System.currentTimeMillis() < now) { - System.out.println("Time travelling, woo hoo!"); - } else if (System.currentTimeMillis() == now) { - System.out.println("Time stood still!"); - } else { - System.out.println("Ok, time still moving forward"); - } -} -``` - -Catching exceptions using `try/catch` is also a use case for `nextControlFlow()`: - -```java -MethodSpec main = MethodSpec.methodBuilder("main") - .beginControlFlow("try") - .addStatement("throw new Exception($S)", "Failed") - .nextControlFlow("catch ($T e)", Exception.class) - .addStatement("throw new $T(e)", RuntimeException.class) - .endControlFlow() - .build(); -``` - -Which produces: - -```java -void main() { - try { - throw new Exception("Failed"); - } catch (Exception e) { - throw new RuntimeException(e); - } -} -``` ### $L for Literals @@ -728,7 +674,7 @@ public enum Roshambo { ### Anonymous Inner Classes -In the enum code, we used `TypeSpec.anonymousInnerClass()`. Anonymous inner classes can also be used in +In the enum code, we used `Types.anonymousInnerClass()`. Anonymous inner classes can also be used in code blocks. They are values that can be referenced with `$L`: ```java @@ -892,12 +838,12 @@ Download [the latest .jar][dl] or depend via Maven: <dependency> <groupId>com.squareup</groupId> <artifactId>javapoet</artifactId> - <version>1.12.1</version> + <version>1.11.1</version> </dependency> ``` or Gradle: ```groovy -compile 'com.squareup:javapoet:1.12.1' +compile 'com.squareup:javapoet:1.11.1' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. @@ -11,7 +11,7 @@ <groupId>com.squareup</groupId> <artifactId>javapoet</artifactId> - <version>1.13.0</version> + <version>1.11.1</version> <name>JavaPoet</name> <description>Use beautiful Java code to generate beautiful Java code.</description> @@ -94,7 +94,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> - <version>3.8.0</version> + <version>3.7.0</version> <configuration> <compilerId>javac-with-errorprone</compilerId> <forceJavacCompilerUse>true</forceJavacCompilerUse> @@ -123,7 +123,7 @@ <dependency> <groupId>com.puppycrawl.tools</groupId> <artifactId>checkstyle</artifactId> - <version>8.18</version> + <version>8.7</version> </dependency> </dependencies> <configuration> diff --git a/src/main/java/com/squareup/javapoet/AnnotationSpec.java b/src/main/java/com/squareup/javapoet/AnnotationSpec.java index 5525d7b..d1c5e53 100644 --- a/src/main/java/com/squareup/javapoet/AnnotationSpec.java +++ b/src/main/java/com/squareup/javapoet/AnnotationSpec.java @@ -192,8 +192,7 @@ public final class AnnotationSpec { public static final class Builder { private final TypeName type; - - public final Map<String, List<CodeBlock>> members = new LinkedHashMap<>(); + private final Map<String, List<CodeBlock>> members = new LinkedHashMap<>(); private Builder(TypeName type) { this.type = type; @@ -204,6 +203,8 @@ public final class AnnotationSpec { } public Builder addMember(String name, CodeBlock codeBlock) { + checkNotNull(name, "name == null"); + checkArgument(SourceVersion.isName(name), "not a valid name: %s", name); List<CodeBlock> values = members.computeIfAbsent(name, k -> new ArrayList<>()); values.add(codeBlock); return this; @@ -237,10 +238,6 @@ public final class AnnotationSpec { } public AnnotationSpec build() { - for (String name : members.keySet()) { - checkNotNull(name, "name == null"); - checkArgument(SourceVersion.isName(name), "not a valid name: %s", name); - } return new AnnotationSpec(this); } } diff --git a/src/main/java/com/squareup/javapoet/ClassName.java b/src/main/java/com/squareup/javapoet/ClassName.java index 4bef49d..99c4ed2 100644 --- a/src/main/java/com/squareup/javapoet/ClassName.java +++ b/src/main/java/com/squareup/javapoet/ClassName.java @@ -20,7 +20,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import javax.lang.model.element.Element; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; @@ -33,9 +32,6 @@ import static com.squareup.javapoet.Util.checkNotNull; public final class ClassName extends TypeName implements Comparable<ClassName> { public static final ClassName OBJECT = ClassName.get(Object.class); - /** The name representing the default Java package. */ - private static final String NO_PACKAGE = ""; - /** The package name of this class, or "" if this is in the default package. */ final String packageName; @@ -45,8 +41,6 @@ public final class ClassName extends TypeName implements Comparable<ClassName> { /** This class name, like "Entry" for java.util.Map.Entry. */ final String simpleName; - private List<String> simpleNames; - /** The full class name like "java.util.Map.Entry". */ final String canonicalName; @@ -57,7 +51,7 @@ public final class ClassName extends TypeName implements Comparable<ClassName> { private ClassName(String packageName, ClassName enclosingClassName, String simpleName, List<AnnotationSpec> annotations) { super(annotations); - this.packageName = Objects.requireNonNull(packageName, "packageName == null"); + this.packageName = packageName; this.enclosingClassName = enclosingClassName; this.simpleName = simpleName; this.canonicalName = enclosingClassName != null @@ -114,18 +108,11 @@ public final class ClassName extends TypeName implements Comparable<ClassName> { } public List<String> simpleNames() { - if (simpleNames != null) { - return simpleNames; - } - - if (enclosingClassName == null) { - simpleNames = Collections.singletonList(simpleName); - } else { - List<String> mutableNames = new ArrayList<>(); - mutableNames.addAll(enclosingClassName().simpleNames()); - mutableNames.add(simpleName); - simpleNames = Collections.unmodifiableList(mutableNames); + List<String> simpleNames = new ArrayList<>(); + if (enclosingClassName != null) { + simpleNames.addAll(enclosingClassName().simpleNames()); } + simpleNames.add(simpleName); return simpleNames; } @@ -151,14 +138,6 @@ public final class ClassName extends TypeName implements Comparable<ClassName> { return simpleName; } - /** - * Returns the full class name of this class. - * Like {@code "java.util.Map.Entry"} for {@link Map.Entry}. - * */ - public String canonicalName() { - return canonicalName; - } - public static ClassName get(Class<?> clazz) { checkNotNull(clazz, "clazz == null"); checkArgument(!clazz.isPrimitive(), "primitive types cannot be represented as a ClassName"); @@ -176,7 +155,7 @@ public final class ClassName extends TypeName implements Comparable<ClassName> { if (clazz.getEnclosingClass() == null) { // Avoid unreliable Class.getPackage(). https://github.com/square/javapoet/issues/295 int lastDot = clazz.getName().lastIndexOf('.'); - String packageName = (lastDot != -1) ? clazz.getName().substring(0, lastDot) : NO_PACKAGE; + String packageName = (lastDot != -1) ? clazz.getName().substring(0, lastDot) : null; return new ClassName(packageName, null, name); } @@ -198,7 +177,7 @@ public final class ClassName extends TypeName implements Comparable<ClassName> { p = classNameString.indexOf('.', p) + 1; checkArgument(p != 0, "couldn't make a guess for %s", classNameString); } - String packageName = p == 0 ? NO_PACKAGE : classNameString.substring(0, p - 1); + String packageName = p == 0 ? "" : classNameString.substring(0, p - 1); // Add class names like "Map" and "Entry". ClassName className = null; diff --git a/src/main/java/com/squareup/javapoet/CodeBlock.java b/src/main/java/com/squareup/javapoet/CodeBlock.java index 02542f5..33e3846 100644 --- a/src/main/java/com/squareup/javapoet/CodeBlock.java +++ b/src/main/java/com/squareup/javapoet/CodeBlock.java @@ -189,7 +189,7 @@ public final class CodeBlock { while (p < format.length()) { int nextP = format.indexOf("$", p); if (nextP == -1) { - formatParts.add(format.substring(p)); + formatParts.add(format.substring(p, format.length())); break; } @@ -424,12 +424,6 @@ public final class CodeBlock { return this; } - public Builder clear() { - formatParts.clear(); - args.clear(); - return this; - } - public CodeBlock build() { return new CodeBlock(this); } diff --git a/src/main/java/com/squareup/javapoet/CodeWriter.java b/src/main/java/com/squareup/javapoet/CodeWriter.java index 3b2f188..542f434 100644 --- a/src/main/java/com/squareup/javapoet/CodeWriter.java +++ b/src/main/java/com/squareup/javapoet/CodeWriter.java @@ -54,11 +54,9 @@ final class CodeWriter { private final List<TypeSpec> typeSpecStack = new ArrayList<>(); private final Set<String> staticImportClassNames; private final Set<String> staticImports; - private final Set<String> alwaysQualify; private final Map<String, ClassName> importedTypes; private final Map<String, ClassName> importableTypes = new LinkedHashMap<>(); private final Set<String> referencedNames = new LinkedHashSet<>(); - private final Multiset<String> currentTypeVariables = new Multiset<>(); private boolean trailingNewline; /** @@ -69,23 +67,19 @@ final class CodeWriter { int statementLine = -1; CodeWriter(Appendable out) { - this(out, " ", Collections.emptySet(), Collections.emptySet()); + this(out, " ", Collections.emptySet()); } - CodeWriter(Appendable out, String indent, Set<String> staticImports, Set<String> alwaysQualify) { - this(out, indent, Collections.emptyMap(), staticImports, alwaysQualify); + CodeWriter(Appendable out, String indent, Set<String> staticImports) { + this(out, indent, Collections.emptyMap(), staticImports); } - CodeWriter(Appendable out, - String indent, - Map<String, ClassName> importedTypes, - Set<String> staticImports, - Set<String> alwaysQualify) { + CodeWriter(Appendable out, String indent, Map<String, ClassName> importedTypes, + Set<String> staticImports) { this.out = new LineWrapper(out, indent, 100); this.indent = checkNotNull(indent, "indent == null"); this.importedTypes = checkNotNull(importedTypes, "importedTypes == null"); this.staticImports = checkNotNull(staticImports, "staticImports == null"); - this.alwaysQualify = checkNotNull(alwaysQualify, "alwaysQualify == null"); this.staticImportClassNames = new LinkedHashSet<>(); for (String signature : staticImports) { staticImportClassNames.add(signature.substring(0, signature.lastIndexOf('.'))); @@ -154,7 +148,7 @@ final class CodeWriter { emit("/**\n"); javadoc = true; try { - emit(javadocCodeBlock, true); + emit(javadocCodeBlock); } finally { javadoc = false; } @@ -193,8 +187,6 @@ final class CodeWriter { public void emitTypeVariables(List<TypeVariableName> typeVariables) throws IOException { if (typeVariables.isEmpty()) return; - typeVariables.forEach(typeVariable -> currentTypeVariables.add(typeVariable.name)); - emit("<"); boolean firstTypeVariable = true; for (TypeVariableName typeVariable : typeVariables) { @@ -211,10 +203,6 @@ final class CodeWriter { emit(">"); } - public void popTypeVariables(List<TypeVariableName> typeVariables) throws IOException { - typeVariables.forEach(typeVariable -> currentTypeVariables.remove(typeVariable.name)); - } - public CodeWriter emit(String s) throws IOException { return emitAndIndent(s); } @@ -224,10 +212,6 @@ final class CodeWriter { } public CodeWriter emit(CodeBlock codeBlock) throws IOException { - return emit(codeBlock, false); - } - - public CodeWriter emit(CodeBlock codeBlock, boolean ensureTrailingNewline) throws IOException { int a = 0; ClassName deferredTypeName = null; // used by "import static" logic ListIterator<String> partIterator = codeBlock.formatParts.listIterator(); @@ -316,9 +300,6 @@ final class CodeWriter { break; } } - if (ensureTrailingNewline && out.lastChar() != '\n') { - emit("\n"); - } return this; } @@ -372,12 +353,6 @@ final class CodeWriter { * names visible due to inheritance. */ String lookupName(ClassName className) { - // If the top level simple name is masked by a current type variable, use the canonical name. - String topLevelSimpleName = className.topLevelClassName().simpleName(); - if (currentTypeVariables.contains(topLevelSimpleName)) { - return className.canonicalName; - } - // Find the shortest suffix of className that resolves to className. This uses both local type // names (so `Entry` in `Map` refers to `Map.Entry`). Also uses imports. boolean nameResolved = false; @@ -399,7 +374,7 @@ final class CodeWriter { // If the class is in the same package, we're done. if (Objects.equals(packageName, className.packageName())) { - referencedNames.add(topLevelSimpleName); + referencedNames.add(className.topLevelClassName().simpleName()); return join(".", className.simpleNames()); } @@ -414,9 +389,6 @@ final class CodeWriter { private void importableType(ClassName className) { if (className.packageName().isEmpty()) { return; - } else if (alwaysQualify.contains(className.simpleName)) { - // TODO what about nested types like java.util.Map.Entry? - return; } ClassName topLevelClassName = className.topLevelClassName(); String simpleName = topLevelClassName.simpleName(); @@ -435,8 +407,10 @@ final class CodeWriter { // Match a child of the current (potentially nested) class. for (int i = typeSpecStack.size() - 1; i >= 0; i--) { TypeSpec typeSpec = typeSpecStack.get(i); - if (typeSpec.nestedTypesSimpleNames.contains(simpleName)) { - return stackClassName(i, simpleName); + for (TypeSpec visibleChild : typeSpec.typeSpecs) { + if (Objects.equals(visibleChild.name, simpleName)) { + return stackClassName(i, simpleName); + } } } @@ -469,7 +443,7 @@ final class CodeWriter { */ CodeWriter emitAndIndent(String s) throws IOException { boolean first = true; - for (String line : s.split("\\R", -1)) { + for (String line : s.split("\n", -1)) { // Emit a newline character. Make sure blank lines in Javadoc & comments look good. if (!first) { if ((javadoc || comment) && trailingNewline) { @@ -520,26 +494,4 @@ final class CodeWriter { result.keySet().removeAll(referencedNames); return result; } - - // A makeshift multi-set implementation - private static final class Multiset<T> { - private final Map<T, Integer> map = new LinkedHashMap<>(); - - void add(T t) { - int count = map.getOrDefault(t, 0); - map.put(t, count + 1); - } - - void remove(T t) { - int count = map.getOrDefault(t, 0); - if (count == 0) { - throw new IllegalStateException(t + " is not in the multiset"); - } - map.put(t, count - 1); - } - - boolean contains(T t) { - return map.getOrDefault(t, 0) > 0; - } - } } diff --git a/src/main/java/com/squareup/javapoet/FieldSpec.java b/src/main/java/com/squareup/javapoet/FieldSpec.java index f530d6e..851b36d 100644 --- a/src/main/java/com/squareup/javapoet/FieldSpec.java +++ b/src/main/java/com/squareup/javapoet/FieldSpec.java @@ -111,11 +111,10 @@ public final class FieldSpec { private final String name; private final CodeBlock.Builder javadoc = CodeBlock.builder(); + private final List<AnnotationSpec> annotations = new ArrayList<>(); + private final List<Modifier> modifiers = new ArrayList<>(); private CodeBlock initializer = null; - public final List<AnnotationSpec> annotations = new ArrayList<>(); - public final List<Modifier> modifiers = new ArrayList<>(); - private Builder(TypeName type, String name) { this.type = type; this.name = name; diff --git a/src/main/java/com/squareup/javapoet/JavaFile.java b/src/main/java/com/squareup/javapoet/JavaFile.java index da3dd86..e7662dd 100644 --- a/src/main/java/com/squareup/javapoet/JavaFile.java +++ b/src/main/java/com/squareup/javapoet/JavaFile.java @@ -22,12 +22,10 @@ import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.URI; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -61,7 +59,6 @@ public final class JavaFile { public final TypeSpec typeSpec; public final boolean skipJavaLangImports; private final Set<String> staticImports; - private final Set<String> alwaysQualify; private final String indent; private JavaFile(Builder builder) { @@ -71,63 +68,21 @@ public final class JavaFile { this.skipJavaLangImports = builder.skipJavaLangImports; this.staticImports = Util.immutableSet(builder.staticImports); this.indent = builder.indent; - - Set<String> alwaysQualifiedNames = new LinkedHashSet<>(); - fillAlwaysQualifiedNames(builder.typeSpec, alwaysQualifiedNames); - this.alwaysQualify = Util.immutableSet(alwaysQualifiedNames); - } - - private void fillAlwaysQualifiedNames(TypeSpec spec, Set<String> alwaysQualifiedNames) { - alwaysQualifiedNames.addAll(spec.alwaysQualifiedNames); - for (TypeSpec nested : spec.typeSpecs) { - fillAlwaysQualifiedNames(nested, alwaysQualifiedNames); - } } public void writeTo(Appendable out) throws IOException { // First pass: emit the entire class, just to collect the types we'll need to import. - CodeWriter importsCollector = new CodeWriter( - NULL_APPENDABLE, - indent, - staticImports, - alwaysQualify - ); + CodeWriter importsCollector = new CodeWriter(NULL_APPENDABLE, indent, staticImports); emit(importsCollector); Map<String, ClassName> suggestedImports = importsCollector.suggestedImports(); // Second pass: write the code, taking advantage of the imports. - CodeWriter codeWriter - = new CodeWriter(out, indent, suggestedImports, staticImports, alwaysQualify); + CodeWriter codeWriter = new CodeWriter(out, indent, suggestedImports, staticImports); emit(codeWriter); } /** Writes this to {@code directory} as UTF-8 using the standard directory structure. */ public void writeTo(Path directory) throws IOException { - writeToPath(directory); - } - - /** - * Writes this to {@code directory} with the provided {@code charset} using the standard directory - * structure. - */ - public void writeTo(Path directory, Charset charset) throws IOException { - writeToPath(directory, charset); - } - - /** - * Writes this to {@code directory} as UTF-8 using the standard directory structure. - * Returns the {@link Path} instance to which source is actually written. - */ - public Path writeToPath(Path directory) throws IOException { - return writeToPath(directory, UTF_8); - } - - /** - * Writes this to {@code directory} with the provided {@code charset} using the standard directory - * structure. - * Returns the {@link Path} instance to which source is actually written. - */ - public Path writeToPath(Path directory, Charset charset) throws IOException { checkArgument(Files.notExists(directory) || Files.isDirectory(directory), "path %s exists but is not a directory.", directory); Path outputDirectory = directory; @@ -139,11 +94,9 @@ public final class JavaFile { } Path outputPath = outputDirectory.resolve(typeSpec.name + ".java"); - try (Writer writer = new OutputStreamWriter(Files.newOutputStream(outputPath), charset)) { + try (Writer writer = new OutputStreamWriter(Files.newOutputStream(outputPath), UTF_8)) { writeTo(writer); } - - return outputPath; } /** Writes this to {@code directory} as UTF-8 using the standard directory structure. */ @@ -151,15 +104,6 @@ public final class JavaFile { writeTo(directory.toPath()); } - /** - * Writes this to {@code directory} as UTF-8 using the standard directory structure. - * Returns the {@link File} instance to which source is actually written. - */ - public File writeToFile(File directory) throws IOException { - final Path outputPath = writeToPath(directory.toPath()); - return outputPath.toFile(); - } - /** Writes this to {@code filer}. */ public void writeTo(Filer filer) throws IOException { String fileName = packageName.isEmpty() @@ -200,12 +144,7 @@ public final class JavaFile { int importedTypesCount = 0; for (ClassName className : new TreeSet<>(codeWriter.importedTypes().values())) { - // TODO what about nested types like java.util.Map.Entry? - if (skipJavaLangImports - && className.packageName().equals("java.lang") - && !alwaysQualify.contains(className.simpleName)) { - continue; - } + if (skipJavaLangImports && className.packageName().equals("java.lang")) continue; codeWriter.emit("import $L;\n", className.withoutAnnotations()); importedTypesCount++; } @@ -277,11 +216,10 @@ public final class JavaFile { private final String packageName; private final TypeSpec typeSpec; private final CodeBlock.Builder fileComment = CodeBlock.builder(); + private final Set<String> staticImports = new TreeSet<>(); private boolean skipJavaLangImports; private String indent = " "; - public final Set<String> staticImports = new TreeSet<>(); - private Builder(String packageName, TypeSpec typeSpec) { this.packageName = packageName; this.typeSpec = typeSpec; diff --git a/src/main/java/com/squareup/javapoet/LineWrapper.java b/src/main/java/com/squareup/javapoet/LineWrapper.java index 928d9f4..6aa3131 100644 --- a/src/main/java/com/squareup/javapoet/LineWrapper.java +++ b/src/main/java/com/squareup/javapoet/LineWrapper.java @@ -24,7 +24,7 @@ import static com.squareup.javapoet.Util.checkNotNull; * or soft-wrapping spaces using {@link #wrappingSpace}. */ final class LineWrapper { - private final RecordingAppendable out; + private final Appendable out; private final String indent; private final int columnLimit; private boolean closed; @@ -47,16 +47,11 @@ final class LineWrapper { LineWrapper(Appendable out, String indent, int columnLimit) { checkNotNull(out, "out == null"); - this.out = new RecordingAppendable(out); + this.out = out; this.indent = indent; this.columnLimit = columnLimit; } - /** @return the last emitted char or {@link Character#MIN_VALUE} if nothing emitted yet. */ - char lastChar() { - return out.lastChar; - } - /** Emit {@code s}. This may be buffered to permit line wraps to be inserted. */ void append(String s) throws IOException { if (closed) throw new IllegalStateException("closed"); @@ -139,33 +134,4 @@ final class LineWrapper { private enum FlushType { WRAP, SPACE, EMPTY; } - - /** A delegating {@link Appendable} that records info about the chars passing through it. */ - static final class RecordingAppendable implements Appendable { - private final Appendable delegate; - - char lastChar = Character.MIN_VALUE; - - RecordingAppendable(Appendable delegate) { - this.delegate = delegate; - } - - @Override public Appendable append(CharSequence csq) throws IOException { - int length = csq.length(); - if (length != 0) { - lastChar = csq.charAt(length - 1); - } - return delegate.append(csq); - } - - @Override public Appendable append(CharSequence csq, int start, int end) throws IOException { - CharSequence sub = csq.subSequence(start, end); - return append(sub); - } - - @Override public Appendable append(char c) throws IOException { - lastChar = c; - return delegate.append(c); - } - } } diff --git a/src/main/java/com/squareup/javapoet/MethodSpec.java b/src/main/java/com/squareup/javapoet/MethodSpec.java index 67722c7..a2c7c43 100644 --- a/src/main/java/com/squareup/javapoet/MethodSpec.java +++ b/src/main/java/com/squareup/javapoet/MethodSpec.java @@ -82,7 +82,7 @@ public final class MethodSpec { void emit(CodeWriter codeWriter, String enclosingName, Set<Modifier> implicitModifiers) throws IOException { - codeWriter.emitJavadoc(javadocWithParameters()); + codeWriter.emitJavadoc(javadoc); codeWriter.emitAnnotations(annotations, false); codeWriter.emitModifiers(modifiers, implicitModifiers); @@ -132,26 +132,11 @@ public final class MethodSpec { codeWriter.emit(" {\n"); codeWriter.indent(); - codeWriter.emit(code, true); + codeWriter.emit(code); codeWriter.unindent(); codeWriter.emit("}\n"); } - codeWriter.popTypeVariables(typeVariables); - } - - private CodeBlock javadocWithParameters() { - CodeBlock.Builder builder = javadoc.toBuilder(); - boolean emitTagNewline = true; - for (ParameterSpec parameterSpec : parameters) { - if (!parameterSpec.javadoc.isEmpty()) { - // Emit a new line before @param section only if the method javadoc is present. - if (emitTagNewline && !javadoc.isEmpty()) builder.add("\n"); - emitTagNewline = false; - builder.add("@param $L $L", parameterSpec.name, parameterSpec.javadoc); - } - } - return builder.build(); } public boolean hasModifier(Modifier modifier) { @@ -292,31 +277,25 @@ public final class MethodSpec { } public static final class Builder { - private String name; + private final String name; private final CodeBlock.Builder javadoc = CodeBlock.builder(); + private final List<AnnotationSpec> annotations = new ArrayList<>(); + private final List<Modifier> modifiers = new ArrayList<>(); + private List<TypeVariableName> typeVariables = new ArrayList<>(); private TypeName returnType; + private final List<ParameterSpec> parameters = new ArrayList<>(); private final Set<TypeName> exceptions = new LinkedHashSet<>(); private final CodeBlock.Builder code = CodeBlock.builder(); private boolean varargs; private CodeBlock defaultValue; - public final List<TypeVariableName> typeVariables = new ArrayList<>(); - public final List<AnnotationSpec> annotations = new ArrayList<>(); - public final List<Modifier> modifiers = new ArrayList<>(); - public final List<ParameterSpec> parameters = new ArrayList<>(); - private Builder(String name) { - setName(name); - } - - public Builder setName(String name) { checkNotNull(name, "name == null"); checkArgument(name.equals(CONSTRUCTOR) || SourceVersion.isName(name), "not a valid name: %s", name); this.name = name; this.returnType = name.equals(CONSTRUCTOR) ? null : TypeName.VOID; - return this; } public Builder addJavadoc(String format, Object... args) { @@ -475,14 +454,6 @@ public final class MethodSpec { } /** - * @param codeBlock the control flow construct and its code, such as "if (foo == 5)". - * Shouldn't contain braces or newline characters. - */ - public Builder beginControlFlow(CodeBlock codeBlock) { - return beginControlFlow("$L", codeBlock); - } - - /** * @param controlFlow the control flow construct and its code, such as "else if (foo == 10)". * Shouldn't contain braces or newline characters. */ @@ -491,14 +462,6 @@ public final class MethodSpec { return this; } - /** - * @param codeBlock the control flow construct and its code, such as "else if (foo == 10)". - * Shouldn't contain braces or newline characters. - */ - public Builder nextControlFlow(CodeBlock codeBlock) { - return nextControlFlow("$L", codeBlock); - } - public Builder endControlFlow() { code.endControlFlow(); return this; @@ -513,14 +476,6 @@ public final class MethodSpec { return this; } - /** - * @param codeBlock the optional control flow construct and its code, such as - * "while(foo == 20)". Only used for "do/while" control flows. - */ - public Builder endControlFlow(CodeBlock codeBlock) { - return endControlFlow("$L", codeBlock); - } - public Builder addStatement(String format, Object... args) { code.addStatement(format, args); return this; diff --git a/src/main/java/com/squareup/javapoet/ParameterSpec.java b/src/main/java/com/squareup/javapoet/ParameterSpec.java index 8b2b6ed..63da3f2 100644 --- a/src/main/java/com/squareup/javapoet/ParameterSpec.java +++ b/src/main/java/com/squareup/javapoet/ParameterSpec.java @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.List; import java.util.Set; import javax.lang.model.SourceVersion; -import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.VariableElement; @@ -36,14 +35,12 @@ public final class ParameterSpec { public final List<AnnotationSpec> annotations; public final Set<Modifier> modifiers; public final TypeName type; - public final CodeBlock javadoc; private ParameterSpec(Builder builder) { this.name = checkNotNull(builder.name, "name == null"); this.annotations = Util.immutableList(builder.annotations); this.modifiers = Util.immutableSet(builder.modifiers); this.type = checkNotNull(builder.type, "type == null"); - this.javadoc = builder.javadoc.build(); } public boolean hasModifier(Modifier modifier) { @@ -84,12 +81,8 @@ public final class ParameterSpec { } public static ParameterSpec get(VariableElement element) { - checkArgument(element.getKind().equals(ElementKind.PARAMETER), "element is not a parameter"); - TypeName type = TypeName.get(element.asType()); String name = element.getSimpleName().toString(); - // Copying parameter annotations can be incorrect so we're deliberately not including them. - // See https://github.com/square/javapoet/issues/482. return ParameterSpec.builder(type, name) .addModifiers(element.getModifiers()) .build(); @@ -103,18 +96,9 @@ public final class ParameterSpec { return result; } - private static boolean isValidParameterName(String name) { - // Allow "this" for explicit receiver parameters - // See https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.1. - if (name.endsWith(".this")) { - return SourceVersion.isIdentifier(name.substring(0, name.length() - ".this".length())); - } - return name.equals("this") || SourceVersion.isName(name); - } - public static Builder builder(TypeName type, String name, Modifier... modifiers) { checkNotNull(type, "type == null"); - checkArgument(isValidParameterName(name), "not a valid name: %s", name); + checkArgument(SourceVersion.isName(name), "not a valid name: %s", name); return new Builder(type, name) .addModifiers(modifiers); } @@ -137,26 +121,15 @@ public final class ParameterSpec { public static final class Builder { private final TypeName type; private final String name; - private final CodeBlock.Builder javadoc = CodeBlock.builder(); - public final List<AnnotationSpec> annotations = new ArrayList<>(); - public final List<Modifier> modifiers = new ArrayList<>(); + private final List<AnnotationSpec> annotations = new ArrayList<>(); + private final List<Modifier> modifiers = new ArrayList<>(); private Builder(TypeName type, String name) { this.type = type; this.name = name; } - public Builder addJavadoc(String format, Object... args) { - javadoc.add(format, args); - return this; - } - - public Builder addJavadoc(CodeBlock block) { - javadoc.add(block); - return this; - } - public Builder addAnnotations(Iterable<AnnotationSpec> annotationSpecs) { checkArgument(annotationSpecs != null, "annotationSpecs == null"); for (AnnotationSpec annotationSpec : annotationSpecs) { @@ -187,9 +160,6 @@ public final class ParameterSpec { public Builder addModifiers(Iterable<Modifier> modifiers) { checkNotNull(modifiers, "modifiers == null"); for (Modifier modifier : modifiers) { - if (!modifier.equals(Modifier.FINAL)) { - throw new IllegalStateException("unexpected parameter modifier: " + modifier); - } this.modifiers.add(modifier); } return this; diff --git a/src/main/java/com/squareup/javapoet/TypeName.java b/src/main/java/com/squareup/javapoet/TypeName.java index c0986bb..38877f7 100644 --- a/src/main/java/com/squareup/javapoet/TypeName.java +++ b/src/main/java/com/squareup/javapoet/TypeName.java @@ -44,7 +44,7 @@ import javax.lang.model.util.SimpleTypeVisitor8; * identifies composite types like {@code char[]} and {@code Set<Long>}. * * <p>Type names are dumb identifiers only and do not model the values they name. For example, the - * type name for {@code java.util.List} doesn't know about the {@code size()} method, the fact that + * type name for {@code java.lang.List} doesn't know about the {@code size()} method, the fact that * lists are collections, or even that it accepts a single type parameter. * * <p>Instances of this class are immutable value objects that implement {@code equals()} and {@code diff --git a/src/main/java/com/squareup/javapoet/TypeSpec.java b/src/main/java/com/squareup/javapoet/TypeSpec.java index 5fb2bb3..46de3a5 100644 --- a/src/main/java/com/squareup/javapoet/TypeSpec.java +++ b/src/main/java/com/squareup/javapoet/TypeSpec.java @@ -16,16 +16,13 @@ package com.squareup.javapoet; import java.io.IOException; -import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -33,11 +30,6 @@ import java.util.Set; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.NoType; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.ElementFilter; import static com.squareup.javapoet.Util.checkArgument; import static com.squareup.javapoet.Util.checkNotNull; @@ -61,9 +53,7 @@ public final class TypeSpec { public final CodeBlock initializerBlock; public final List<MethodSpec> methodSpecs; public final List<TypeSpec> typeSpecs; - final Set<String> nestedTypesSimpleNames; public final List<Element> originatingElements; - public final Set<String> alwaysQualifiedNames; private TypeSpec(Builder builder) { this.kind = builder.kind; @@ -81,16 +71,12 @@ public final class TypeSpec { this.initializerBlock = builder.initializerBlock.build(); this.methodSpecs = Util.immutableList(builder.methodSpecs); this.typeSpecs = Util.immutableList(builder.typeSpecs); - this.alwaysQualifiedNames = Util.immutableSet(builder.alwaysQualifiedNames); - nestedTypesSimpleNames = new HashSet<>(builder.typeSpecs.size()); List<Element> originatingElementsMutable = new ArrayList<>(); originatingElementsMutable.addAll(builder.originatingElements); for (TypeSpec typeSpec : builder.typeSpecs) { - nestedTypesSimpleNames.add(typeSpec.name); originatingElementsMutable.addAll(typeSpec.originatingElements); } - this.originatingElements = Util.immutableList(originatingElementsMutable); } @@ -116,8 +102,6 @@ public final class TypeSpec { this.methodSpecs = Collections.emptyList(); this.typeSpecs = Collections.emptyList(); this.originatingElements = Collections.emptyList(); - this.nestedTypesSimpleNames = Collections.emptySet(); - this.alwaysQualifiedNames = Collections.emptySet(); } public boolean hasModifier(Modifier modifier) { @@ -149,7 +133,9 @@ public final class TypeSpec { } public static Builder anonymousClassBuilder(String typeArgumentsFormat, Object... args) { - return anonymousClassBuilder(CodeBlock.of(typeArgumentsFormat, args)); + return anonymousClassBuilder(CodeBlock.builder() + .add(typeArgumentsFormat, args) + .build()); } public static Builder anonymousClassBuilder(CodeBlock typeArguments) { @@ -178,8 +164,6 @@ public final class TypeSpec { builder.typeSpecs.addAll(typeSpecs); builder.initializerBlock.add(initializerBlock); builder.staticBlock.add(staticBlock); - builder.originatingElements.addAll(originatingElements); - builder.alwaysQualifiedNames.addAll(alwaysQualifiedNames); return builder; } @@ -332,7 +316,6 @@ public final class TypeSpec { codeWriter.unindent(); codeWriter.popType(); - codeWriter.popTypeVariables(typeVariables); codeWriter.emit("}"); if (enumName == null && anonymousTypeArguments == null) { @@ -412,20 +395,18 @@ public final class TypeSpec { private final CodeBlock anonymousTypeArguments; private final CodeBlock.Builder javadoc = CodeBlock.builder(); + private final List<AnnotationSpec> annotations = new ArrayList<>(); + private final List<Modifier> modifiers = new ArrayList<>(); + private final List<TypeVariableName> typeVariables = new ArrayList<>(); private TypeName superclass = ClassName.OBJECT; + private final List<TypeName> superinterfaces = new ArrayList<>(); + private final Map<String, TypeSpec> enumConstants = new LinkedHashMap<>(); + private final List<FieldSpec> fieldSpecs = new ArrayList<>(); private final CodeBlock.Builder staticBlock = CodeBlock.builder(); private final CodeBlock.Builder initializerBlock = CodeBlock.builder(); - - public final Map<String, TypeSpec> enumConstants = new LinkedHashMap<>(); - public final List<AnnotationSpec> annotations = new ArrayList<>(); - public final List<Modifier> modifiers = new ArrayList<>(); - public final List<TypeVariableName> typeVariables = new ArrayList<>(); - public final List<TypeName> superinterfaces = new ArrayList<>(); - public final List<FieldSpec> fieldSpecs = new ArrayList<>(); - public final List<MethodSpec> methodSpecs = new ArrayList<>(); - public final List<TypeSpec> typeSpecs = new ArrayList<>(); - public final List<Element> originatingElements = new ArrayList<>(); - public final Set<String> alwaysQualifiedNames = new LinkedHashSet<>(); + private final List<MethodSpec> methodSpecs = new ArrayList<>(); + private final List<TypeSpec> typeSpecs = new ArrayList<>(); + private final List<Element> originatingElements = new ArrayList<>(); private Builder(Kind kind, String name, CodeBlock anonymousTypeArguments) { @@ -468,11 +449,16 @@ public final class TypeSpec { } public Builder addModifiers(Modifier... modifiers) { - Collections.addAll(this.modifiers, modifiers); + checkState(anonymousTypeArguments == null, "forbidden on anonymous types."); + for (Modifier modifier : modifiers) { + checkArgument(modifier != null, "modifiers contain null"); + this.modifiers.add(modifier); + } return this; } public Builder addTypeVariables(Iterable<TypeVariableName> typeVariables) { + checkState(anonymousTypeArguments == null, "forbidden on anonymous types."); checkArgument(typeVariables != null, "typeVariables == null"); for (TypeVariableName typeVariable : typeVariables) { this.typeVariables.add(typeVariable); @@ -481,6 +467,7 @@ public final class TypeSpec { } public Builder addTypeVariable(TypeVariableName typeVariable) { + checkState(anonymousTypeArguments == null, "forbidden on anonymous types."); typeVariables.add(typeVariable); return this; } @@ -495,32 +482,7 @@ public final class TypeSpec { } public Builder superclass(Type superclass) { - return superclass(superclass, true); - } - - public Builder superclass(Type superclass, boolean avoidNestedTypeNameClashes) { - superclass(TypeName.get(superclass)); - if (avoidNestedTypeNameClashes) { - Class<?> clazz = getRawType(superclass); - if (clazz != null) { - avoidClashesWithNestedClasses(clazz); - } - } - return this; - } - - public Builder superclass(TypeMirror superclass) { - return superclass(superclass, true); - } - - public Builder superclass(TypeMirror superclass, boolean avoidNestedTypeNameClashes) { - superclass(TypeName.get(superclass)); - if (avoidNestedTypeNameClashes && superclass instanceof DeclaredType) { - TypeElement superInterfaceElement = - (TypeElement) ((DeclaredType) superclass).asElement(); - avoidClashesWithNestedClasses(superInterfaceElement); - } - return this; + return superclass(TypeName.get(superclass)); } public Builder addSuperinterfaces(Iterable<? extends TypeName> superinterfaces) { @@ -538,43 +500,7 @@ public final class TypeSpec { } public Builder addSuperinterface(Type superinterface) { - return addSuperinterface(superinterface, true); - } - - public Builder addSuperinterface(Type superinterface, boolean avoidNestedTypeNameClashes) { - addSuperinterface(TypeName.get(superinterface)); - if (avoidNestedTypeNameClashes) { - Class<?> clazz = getRawType(superinterface); - if (clazz != null) { - avoidClashesWithNestedClasses(clazz); - } - } - return this; - } - - private Class<?> getRawType(Type type) { - if (type instanceof Class<?>) { - return (Class<?>) type; - } else if (type instanceof ParameterizedType) { - return getRawType(((ParameterizedType) type).getRawType()); - } else { - return null; - } - } - - public Builder addSuperinterface(TypeMirror superinterface) { - return addSuperinterface(superinterface, true); - } - - public Builder addSuperinterface(TypeMirror superinterface, - boolean avoidNestedTypeNameClashes) { - addSuperinterface(TypeName.get(superinterface)); - if (avoidNestedTypeNameClashes && superinterface instanceof DeclaredType) { - TypeElement superInterfaceElement = - (TypeElement) ((DeclaredType) superinterface).asElement(); - avoidClashesWithNestedClasses(superInterfaceElement); - } - return this; + return addSuperinterface(TypeName.get(superinterface)); } public Builder addEnumConstant(String name) { @@ -582,6 +508,10 @@ public final class TypeSpec { } public Builder addEnumConstant(String name, TypeSpec typeSpec) { + checkState(kind == Kind.ENUM, "%s is not enum", this.name); + checkArgument(typeSpec.anonymousTypeArguments != null, + "enum constants must have anonymous type arguments"); + checkArgument(SourceVersion.isName(name), "not a valid enum constant: %s", name); enumConstants.put(name, typeSpec); return this; } @@ -595,6 +525,12 @@ public final class TypeSpec { } public Builder addField(FieldSpec fieldSpec) { + if (kind == Kind.INTERFACE || kind == Kind.ANNOTATION) { + requireExactlyOneOf(fieldSpec.modifiers, Modifier.PUBLIC, Modifier.PRIVATE); + Set<Modifier> check = EnumSet.of(Modifier.STATIC, Modifier.FINAL); + checkState(fieldSpec.modifiers.containsAll(check), "%s %s.%s requires modifiers %s", + kind, name, fieldSpec.name, check); + } fieldSpecs.add(fieldSpec); return this; } @@ -633,6 +569,23 @@ public final class TypeSpec { } public Builder addMethod(MethodSpec methodSpec) { + if (kind == Kind.INTERFACE) { + requireExactlyOneOf(methodSpec.modifiers, Modifier.ABSTRACT, Modifier.STATIC, + Modifier.DEFAULT); + requireExactlyOneOf(methodSpec.modifiers, Modifier.PUBLIC, Modifier.PRIVATE); + } else if (kind == Kind.ANNOTATION) { + checkState(methodSpec.modifiers.equals(kind.implicitMethodModifiers), + "%s %s.%s requires modifiers %s", + kind, name, methodSpec.name, kind.implicitMethodModifiers); + } + if (kind != Kind.ANNOTATION) { + checkState(methodSpec.defaultValue == null, "%s %s.%s cannot have a default value", + kind, name, methodSpec.name); + } + if (kind != Kind.INTERFACE) { + checkState(!methodSpec.hasModifier(Modifier.DEFAULT), "%s %s.%s cannot be default", + kind, name, methodSpec.name); + } methodSpecs.add(methodSpec); return this; } @@ -646,6 +599,9 @@ public final class TypeSpec { } public Builder addType(TypeSpec typeSpec) { + checkArgument(typeSpec.modifiers.containsAll(kind.implicitTypeModifiers), + "%s %s.%s requires modifiers %s", kind, name, typeSpec.name, + kind.implicitTypeModifiers); typeSpecs.add(typeSpec); return this; } @@ -655,171 +611,10 @@ public final class TypeSpec { return this; } - public Builder alwaysQualify(String... simpleNames) { - checkArgument(simpleNames != null, "simpleNames == null"); - for (String name : simpleNames) { - checkArgument( - name != null, - "null entry in simpleNames array: %s", - Arrays.toString(simpleNames) - ); - alwaysQualifiedNames.add(name); - } - return this; - } - - /** - * Call this to always fully qualify any types that would conflict with possibly nested types of - * this {@code typeElement}. For example - if the following type was passed in as the - * typeElement: - * - * <pre><code> - * class Foo { - * class NestedTypeA { - * - * } - * class NestedTypeB { - * - * } - * } - * </code></pre> - * - * <p> - * Then this would add {@code "NestedTypeA"} and {@code "NestedTypeB"} as names that should - * always be qualified via {@link #alwaysQualify(String...)}. This way they would avoid - * possible import conflicts when this JavaFile is written. - * - * @param typeElement the {@link TypeElement} with nested types to avoid clashes with. - * @return this builder instance. - */ - public Builder avoidClashesWithNestedClasses(TypeElement typeElement) { - checkArgument(typeElement != null, "typeElement == null"); - for (TypeElement nestedType : ElementFilter.typesIn(typeElement.getEnclosedElements())) { - alwaysQualify(nestedType.getSimpleName().toString()); - } - TypeMirror superclass = typeElement.getSuperclass(); - if (!(superclass instanceof NoType) && superclass instanceof DeclaredType) { - TypeElement superclassElement = (TypeElement) ((DeclaredType) superclass).asElement(); - avoidClashesWithNestedClasses(superclassElement); - } - for (TypeMirror superinterface : typeElement.getInterfaces()) { - if (superinterface instanceof DeclaredType) { - TypeElement superinterfaceElement - = (TypeElement) ((DeclaredType) superinterface).asElement(); - avoidClashesWithNestedClasses(superinterfaceElement); - } - } - return this; - } - - /** - * Call this to always fully qualify any types that would conflict with possibly nested types of - * this {@code typeElement}. For example - if the following type was passed in as the - * typeElement: - * - * <pre><code> - * class Foo { - * class NestedTypeA { - * - * } - * class NestedTypeB { - * - * } - * } - * </code></pre> - * - * <p> - * Then this would add {@code "NestedTypeA"} and {@code "NestedTypeB"} as names that should - * always be qualified via {@link #alwaysQualify(String...)}. This way they would avoid - * possible import conflicts when this JavaFile is written. - * - * @param clazz the {@link Class} with nested types to avoid clashes with. - * @return this builder instance. - */ - public Builder avoidClashesWithNestedClasses(Class<?> clazz) { - checkArgument(clazz != null, "clazz == null"); - for (Class<?> nestedType : clazz.getDeclaredClasses()) { - alwaysQualify(nestedType.getSimpleName()); - } - Class<?> superclass = clazz.getSuperclass(); - if (superclass != null && !Object.class.equals(superclass)) { - avoidClashesWithNestedClasses(superclass); - } - for (Class<?> superinterface : clazz.getInterfaces()) { - avoidClashesWithNestedClasses(superinterface); - } - return this; - } - public TypeSpec build() { - for (AnnotationSpec annotationSpec : annotations) { - checkNotNull(annotationSpec, "annotationSpec == null"); - } - - if (!modifiers.isEmpty()) { - checkState(anonymousTypeArguments == null, "forbidden on anonymous types."); - for (Modifier modifier : modifiers) { - checkArgument(modifier != null, "modifiers contain null"); - } - } - checkArgument(kind != Kind.ENUM || !enumConstants.isEmpty(), "at least one enum constant is required for %s", name); - for (TypeName superinterface : superinterfaces) { - checkArgument(superinterface != null, "superinterfaces contains null"); - } - - if (!typeVariables.isEmpty()) { - checkState(anonymousTypeArguments == null, - "typevariables are forbidden on anonymous types."); - for (TypeVariableName typeVariableName : typeVariables) { - checkArgument(typeVariableName != null, "typeVariables contain null"); - } - } - - for (Map.Entry<String, TypeSpec> enumConstant : enumConstants.entrySet()) { - checkState(kind == Kind.ENUM, "%s is not enum", this.name); - checkArgument(enumConstant.getValue().anonymousTypeArguments != null, - "enum constants must have anonymous type arguments"); - checkArgument(SourceVersion.isName(name), "not a valid enum constant: %s", name); - } - - for (FieldSpec fieldSpec : fieldSpecs) { - if (kind == Kind.INTERFACE || kind == Kind.ANNOTATION) { - requireExactlyOneOf(fieldSpec.modifiers, Modifier.PUBLIC, Modifier.PRIVATE); - Set<Modifier> check = EnumSet.of(Modifier.STATIC, Modifier.FINAL); - checkState(fieldSpec.modifiers.containsAll(check), "%s %s.%s requires modifiers %s", - kind, name, fieldSpec.name, check); - } - } - - for (MethodSpec methodSpec : methodSpecs) { - if (kind == Kind.INTERFACE) { - requireExactlyOneOf(methodSpec.modifiers, Modifier.ABSTRACT, Modifier.STATIC, - Modifier.DEFAULT); - requireExactlyOneOf(methodSpec.modifiers, Modifier.PUBLIC, Modifier.PRIVATE); - } else if (kind == Kind.ANNOTATION) { - checkState(methodSpec.modifiers.equals(kind.implicitMethodModifiers), - "%s %s.%s requires modifiers %s", - kind, name, methodSpec.name, kind.implicitMethodModifiers); - } - if (kind != Kind.ANNOTATION) { - checkState(methodSpec.defaultValue == null, "%s %s.%s cannot have a default value", - kind, name, methodSpec.name); - } - if (kind != Kind.INTERFACE) { - checkState(!methodSpec.hasModifier(Modifier.DEFAULT), "%s %s.%s cannot be default", - kind, name, methodSpec.name); - } - } - - for (TypeSpec typeSpec : typeSpecs) { - checkArgument(typeSpec.modifiers.containsAll(kind.implicitTypeModifiers), - "%s %s.%s requires modifiers %s", kind, name, typeSpec.name, - kind.implicitTypeModifiers); - } - boolean isAbstract = modifiers.contains(Modifier.ABSTRACT) || kind != Kind.CLASS; for (MethodSpec methodSpec : methodSpecs) { checkArgument(isAbstract || !methodSpec.hasModifier(Modifier.ABSTRACT), diff --git a/src/test/java/ClassNameNoPackageTest.java b/src/test/java/ClassNameNoPackageTest.java deleted file mode 100644 index 8b8545d..0000000 --- a/src/test/java/ClassNameNoPackageTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -import static com.google.common.truth.Truth.assertThat; - -import com.squareup.javapoet.ClassName; -import org.junit.Test; - -/** - * Since it is impossible to import classes from the default package into other - * modules, this test must live in this package. - */ -public final class ClassNameNoPackageTest { - @Test public void shouldSupportClassInDefaultPackage() { - ClassName className = ClassName.get(ClassNameNoPackageTest.class); - assertThat(className.packageName()).isEqualTo(""); - assertThat(className.simpleName()).isEqualTo("ClassNameNoPackageTest"); - assertThat(className.toString()).isEqualTo("ClassNameNoPackageTest"); - } -} diff --git a/src/test/java/com/squareup/javapoet/AnnotationSpecTest.java b/src/test/java/com/squareup/javapoet/AnnotationSpecTest.java index 97c1e6e..49606c7 100644 --- a/src/test/java/com/squareup/javapoet/AnnotationSpecTest.java +++ b/src/test/java/com/squareup/javapoet/AnnotationSpecTest.java @@ -20,8 +20,6 @@ import java.lang.annotation.Annotation; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.Arrays; - import javax.lang.model.element.TypeElement; import org.junit.Rule; import org.junit.Test; @@ -373,16 +371,6 @@ public final class AnnotationSpecTest { } } - @Test public void modifyMembers() { - AnnotationSpec.Builder builder = AnnotationSpec.builder(SuppressWarnings.class) - .addMember("value", "$S", "Foo"); - - builder.members.clear(); - builder.members.put("value", Arrays.asList(CodeBlock.of("$S", "Bar"))); - - assertThat(builder.build().toString()).isEqualTo("@java.lang.SuppressWarnings(\"Bar\")"); - } - private String toString(TypeSpec typeSpec) { return JavaFile.builder("com.squareup.tacos", typeSpec).build().toString(); } diff --git a/src/test/java/com/squareup/javapoet/ClassNameTest.java b/src/test/java/com/squareup/javapoet/ClassNameTest.java index 590ad5d..e2cc55e 100644 --- a/src/test/java/com/squareup/javapoet/ClassNameTest.java +++ b/src/test/java/com/squareup/javapoet/ClassNameTest.java @@ -193,14 +193,4 @@ public final class ClassNameTest { assertEquals("Foo$Bar$Baz", ClassName.get("", "Foo", "Bar", "Baz").reflectionName()); assertEquals("a.b.c.Foo$Bar$Baz", ClassName.get("a.b.c", "Foo", "Bar", "Baz").reflectionName()); } - - @Test - public void canonicalName() { - assertEquals("java.lang.Object", TypeName.OBJECT.canonicalName()); - assertEquals("java.lang.Thread.State", ClassName.get(Thread.State.class).canonicalName()); - assertEquals("java.util.Map.Entry", ClassName.get(Map.Entry.class).canonicalName()); - assertEquals("Foo", ClassName.get("", "Foo").canonicalName()); - assertEquals("Foo.Bar.Baz", ClassName.get("", "Foo", "Bar", "Baz").canonicalName()); - assertEquals("a.b.c.Foo.Bar.Baz", ClassName.get("a.b.c", "Foo", "Bar", "Baz").canonicalName()); - } } diff --git a/src/test/java/com/squareup/javapoet/CodeBlockTest.java b/src/test/java/com/squareup/javapoet/CodeBlockTest.java index 11b75fa..2862809 100644 --- a/src/test/java/com/squareup/javapoet/CodeBlockTest.java +++ b/src/test/java/com/squareup/javapoet/CodeBlockTest.java @@ -339,13 +339,4 @@ public final class CodeBlockTest { CodeBlock joined = codeBlocks.stream().collect(CodeBlock.joining(" || ", "start {", "} end")); assertThat(joined.toString()).isEqualTo("start {\"hello\" || world.World || need tacos} end"); } - - @Test public void clear() { - CodeBlock block = CodeBlock.builder() - .addStatement("$S", "Test string") - .clear() - .build(); - - assertThat(block.toString()).isEmpty(); - } } diff --git a/src/test/java/com/squareup/javapoet/CodeWriterTest.java b/src/test/java/com/squareup/javapoet/CodeWriterTest.java deleted file mode 100644 index 331d000..0000000 --- a/src/test/java/com/squareup/javapoet/CodeWriterTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.squareup.javapoet; - -import org.junit.Test; - -import java.io.IOException; - -import static com.google.common.truth.Truth.assertThat; - -public class CodeWriterTest { - - @Test - public void emptyLineInJavaDocDosEndings() throws IOException { - CodeBlock javadocCodeBlock = CodeBlock.of("A\r\n\r\nB\r\n"); - StringBuilder out = new StringBuilder(); - new CodeWriter(out).emitJavadoc(javadocCodeBlock); - assertThat(out.toString()).isEqualTo( - "/**\n" + - " * A\n" + - " *\n" + - " * B\n" + - " */\n"); - } -}
\ No newline at end of file diff --git a/src/test/java/com/squareup/javapoet/FieldSpecTest.java b/src/test/java/com/squareup/javapoet/FieldSpecTest.java index bc68f6f..63f7aa8 100644 --- a/src/test/java/com/squareup/javapoet/FieldSpecTest.java +++ b/src/test/java/com/squareup/javapoet/FieldSpecTest.java @@ -28,12 +28,10 @@ public class FieldSpecTest { FieldSpec b = FieldSpec.builder(int.class, "foo").build(); assertThat(a.equals(b)).isTrue(); assertThat(a.hashCode()).isEqualTo(b.hashCode()); - assertThat(a.toString()).isEqualTo(b.toString()); a = FieldSpec.builder(int.class, "FOO", Modifier.PUBLIC, Modifier.STATIC).build(); b = FieldSpec.builder(int.class, "FOO", Modifier.PUBLIC, Modifier.STATIC).build(); assertThat(a.equals(b)).isTrue(); assertThat(a.hashCode()).isEqualTo(b.hashCode()); - assertThat(a.toString()).isEqualTo(b.toString()); } @Test public void nullAnnotationsAddition() { @@ -46,21 +44,4 @@ public class FieldSpecTest { .isEqualTo("annotationSpecs == null"); } } - - @Test public void modifyAnnotations() { - FieldSpec.Builder builder = FieldSpec.builder(int.class, "foo") - .addAnnotation(Override.class) - .addAnnotation(SuppressWarnings.class); - - builder.annotations.remove(1); - assertThat(builder.build().annotations).hasSize(1); - } - - @Test public void modifyModifiers() { - FieldSpec.Builder builder = FieldSpec.builder(int.class, "foo") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC); - - builder.modifiers.remove(1); - assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC); - } -} +}
\ No newline at end of file diff --git a/src/test/java/com/squareup/javapoet/FileWritingTest.java b/src/test/java/com/squareup/javapoet/FileWritingTest.java index 58e5b62..f817ddb 100644 --- a/src/test/java/com/squareup/javapoet/FileWritingTest.java +++ b/src/test/java/com/squareup/javapoet/FileWritingTest.java @@ -216,11 +216,4 @@ public final class FileWritingTest { + "class Taco {\n" + "}\n"); } - - @Test public void writeToPathReturnsPath() throws IOException { - JavaFile javaFile = JavaFile.builder("foo", TypeSpec.classBuilder("Taco").build()).build(); - Path filePath = javaFile.writeToPath(fsRoot); - // Cast to avoid ambiguity between assertThat(Path) and assertThat(Iterable<?>) - assertThat((Iterable<?>) filePath).isEqualTo(fsRoot.resolve(fs.getPath("foo", "Taco.java"))); - } } diff --git a/src/test/java/com/squareup/javapoet/JavaFileTest.java b/src/test/java/com/squareup/javapoet/JavaFileTest.java index e75a019..e056116 100644 --- a/src/test/java/com/squareup/javapoet/JavaFileTest.java +++ b/src/test/java/com/squareup/javapoet/JavaFileTest.java @@ -15,19 +15,12 @@ */ package com.squareup.javapoet; -import java.io.File; -import com.google.testing.compile.CompilationRule; import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.Map; -import java.util.Optional; import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -36,13 +29,6 @@ import static com.google.common.truth.Truth.assertThat; @RunWith(JUnit4.class) public final class JavaFileTest { - - @Rule public final CompilationRule compilation = new CompilationRule(); - - private TypeElement getElement(Class<?> clazz) { - return compilation.getElements().getTypeElement(clazz.getCanonicalName()); - } - @Test public void importStaticReadmeExample() { ClassName hoverboard = ClassName.get("com.mattel", "Hoverboard"); ClassName namedBoards = ClassName.get("com.mattel", "Hoverboard", "Boards"); @@ -703,312 +689,4 @@ public final class JavaFileTest { + " A a;\n" + "}\n"); } - - @Test public void modifyStaticImports() throws Exception { - JavaFile.Builder builder = JavaFile.builder("com.squareup.tacos", - TypeSpec.classBuilder("Taco") - .build()) - .addStaticImport(File.class, "separator"); - - builder.staticImports.clear(); - builder.staticImports.add(File.class.getCanonicalName() + ".separatorChar"); - - String source = builder.build().toString(); - - assertThat(source).isEqualTo("" - + "package com.squareup.tacos;\n" - + "\n" - + "import static java.io.File.separatorChar;\n" - + "\n" - + "class Taco {\n" - + "}\n"); - } - - @Test public void alwaysQualifySimple() { - String source = JavaFile.builder("com.squareup.tacos", - TypeSpec.classBuilder("Taco") - .addField(Thread.class, "thread") - .alwaysQualify("Thread") - .build()) - .build() - .toString(); - assertThat(source).isEqualTo("" - + "package com.squareup.tacos;\n" - + "\n" - + "class Taco {\n" - + " java.lang.Thread thread;\n" - + "}\n"); - } - - @Test public void alwaysQualifySupersedesJavaLangImports() { - String source = JavaFile.builder("com.squareup.tacos", - TypeSpec.classBuilder("Taco") - .addField(Thread.class, "thread") - .alwaysQualify("Thread") - .build()) - .skipJavaLangImports(true) - .build() - .toString(); - assertThat(source).isEqualTo("" - + "package com.squareup.tacos;\n" - + "\n" - + "class Taco {\n" - + " java.lang.Thread thread;\n" - + "}\n"); - } - - @Test public void avoidClashesWithNestedClasses_viaClass() { - String source = JavaFile.builder("com.squareup.tacos", - TypeSpec.classBuilder("Taco") - // These two should get qualified - .addField(ClassName.get("other", "NestedTypeA"), "nestedA") - .addField(ClassName.get("other", "NestedTypeB"), "nestedB") - // This one shouldn't since it's not a nested type of Foo - .addField(ClassName.get("other", "NestedTypeC"), "nestedC") - // This one shouldn't since we only look at nested types - .addField(ClassName.get("other", "Foo"), "foo") - .avoidClashesWithNestedClasses(Foo.class) - .build()) - .build() - .toString(); - assertThat(source).isEqualTo("" - + "package com.squareup.tacos;\n" - + "\n" - + "import other.Foo;\n" - + "import other.NestedTypeC;\n" - + "\n" - + "class Taco {\n" - + " other.NestedTypeA nestedA;\n" - + "\n" - + " other.NestedTypeB nestedB;\n" - + "\n" - + " NestedTypeC nestedC;\n" - + "\n" - + " Foo foo;\n" - + "}\n"); - } - - @Test public void avoidClashesWithNestedClasses_viaTypeElement() { - String source = JavaFile.builder("com.squareup.tacos", - TypeSpec.classBuilder("Taco") - // These two should get qualified - .addField(ClassName.get("other", "NestedTypeA"), "nestedA") - .addField(ClassName.get("other", "NestedTypeB"), "nestedB") - // This one shouldn't since it's not a nested type of Foo - .addField(ClassName.get("other", "NestedTypeC"), "nestedC") - // This one shouldn't since we only look at nested types - .addField(ClassName.get("other", "Foo"), "foo") - .avoidClashesWithNestedClasses(getElement(Foo.class)) - .build()) - .build() - .toString(); - assertThat(source).isEqualTo("" - + "package com.squareup.tacos;\n" - + "\n" - + "import other.Foo;\n" - + "import other.NestedTypeC;\n" - + "\n" - + "class Taco {\n" - + " other.NestedTypeA nestedA;\n" - + "\n" - + " other.NestedTypeB nestedB;\n" - + "\n" - + " NestedTypeC nestedC;\n" - + "\n" - + " Foo foo;\n" - + "}\n"); - } - - @Test public void avoidClashesWithNestedClasses_viaSuperinterfaceType() { - String source = JavaFile.builder("com.squareup.tacos", - TypeSpec.classBuilder("Taco") - // These two should get qualified - .addField(ClassName.get("other", "NestedTypeA"), "nestedA") - .addField(ClassName.get("other", "NestedTypeB"), "nestedB") - // This one shouldn't since it's not a nested type of Foo - .addField(ClassName.get("other", "NestedTypeC"), "nestedC") - // This one shouldn't since we only look at nested types - .addField(ClassName.get("other", "Foo"), "foo") - .addType(TypeSpec.classBuilder("NestedTypeA").build()) - .addType(TypeSpec.classBuilder("NestedTypeB").build()) - .addSuperinterface(FooInterface.class) - .build()) - .build() - .toString(); - assertThat(source).isEqualTo("package com.squareup.tacos;\n" - + "\n" - + "import com.squareup.javapoet.JavaFileTest;\n" - + "import other.Foo;\n" - + "import other.NestedTypeC;\n" - + "\n" - + "class Taco implements JavaFileTest.FooInterface {\n" - + " other.NestedTypeA nestedA;\n" - + "\n" - + " other.NestedTypeB nestedB;\n" - + "\n" - + " NestedTypeC nestedC;\n" - + "\n" - + " Foo foo;\n" - + "\n" - + " class NestedTypeA {\n" - + " }\n" - + "\n" - + " class NestedTypeB {\n" - + " }\n" - + "}\n"); - } - - static class Foo { - static class NestedTypeA { - - } - static class NestedTypeB { - - } - } - - interface FooInterface { - class NestedTypeA { - - } - class NestedTypeB { - - } - } - - private TypeSpec.Builder childTypeBuilder() { - return TypeSpec.classBuilder("Child") - .addMethod(MethodSpec.methodBuilder("optionalString") - .returns(ParameterizedTypeName.get(Optional.class, String.class)) - .addStatement("return $T.empty()", Optional.class) - .build()) - .addMethod(MethodSpec.methodBuilder("pattern") - .returns(Pattern.class) - .addStatement("return null") - .build()); - } - - @Test - public void avoidClashes_parentChild_superclass_type() { - String source = JavaFile.builder("com.squareup.javapoet", - childTypeBuilder().superclass(Parent.class).build()) - .build() - .toString(); - assertThat(source).isEqualTo("package com.squareup.javapoet;\n" - + "\n" - + "import java.lang.String;\n" - + "\n" - + "class Child extends JavaFileTest.Parent {\n" - + " java.util.Optional<String> optionalString() {\n" - + " return java.util.Optional.empty();\n" - + " }\n" - + "\n" - + " java.util.regex.Pattern pattern() {\n" - + " return null;\n" - + " }\n" - + "}\n"); - } - - @Test - public void avoidClashes_parentChild_superclass_typeMirror() { - String source = JavaFile.builder("com.squareup.javapoet", - childTypeBuilder().superclass(getElement(Parent.class).asType()).build()) - .build() - .toString(); - assertThat(source).isEqualTo("package com.squareup.javapoet;\n" - + "\n" - + "import java.lang.String;\n" - + "\n" - + "class Child extends JavaFileTest.Parent {\n" - + " java.util.Optional<String> optionalString() {\n" - + " return java.util.Optional.empty();\n" - + " }\n" - + "\n" - + " java.util.regex.Pattern pattern() {\n" - + " return null;\n" - + " }\n" - + "}\n"); - } - - @Test - public void avoidClashes_parentChild_superinterface_type() { - String source = JavaFile.builder("com.squareup.javapoet", - childTypeBuilder().addSuperinterface(ParentInterface.class).build()) - .build() - .toString(); - assertThat(source).isEqualTo("package com.squareup.javapoet;\n" - + "\n" - + "import java.lang.String;\n" - + "import java.util.regex.Pattern;\n" - + "\n" - + "class Child implements JavaFileTest.ParentInterface {\n" - + " java.util.Optional<String> optionalString() {\n" - + " return java.util.Optional.empty();\n" - + " }\n" - + "\n" - + " Pattern pattern() {\n" - + " return null;\n" - + " }\n" - + "}\n"); - } - - @Test - public void avoidClashes_parentChild_superinterface_typeMirror() { - String source = JavaFile.builder("com.squareup.javapoet", - childTypeBuilder().addSuperinterface(getElement(ParentInterface.class).asType()).build()) - .build() - .toString(); - assertThat(source).isEqualTo("package com.squareup.javapoet;\n" - + "\n" - + "import java.lang.String;\n" - + "import java.util.regex.Pattern;\n" - + "\n" - + "class Child implements JavaFileTest.ParentInterface {\n" - + " java.util.Optional<String> optionalString() {\n" - + " return java.util.Optional.empty();\n" - + " }\n" - + "\n" - + " Pattern pattern() {\n" - + " return null;\n" - + " }\n" - + "}\n"); - } - - // Regression test for https://github.com/square/javapoet/issues/77 - // This covers class and inheritance - static class Parent implements ParentInterface { - static class Pattern { - - } - } - - interface ParentInterface { - class Optional { - - } - } - - // Regression test for case raised here: https://github.com/square/javapoet/issues/77#issuecomment-519972404 - @Test - public void avoidClashes_mapEntry() { - String source = JavaFile.builder("com.squareup.javapoet", - TypeSpec.classBuilder("MapType") - .addMethod(MethodSpec.methodBuilder("optionalString") - .returns(ClassName.get("com.foo", "Entry")) - .addStatement("return null") - .build()) - .addSuperinterface(Map.class) - .build()) - .build() - .toString(); - assertThat(source).isEqualTo("package com.squareup.javapoet;\n" - + "\n" - + "import java.util.Map;\n" - + "\n" - + "class MapType implements Map {\n" - + " com.foo.Entry optionalString() {\n" - + " return null;\n" - + " }\n" - + "}\n"); - } } diff --git a/src/test/java/com/squareup/javapoet/MethodSpecTest.java b/src/test/java/com/squareup/javapoet/MethodSpecTest.java index e180f20..5dfabaa 100644 --- a/src/test/java/com/squareup/javapoet/MethodSpecTest.java +++ b/src/test/java/com/squareup/javapoet/MethodSpecTest.java @@ -15,36 +15,28 @@ */ package com.squareup.javapoet; -import com.google.testing.compile.Compilation; import com.google.testing.compile.CompilationRule; import java.io.Closeable; import java.io.IOException; import java.lang.annotation.ElementType; import java.lang.annotation.Target; import java.util.Arrays; -import java.util.HashMap; +import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.TimeoutException; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; -import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; -import javax.tools.JavaFileObject; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.truth.Truth.assertThat; -import static com.google.testing.compile.CompilationSubject.assertThat; -import static com.google.testing.compile.Compiler.javac; -import static com.squareup.javapoet.TestUtil.findFirst; import static javax.lang.model.util.ElementFilter.methodsIn; import static org.junit.Assert.fail; @@ -63,6 +55,15 @@ public final class MethodSpecTest { return elements.getTypeElement(clazz.getCanonicalName()); } + private ExecutableElement findFirst(Collection<ExecutableElement> elements, String name) { + for (ExecutableElement executableElement : elements) { + if (executableElement.getSimpleName().toString().equals(name)) { + return executableElement; + } + } + throw new IllegalArgumentException(name + " not found in " + elements); + } + @Test public void nullAnnotationsAddition() { try { MethodSpec.methodBuilder("doSomething").addAnnotations(null); @@ -252,26 +253,6 @@ public final class MethodSpecTest { } } - abstract static class AbstractClassWithPrivateAnnotation { - - private @interface PrivateAnnotation{ } - - abstract void foo(@PrivateAnnotation final String bar); - } - - @Test public void overrideDoesNotCopyParameterAnnotations() { - TypeElement abstractTypeElement = getElement(AbstractClassWithPrivateAnnotation.class); - ExecutableElement fooElement = ElementFilter.methodsIn(abstractTypeElement.getEnclosedElements()).get(0); - ClassName implClassName = ClassName.get("com.squareup.javapoet", "Impl"); - TypeSpec type = TypeSpec.classBuilder(implClassName) - .superclass(abstractTypeElement.asType()) - .addMethod(MethodSpec.overriding(fooElement).build()) - .build(); - JavaFileObject jfo = JavaFile.builder(implClassName.packageName, type).build().toJavaFileObject(); - Compilation compilation = javac().compile(jfo); - assertThat(compilation).succeeded(); - } - @Test public void equalsAndHashCode() { MethodSpec a = MethodSpec.constructorBuilder().build(); MethodSpec b = MethodSpec.constructorBuilder().build(); @@ -289,59 +270,6 @@ public final class MethodSpecTest { assertThat(a.hashCode()).isEqualTo(b.hashCode()); } - @Test public void withoutParameterJavaDoc() { - MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") - .addModifiers(Modifier.PRIVATE) - .addParameter(TypeName.DOUBLE, "money") - .addJavadoc("Gets the best Taco\n") - .build(); - assertThat(methodSpec.toString()).isEqualTo("" - + "/**\n" - + " * Gets the best Taco\n" - + " */\n" - + "private void getTaco(double money) {\n" - + "}\n"); - } - - @Test public void withParameterJavaDoc() { - MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") - .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") - .addJavadoc("the amount required to buy the taco.\n") - .build()) - .addParameter(ParameterSpec.builder(TypeName.INT, "count") - .addJavadoc("the number of Tacos to buy.\n") - .build()) - .addJavadoc("Gets the best Taco money can buy.\n") - .build(); - assertThat(methodSpec.toString()).isEqualTo("" - + "/**\n" - + " * Gets the best Taco money can buy.\n" - + " *\n" - + " * @param money the amount required to buy the taco.\n" - + " * @param count the number of Tacos to buy.\n" - + " */\n" - + "void getTaco(double money, int count) {\n" - + "}\n"); - } - - @Test public void withParameterJavaDocAndWithoutMethodJavadoc() { - MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco") - .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money") - .addJavadoc("the amount required to buy the taco.\n") - .build()) - .addParameter(ParameterSpec.builder(TypeName.INT, "count") - .addJavadoc("the number of Tacos to buy.\n") - .build()) - .build(); - assertThat(methodSpec.toString()).isEqualTo("" - + "/**\n" - + " * @param money the amount required to buy the taco.\n" - + " * @param count the number of Tacos to buy.\n" - + " */\n" - + "void getTaco(double money, int count) {\n" - + "}\n"); - } - @Test public void duplicateExceptionsIgnored() { ClassName ioException = ClassName.get(IOException.class); ClassName timeoutException = ClassName.get(TimeoutException.class); @@ -374,115 +302,4 @@ public final class MethodSpecTest { assertThat(e.getMessage()).isEqualTo("modifiers == null"); } } - - @Test public void modifyMethodName() { - MethodSpec methodSpec = MethodSpec.methodBuilder("initialMethod") - .build() - .toBuilder() - .setName("revisedMethod") - .build(); - - assertThat(methodSpec.toString()).isEqualTo("" + "void revisedMethod() {\n" + "}\n"); - } - - @Test public void modifyAnnotations() { - MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") - .addAnnotation(Override.class) - .addAnnotation(SuppressWarnings.class); - - builder.annotations.remove(1); - assertThat(builder.build().annotations).hasSize(1); - } - - @Test public void modifyModifiers() { - MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC); - - builder.modifiers.remove(1); - assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC); - } - - @Test public void modifyParameters() { - MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") - .addParameter(int.class, "source"); - - builder.parameters.remove(0); - assertThat(builder.build().parameters).isEmpty(); - } - - @Test public void modifyTypeVariables() { - TypeVariableName t = TypeVariableName.get("T"); - MethodSpec.Builder builder = MethodSpec.methodBuilder("foo") - .addTypeVariable(t) - .addTypeVariable(TypeVariableName.get("V")); - - builder.typeVariables.remove(1); - assertThat(builder.build().typeVariables).containsExactly(t); - } - - @Test public void ensureTrailingNewline() { - MethodSpec methodSpec = MethodSpec.methodBuilder("method") - .addCode("codeWithNoNewline();") - .build(); - - assertThat(methodSpec.toString()).isEqualTo("" - + "void method() {\n" - + " codeWithNoNewline();\n" - + "}\n"); - } - - /** Ensures that we don't add a duplicate newline if one is already present. */ - @Test public void ensureTrailingNewlineWithExistingNewline() { - MethodSpec methodSpec = MethodSpec.methodBuilder("method") - .addCode("codeWithNoNewline();\n") // Have a newline already, so ensure we're not adding one - .build(); - - assertThat(methodSpec.toString()).isEqualTo("" - + "void method() {\n" - + " codeWithNoNewline();\n" - + "}\n"); - } - - @Test public void controlFlowWithNamedCodeBlocks() { - Map<String, Object> m = new HashMap<>(); - m.put("field", "valueField"); - m.put("threshold", "5"); - - MethodSpec methodSpec = MethodSpec.methodBuilder("method") - .beginControlFlow(named("if ($field:N > $threshold:L)", m)) - .nextControlFlow(named("else if ($field:N == $threshold:L)", m)) - .endControlFlow() - .build(); - - assertThat(methodSpec.toString()).isEqualTo("" - + "void method() {\n" - + " if (valueField > 5) {\n" - + " } else if (valueField == 5) {\n" - + " }\n" - + "}\n"); - } - - @Test public void doWhileWithNamedCodeBlocks() { - Map<String, Object> m = new HashMap<>(); - m.put("field", "valueField"); - m.put("threshold", "5"); - - MethodSpec methodSpec = MethodSpec.methodBuilder("method") - .beginControlFlow("do") - .addStatement(named("$field:N--", m)) - .endControlFlow(named("while ($field:N > $threshold:L)", m)) - .build(); - - assertThat(methodSpec.toString()).isEqualTo("" - + "void method() {\n" + - " do {\n" + - " valueField--;\n" + - " } while (valueField > 5);\n" + - "}\n"); - } - - private static CodeBlock named(String format, Map<String, ?> args){ - return CodeBlock.builder().addNamed(format, args).build(); - } - } diff --git a/src/test/java/com/squareup/javapoet/NameAllocatorTest.java b/src/test/java/com/squareup/javapoet/NameAllocatorTest.java index 71402c6..1840107 100644 --- a/src/test/java/com/squareup/javapoet/NameAllocatorTest.java +++ b/src/test/java/com/squareup/javapoet/NameAllocatorTest.java @@ -18,11 +18,9 @@ package com.squareup.javapoet; import org.junit.Test; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public final class NameAllocatorTest { - @Test public void usage() throws Exception { NameAllocator nameAllocator = new NameAllocator(); assertThat(nameAllocator.newName("foo", 1)).isEqualTo("foo"); @@ -61,7 +59,6 @@ public final class NameAllocatorTest { @Test public void characterMappingInvalidStartButValidPart() throws Exception { NameAllocator nameAllocator = new NameAllocator(); assertThat(nameAllocator.newName("1ab", 1)).isEqualTo("_1ab"); - assertThat(nameAllocator.newName("a-1", 2)).isEqualTo("a_1"); } @Test public void characterMappingInvalidStartIsInvalidPart() throws Exception { diff --git a/src/test/java/com/squareup/javapoet/ParameterSpecTest.java b/src/test/java/com/squareup/javapoet/ParameterSpecTest.java index 561eebf..2f81866 100644 --- a/src/test/java/com/squareup/javapoet/ParameterSpecTest.java +++ b/src/test/java/com/squareup/javapoet/ParameterSpecTest.java @@ -15,68 +15,23 @@ */ package com.squareup.javapoet; -import com.google.testing.compile.CompilationRule; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nullable; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.util.Elements; -import org.junit.Before; -import org.junit.Rule; -import javax.lang.model.element.Modifier; import org.junit.Test; import static com.google.common.truth.Truth.assertThat; -import static com.squareup.javapoet.TestUtil.findFirst; -import static javax.lang.model.util.ElementFilter.fieldsIn; -import static javax.lang.model.util.ElementFilter.methodsIn; import static org.junit.Assert.fail; -public class ParameterSpecTest { - @Rule public final CompilationRule compilation = new CompilationRule(); - - private Elements elements; - - @Before public void setUp() { - elements = compilation.getElements(); - } - - private TypeElement getElement(Class<?> clazz) { - return elements.getTypeElement(clazz.getCanonicalName()); - } +import javax.lang.model.element.Modifier; +public class ParameterSpecTest { @Test public void equalsAndHashCode() { ParameterSpec a = ParameterSpec.builder(int.class, "foo").build(); ParameterSpec b = ParameterSpec.builder(int.class, "foo").build(); assertThat(a.equals(b)).isTrue(); assertThat(a.hashCode()).isEqualTo(b.hashCode()); - assertThat(a.toString()).isEqualTo(b.toString()); a = ParameterSpec.builder(int.class, "i").addModifiers(Modifier.STATIC).build(); b = ParameterSpec.builder(int.class, "i").addModifiers(Modifier.STATIC).build(); assertThat(a.equals(b)).isTrue(); assertThat(a.hashCode()).isEqualTo(b.hashCode()); - assertThat(a.toString()).isEqualTo(b.toString()); - } - - @Test public void receiverParameterInstanceMethod() { - ParameterSpec.Builder builder = ParameterSpec.builder(int.class, "this"); - assertThat(builder.build().name).isEqualTo("this"); - } - - @Test public void receiverParameterNestedClass() { - ParameterSpec.Builder builder = ParameterSpec.builder(int.class, "Foo.this"); - assertThat(builder.build().name).isEqualTo("Foo.this"); - } - - @Test public void keywordName() { - try { - ParameterSpec.builder(int.class, "super"); - fail(); - } catch (Exception e) { - assertThat(e.getMessage()).isEqualTo("not a valid name: super"); - } } @Test public void nullAnnotationsAddition() { @@ -88,67 +43,4 @@ public class ParameterSpecTest { .isEqualTo("annotationSpecs == null"); } } - - final class VariableElementFieldClass { - String name; - } - - @Test public void fieldVariableElement() { - TypeElement classElement = getElement(VariableElementFieldClass.class); - List<VariableElement> methods = fieldsIn(elements.getAllMembers(classElement)); - VariableElement element = findFirst(methods, "name"); - - try { - ParameterSpec.get(element); - fail(); - } catch (IllegalArgumentException exception) { - assertThat(exception).hasMessageThat().isEqualTo("element is not a parameter"); - } - } - - final class VariableElementParameterClass { - public void foo(@Nullable final String bar) { - } - } - - @Test public void parameterVariableElement() { - TypeElement classElement = getElement(VariableElementParameterClass.class); - List<ExecutableElement> methods = methodsIn(elements.getAllMembers(classElement)); - ExecutableElement element = findFirst(methods, "foo"); - VariableElement parameterElement = element.getParameters().get(0); - - assertThat(ParameterSpec.get(parameterElement).toString()) - .isEqualTo("java.lang.String arg0"); - } - - @Test public void addNonFinalModifier() { - List<Modifier> modifiers = new ArrayList<>(); - modifiers.add(Modifier.FINAL); - modifiers.add(Modifier.PUBLIC); - - try { - ParameterSpec.builder(int.class, "foo") - .addModifiers(modifiers); - fail(); - } catch (Exception e) { - assertThat(e.getMessage()).isEqualTo("unexpected parameter modifier: public"); - } - } - - @Test public void modifyAnnotations() { - ParameterSpec.Builder builder = ParameterSpec.builder(int.class, "foo") - .addAnnotation(Override.class) - .addAnnotation(SuppressWarnings.class); - - builder.annotations.remove(1); - assertThat(builder.build().annotations).hasSize(1); - } - - @Test public void modifyModifiers() { - ParameterSpec.Builder builder = ParameterSpec.builder(int.class, "foo") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC); - - builder.modifiers.remove(1); - assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC); - } -} +}
\ No newline at end of file diff --git a/src/test/java/com/squareup/javapoet/TestUtil.java b/src/test/java/com/squareup/javapoet/TestUtil.java deleted file mode 100644 index f773d50..0000000 --- a/src/test/java/com/squareup/javapoet/TestUtil.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.squareup.javapoet; - -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.VariableElement; -import java.util.Collection; - -final class TestUtil { - static <E extends Element> E findFirst(Collection<E> elements, String name) { - for (E element : elements) { - if (element.getSimpleName().toString().equals(name)) { - return element; - } - } - throw new IllegalArgumentException(name + " not found in " + elements); - } -} diff --git a/src/test/java/com/squareup/javapoet/TypeSpecTest.java b/src/test/java/com/squareup/javapoet/TypeSpecTest.java index 0f67c5c..9cd22c2 100644 --- a/src/test/java/com/squareup/javapoet/TypeSpecTest.java +++ b/src/test/java/com/squareup/javapoet/TypeSpecTest.java @@ -17,7 +17,6 @@ package com.squareup.javapoet; import com.google.common.collect.ImmutableMap; import com.google.testing.compile.CompilationRule; -import java.io.File; import java.io.IOException; import java.io.Serializable; import java.math.BigDecimal; @@ -986,74 +985,6 @@ public final class TypeSpecTest { + "}\n"); } - @Test public void simpleNameConflictsWithTypeVariable() { - ClassName inPackage = ClassName.get("com.squareup.tacos", "InPackage"); - ClassName otherType = ClassName.get("com.other", "OtherType"); - ClassName methodInPackage = ClassName.get("com.squareup.tacos", "MethodInPackage"); - ClassName methodOtherType = ClassName.get("com.other", "MethodOtherType"); - TypeSpec gen = TypeSpec.classBuilder("Gen") - .addTypeVariable(TypeVariableName.get("InPackage")) - .addTypeVariable(TypeVariableName.get("OtherType")) - .addField(FieldSpec.builder(inPackage, "inPackage").build()) - .addField(FieldSpec.builder(otherType, "otherType").build()) - .addMethod(MethodSpec.methodBuilder("withTypeVariables") - .addTypeVariable(TypeVariableName.get("MethodInPackage")) - .addTypeVariable(TypeVariableName.get("MethodOtherType")) - .addStatement("$T inPackage = null", methodInPackage) - .addStatement("$T otherType = null", methodOtherType) - .build()) - .addMethod(MethodSpec.methodBuilder("withoutTypeVariables") - .addStatement("$T inPackage = null", methodInPackage) - .addStatement("$T otherType = null", methodOtherType) - .build()) - .addMethod(MethodSpec.methodBuilder("againWithTypeVariables") - .addTypeVariable(TypeVariableName.get("MethodInPackage")) - .addTypeVariable(TypeVariableName.get("MethodOtherType")) - .addStatement("$T inPackage = null", methodInPackage) - .addStatement("$T otherType = null", methodOtherType) - .build()) - // https://github.com/square/javapoet/pull/657#discussion_r205514292 - .addMethod(MethodSpec.methodBuilder("masksEnclosingTypeVariable") - .addTypeVariable(TypeVariableName.get("InPackage")) - .build()) - .addMethod(MethodSpec.methodBuilder("hasSimpleNameThatWasPreviouslyMasked") - .addStatement("$T inPackage = null", inPackage) - .build()) - .build(); - assertThat(toString(gen)).isEqualTo("" - + "package com.squareup.tacos;\n" - + "\n" - + "import com.other.MethodOtherType;\n" - + "\n" - + "class Gen<InPackage, OtherType> {\n" - + " com.squareup.tacos.InPackage inPackage;\n" - + "\n" - + " com.other.OtherType otherType;\n" - + "\n" - + " <MethodInPackage, MethodOtherType> void withTypeVariables() {\n" - + " com.squareup.tacos.MethodInPackage inPackage = null;\n" - + " com.other.MethodOtherType otherType = null;\n" - + " }\n" - + "\n" - + " void withoutTypeVariables() {\n" - + " MethodInPackage inPackage = null;\n" - + " MethodOtherType otherType = null;\n" - + " }\n" - + "\n" - + " <MethodInPackage, MethodOtherType> void againWithTypeVariables() {\n" - + " com.squareup.tacos.MethodInPackage inPackage = null;\n" - + " com.other.MethodOtherType otherType = null;\n" - + " }\n" - + "\n" - + " <InPackage> void masksEnclosingTypeVariable() {\n" - + " }\n" - + "\n" - + " void hasSimpleNameThatWasPreviouslyMasked() {\n" - + " com.squareup.tacos.InPackage inPackage = null;\n" - + " }\n" - + "}\n"); - } - @Test public void originatingElementsIncludesThoseOfNestedTypes() { Element outerElement = Mockito.mock(Element.class); Element innerElement = Mockito.mock(Element.class); @@ -1849,8 +1780,7 @@ public final class TypeSpecTest { + " }\n" + "\n" + " /**\n" - + " * chosen by fair dice roll ;)\n" - + " */\n" + + " * chosen by fair dice roll ;) */\n" + " public int getRandomQuantity() {\n" + " return 4;\n" + " }\n" @@ -1909,7 +1839,7 @@ public final class TypeSpecTest { @Test public void nullModifiersAddition() { try { - TypeSpec.classBuilder("Taco").addModifiers((Modifier) null).build(); + TypeSpec.classBuilder("Taco").addModifiers((Modifier) null); fail(); } catch(IllegalArgumentException expected) { assertThat(expected.getMessage()) @@ -2266,7 +2196,6 @@ public final class TypeSpecTest { @Test public void initializersToBuilder() { // Tests if toBuilder() contains correct static and instance initializers - Element originatingElement = getElement(TypeSpecTest.class); TypeSpec taco = TypeSpec.classBuilder("Taco") .addField(String.class, "foo", Modifier.PRIVATE) .addField(String.class, "FOO", Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) @@ -2283,16 +2212,10 @@ public final class TypeSpecTest { .addInitializerBlock(CodeBlock.builder() .addStatement("foo = $S", "FOO") .build()) - .addOriginatingElement(originatingElement) - .alwaysQualify("com.example.AlwaysQualified") .build(); TypeSpec recreatedTaco = taco.toBuilder().build(); assertThat(toString(taco)).isEqualTo(toString(recreatedTaco)); - assertThat(taco.originatingElements) - .containsExactlyElementsIn(recreatedTaco.originatingElements); - assertThat(taco.alwaysQualifiedNames) - .containsExactlyElementsIn(recreatedTaco.alwaysQualifiedNames); TypeSpec initializersAdded = taco.toBuilder() .addInitializerBlock(CodeBlock.builder() @@ -2433,122 +2356,4 @@ public final class TypeSpecTest { assertThat(TypeSpec.enumBuilder(className).addEnumConstant("A").build().name).isEqualTo("Example"); assertThat(TypeSpec.annotationBuilder(className).build().name).isEqualTo("Example"); } - - @Test - public void modifyAnnotations() { - TypeSpec.Builder builder = - TypeSpec.classBuilder("Taco") - .addAnnotation(Override.class) - .addAnnotation(SuppressWarnings.class); - - builder.annotations.remove(1); - assertThat(builder.build().annotations).hasSize(1); - } - - @Test - public void modifyModifiers() { - TypeSpec.Builder builder = - TypeSpec.classBuilder("Taco").addModifiers(Modifier.PUBLIC, Modifier.FINAL); - - builder.modifiers.remove(1); - assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC); - } - - @Test - public void modifyFields() { - TypeSpec.Builder builder = TypeSpec.classBuilder("Taco") - .addField(int.class, "source"); - - builder.fieldSpecs.remove(0); - assertThat(builder.build().fieldSpecs).isEmpty(); - } - - @Test - public void modifyTypeVariables() { - TypeVariableName t = TypeVariableName.get("T"); - TypeSpec.Builder builder = - TypeSpec.classBuilder("Taco") - .addTypeVariable(t) - .addTypeVariable(TypeVariableName.get("V")); - - builder.typeVariables.remove(1); - assertThat(builder.build().typeVariables).containsExactly(t); - } - - @Test - public void modifySuperinterfaces() { - TypeSpec.Builder builder = TypeSpec.classBuilder("Taco") - .addSuperinterface(File.class); - - builder.superinterfaces.clear(); - assertThat(builder.build().superinterfaces).isEmpty(); - } - - @Test - public void modifyMethods() { - TypeSpec.Builder builder = TypeSpec.classBuilder("Taco") - .addMethod(MethodSpec.methodBuilder("bell").build()); - - builder.methodSpecs.clear(); - assertThat(builder.build().methodSpecs).isEmpty(); - } - - @Test - public void modifyTypes() { - TypeSpec.Builder builder = TypeSpec.classBuilder("Taco") - .addType(TypeSpec.classBuilder("Bell").build()); - - builder.typeSpecs.clear(); - assertThat(builder.build().typeSpecs).isEmpty(); - } - - @Test - public void modifyEnumConstants() { - TypeSpec constantType = TypeSpec.anonymousClassBuilder("").build(); - TypeSpec.Builder builder = TypeSpec.enumBuilder("Taco") - .addEnumConstant("BELL", constantType) - .addEnumConstant("WUT", TypeSpec.anonymousClassBuilder("").build()); - - builder.enumConstants.remove("WUT"); - assertThat(builder.build().enumConstants).containsExactly("BELL", constantType); - } - - @Test - public void modifyOriginatingElements() { - TypeSpec.Builder builder = TypeSpec.classBuilder("Taco") - .addOriginatingElement(Mockito.mock(Element.class)); - - builder.originatingElements.clear(); - assertThat(builder.build().originatingElements).isEmpty(); - } - - @Test public void javadocWithTrailingLineDoesNotAddAnother() { - TypeSpec spec = TypeSpec.classBuilder("Taco") - .addJavadoc("Some doc with a newline\n") - .build(); - - assertThat(toString(spec)).isEqualTo("" - + "package com.squareup.tacos;\n" - + "\n" - + "/**\n" - + " * Some doc with a newline\n" - + " */\n" - + "class Taco {\n" - + "}\n"); - } - - @Test public void javadocEnsuresTrailingLine() { - TypeSpec spec = TypeSpec.classBuilder("Taco") - .addJavadoc("Some doc with a newline") - .build(); - - assertThat(toString(spec)).isEqualTo("" - + "package com.squareup.tacos;\n" - + "\n" - + "/**\n" - + " * Some doc with a newline\n" - + " */\n" - + "class Taco {\n" - + "}\n"); - } } |