Full Code of square/javapoet for AI

master b9017a9503b7 cached
50 files
495.9 KB
121.2k tokens
920 symbols
1 requests
Download .txt
Showing preview only (518K chars total). Download the full file or copy to clipboard to get everything.
Repository: square/javapoet
Branch: master
Commit: b9017a9503b7
Files: 50
Total size: 495.9 KB

Directory structure:
gitextract_4emi2l0t/

├── .github/
│   ├── CONTRIBUTING.md
│   └── workflows/
│       ├── build.yml
│       └── settings.xml
├── .gitignore
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── RELEASING.md
├── checkstyle.xml
├── pom.xml
├── renovate.json
└── src/
    ├── main/
    │   └── java/
    │       └── com/
    │           └── squareup/
    │               └── javapoet/
    │                   ├── AnnotationSpec.java
    │                   ├── ArrayTypeName.java
    │                   ├── ClassName.java
    │                   ├── CodeBlock.java
    │                   ├── CodeWriter.java
    │                   ├── FieldSpec.java
    │                   ├── JavaFile.java
    │                   ├── LineWrapper.java
    │                   ├── MethodSpec.java
    │                   ├── NameAllocator.java
    │                   ├── ParameterSpec.java
    │                   ├── ParameterizedTypeName.java
    │                   ├── TypeName.java
    │                   ├── TypeSpec.java
    │                   ├── TypeVariableName.java
    │                   ├── Util.java
    │                   └── WildcardTypeName.java
    └── test/
        └── java/
            ├── ClassNameNoPackageTest.java
            └── com/
                └── squareup/
                    └── javapoet/
                        ├── AbstractTypesTest.java
                        ├── AnnotatedTypeNameTest.java
                        ├── AnnotationSpecTest.java
                        ├── ClassNameTest.java
                        ├── CodeBlockTest.java
                        ├── CodeWriterTest.java
                        ├── FieldSpecTest.java
                        ├── FileReadingTest.java
                        ├── FileWritingTest.java
                        ├── JavaFileTest.java
                        ├── LineWrapperTest.java
                        ├── MethodSpecTest.java
                        ├── NameAllocatorTest.java
                        ├── ParameterSpecTest.java
                        ├── TestFiler.java
                        ├── TestUtil.java
                        ├── TypeNameTest.java
                        ├── TypeSpecTest.java
                        ├── TypesEclipseTest.java
                        ├── TypesTest.java
                        └── UtilTest.java

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/CONTRIBUTING.md
================================================
Contributing
============

If you would like to contribute code you can do so through GitHub by forking
the repository and sending a pull request.

When submitting code, please make every effort to follow existing conventions
and style in order to keep the code as readable as possible. Please also make
sure your code compiles by running `mvn clean verify`. Checkstyle failures
during compilation indicate errors in your style and can be viewed in the
`checkstyle-result.xml` file.

Before your code can be accepted into the project you must also sign the
[Individual Contributor License Agreement (CLA)][1].


 [1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1


================================================
FILE: .github/workflows/build.yml
================================================
name: build

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 8

      - run: mvn --no-transfer-progress verify source:jar javadoc:jar

      - run: mvn --no-transfer-progress deploy --settings=".github/workflows/settings.xml" -Dmaven.test.skip=true
        if: ${{ github.ref == 'refs/heads/master' && github.repository == 'square/javapoet' }}


================================================
FILE: .github/workflows/settings.xml
================================================
<settings>
  <servers>
    <server>
      <id>sonatype-nexus-snapshots</id>
      <username>${env.SONATYPE_DEPLOY_USERNAME}</username>
      <password>${env.SONATYPE_DEPLOY_PASSWORD}</password>
    </server>
  </servers>
</settings>


================================================
FILE: .gitignore
================================================
.classpath
.project
.settings
.checkstyle
eclipsebin

bin
gen
build
out
lib

target
pom.xml.*
release.properties

.idea
*.iml
classes

obj

.DS_Store


================================================
FILE: CHANGELOG.md
================================================
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)*
-----------------------------

 * Fix: JavaPoet 1.11 had a regression where `TypeName.get()` would throw on error types, masking
   other errors in an annotation processing round. This is fixed with a test to prevent future
   regressions!


JavaPoet 1.11.0 *(2018-04-29)*
-----------------------------

 * New: Support `TYPE_USE` annotations on each enclosing `ClassName`.
 * New: Work around a compiler bug in `TypeName.get(TypeElement)`. There was a problem getting an
   element's kind when building from source ABIs.


JavaPoet 1.10.0 *(2018-01-27)*
-----------------------------

 * **JavaPoet now requires Java 8 or newer.**
 * New: `$Z` as an optional newline (zero-width space) if a line may exceed 100 chars.
 * New: `CodeBlock.join()` and `CodeBlock.joining()` let you join codeblocks by delimiters.
 * New: Add `CodeBlock.Builder.isEmpty()`.
 * New: `addStatement(CodeBlock)` overloads for `CodeBlock` and `MethodSpec`.
 * Fix: Include annotations when emitting type variables.
 * Fix: Use the right imports for annotated type parameters.
 * Fix: Don't incorrectly escape classnames that start with `$`.


JavaPoet 1.9.0 *(2017-05-13)*
-----------------------------

 * Fix: Don't emit incorrect code when the declared type's signature references another type with
   the same simple name.
 * Fix: Support anonymous inner classes in `ClassName.get()`.
 * New: `MethodSpec.Builder.addNamedCode()` and `TypeSpec.anonymousClassBuilder(CodeBlock)`.


JavaPoet 1.8.0 *(2016-11-09)*
-----------------------------

 * New: Basic support for line wrapping. Use `$W` to insert a Wrappable Whitespace character. It'll
   emit either a single space or a newline with appropriate indentation.
 * New: Named arguments in `CodeBlock`. These are intended to make larger code snippets easier to
   read:

   ```
    Map<String, Object> map = new LinkedHashMap<>();
    map.put("count", 3);
    map.put("greeting", "Hello, ");
    map.put("system", System.class);

    String template = ""
        + "for (int i = 0; i < $count:L; i++) {\n"
        + "  $system:T.out.println($greeting:S + list.get(i));\n"
        + "}\n";

    CodeBlock.Builder builder = CodeBlock.builder();
    builder.addNamed(template, map);
   ```

 * New: `addJavadoc(CodeBlock)` overloads for TypeSpec, MethodSpec, and FieldSpec.
 * New: `MethodSpec.addComment()` makes it easy to add a `// single-line comment.`
 * New: `ClassName.getReflectionName()` returns a string like `java.util.Map$Entry`.
 * Fix: Always write UTF-8. Previously JavaPoet would use the system default charset which was
   potentially inconsistent across environments.
 * Fix: Permit (constant) fields to be defined in annotation types.


JavaPoet 1.7.0 *(2016-04-26)*
-----------------------------

 * New: Support parameterized types that enclose other types, like `Outer<String>.Inner`.
 * New: `TypeName.isBoxedPrimitive()`.


JavaPoet 1.6.1 *(2016-03-21)*
-----------------------------

 * Fix: Double quotes and backslashes in string literals were not properly quoted in 1.6.0. This is
   now fixed.


JavaPoet 1.6.0 *(2016-03-19)*
-----------------------------

 * New: Revive `CodeBlock.of()`, a handy factory method for building code blocks.
 * New: Add `TypeSpec` factory methods that take a `ClassName`.
 * New: `TypeName.annotated()` adds an annotation to a type.
 * New: `TypeVariableName.withBounds()` adds bounds to a type variable.
 * New: `TypeSpec.Builder.addInitializerBlock()` adds an instance initializer.
 * Fix: Make `TypeSpec.Kind` enum public. This can be used to check if a `TypeSpec` is a class,
   interface, enum, or annotation.
 * Fix: Don’t break import resolution on annotated types.
 * Fix: Forbid unexpected modifiers like `private` on annotation members.
 * Fix: Deduplicate exceptions in `MethodSpec.Builder`.
 * Fix: Treat `ErrorType` like a regular `DeclaredType` in `TypeName.get()`. This should make it
   easier to write annotation processors.


JavaPoet 1.5.1 *(2016-01-10)*
-----------------------------

 * Fix: Annotated `TypeName` instances are only equal if their annotations are equal.

JavaPoet 1.5.0 *(2016-01-10)*
-----------------------------

 * New: `import static`! See `JavaFile.Builder.addStaticImport()` variants.
 * New: Overload `NameAllocator.newName(String)` for creating a one-off name without a tag.
 * Fix: AnnotationSpec escapes character literals properly.
 * Fix: Don't stack overflow when `TypeVariableName` is part of `ParameterizedTypeName`.
 * Fix: Reporting not used indexed arguments in like `add("$1S", "a", "b")`.
 * Fix: Prevent import of types located in the default package, i.e. have no package name.


JavaPoet 1.4.0 *(2015-11-13)*
-----------------------------

 * New: `AnnotationSpec.get(Annotation)`.
 * New: Type annotations! `TypeName.annotated()` can attach annotations like `@Nullable` directly to
   types. This works for both top-level types and type parameters as in `List<@Nullable String>`.
 * New: `equals()` and `hashCode()` on `AnnotationSpec`, `CodeBlock`, `FieldSpec`, `JavaFile`,
   `MethodSpec`, `ParameterSpec`, `TypeName`, and `TypeSpec`.
 * New: `NameAllocator.clone()` to refine a NameAllocator for use in an inner scope code block.
 * Fix: Don't stack overflow when `TypeVariableName` gets a self-referential type.
 * Fix: Better handling of name collisions on imports. Previously JavaPoet did the wrong thing when
   a referenced type and a nested types had the same name.


JavaPoet 1.3.0 *(2015-09-20)*
-----------------------------

 * New: `NameAllocator` API makes it easy to declare non-conflicting names.
 * New: Support annotations on enum values.
 * Fix: Avoid infinite recursion in `TypeName.get(TypeMirror)`.
 * Fix: Use qualified name for conflicting simple names in the same file.
 * Fix: Better messages for parameter indexing errors.


JavaPoet 1.2.0 *(2015-07-04)*
-----------------------------

 * New: Arguments may have positional indexes like `$1T` and `$2N`. Indexes can be used to refer to
   the same argument multiple times in a single format string.
 * New: Permit Javadoc on enum constants.
 * New: Class initializer blocks with `addStaticBlock()`.
 * Fix: `MethodSpec.overriding()` retains annotations.


JavaPoet 1.1.0 *(2015-05-25)*
-----------------------------

 * New: Eager validation of argument types like `$T` and `$N`.
 * New: `MethodSpec.varargs(boolean)` to generate varags methods.
 * New: `AnnotationSpec.get()` and `MethodSpec.overriding()` to create annotations and methods from
   the `javax.lang.model` API.
 * New: `JavaFile.toJavaFileObject()`.
 * New: Java 8 `DEFAULT` modifier.
 * New: `toBuilder()` methods to build upon objects already constructed.
 * New: Generate `@interface` annotation types.
 * New: `TypeName.box()` and `TypeName.unbox()` convenience APIs.
 * Fix: `nextControlFlow()` accepts arguments.
 * Fix: Reject duplicate calls to set the superclass.
 * Fix: `WildcardTypeName.get(WildcardType)` no longer throws a `NullPointerException`.
 * Fix: Don't allow double field initialization.

JavaPoet 1.0.0 *(2015-01-28)*
-----------------------------

 * This update is a complete rewrite. The project name is now `javapoet`. We renamed the it so you
   can simultaneously use the old JavaWriter API and our new builder-based APIs in one project.
 * Immutable value objects and builders. Instead of streaming the `.java` file from top to bottom,
   you now define members in whatever way is convenient.
 * We now use our own models for type names.
 * Imports are now added automatically.


JavaWriter 2.5.1 *(2014-12-03)*
-------------------------------

 * New: `StringLiteral` type which encapsulates the behavior of `stringLiteral`.
 * Fix: Use canonical name when emitting a class import.
 * Fix: Apply type compression to varargs and array types.
 * Fix: Restore binary compatibility with pre-2.5 versions.


JavaWriter 2.5.0 *(2014-04-18)*
-------------------------------

 * New: Methods in interfaces will always have no body declaration.
 * New: Control flow begin declaration now supports String format arguments.
 * Fix: Truncate any generic type when emitting constructors.
 * Fix: Do not emit trailing whitespace after '=' at end-of-line.


JavaWriter 2.4.0 *(2014-01-10)*
-------------------------------

 * New: Properly indent hanging lines in field initializers.
 * New: `emitEnumValue` variant which exposes a boolean of whether the current value is the last.


JavaWriter 2.3.1 *(2013-12-16)*
-------------------------------

 * Fix: Properly handle subpackages of `java.lang` in `compressType`.


JavaWriter 2.3.0 *(2013-11-24)*
-------------------------------

 * New: Configurable indent level via `setIndent`.
 * New: `beginConstructor` method is a semantically clearer alternative for constructors.
 * New: `emitEnumValues` method emits a list of values followed by semicolon.
 * `emitImports` now supports `Class` arguments directly.
 * Previously-deprecated, `int`-based modifier methods have been removed.


JavaWriter 2.2.1 *(2013-10-23)*
-------------------------------

 * Fix: Do not emit trailing whitespace for empty Javadoc lines.


JavaWriter 2.2.0 *(2013-09-25)*
-------------------------------

 * `setCompressingTypes` controls whether types are emitted as fully-qualified or not.


JavaWriter 2.1.2 *(2013-08-23)*
-------------------------------

 * Attempt to keep annotations on a single line.


JavaWriter 2.1.1 *(2013-07-23)*
-------------------------------

 * Fix: `stringLiteral` now correctly handles escapes and control characters.


JavaWriter 2.1.0 *(2013-07-15)*
-------------------------------

 * New: All methods now take a `Set` of `Modifier`s rather than an `int`. The `int` methods are
   now deprecated for removal in JavaPoet 1.0.
 * Annotations with a single "value" attribute will now omit the key.


JavaWriter 2.0.1 *(2013-06-17)*
-------------------------------

 * Correct casing of `emitSingleLineComment`.


JavaWriter 2.0.0 *(2013-06-06)*
-------------------------------

 * Package name is now `com.squareup.javawriter`.
 * Support declaring `throws` clause on methods.


JavaWriter 1.0.5 *(2013-05-08)*
-------------------------------

 * Fix: Fully qualify types whose simple name matches an import.


JavaWriter 1.0.4 *(2013-03-15)*
-------------------------------

 * Fix: Static import emit now properly supports method imports.


JavaWriter 1.0.3 *(2013-02-21)*
-------------------------------

 * Add support for emitting static imports.


JavaWriter 1.0.2 *(2013-02-11)*
-------------------------------

 * Add `type` API for helping build generic types.
 * Minor performance improvements.


JavaWriter 1.0.1 *(2013-02-03)*
-------------------------------

 * Expose `compressType` API.


JavaWriter 1.0.0 *(2013-02-01)*
-------------------------------

Initial release.


================================================
FILE: LICENSE.txt
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   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.


================================================
FILE: README.md
================================================
JavaPoet
========

`JavaPoet` is a Java API for generating `.java` source files.

Source file generation can be useful when doing things such as annotation processing or interacting
with metadata files (e.g., database schemas, protocol formats). By generating code, you eliminate
the need to write boilerplate while also keeping a single source of truth for the metadata.


Deprecated
----------

As of 2020-10-10, Square's JavaPoet project is deprecated. We're proud of our work but we haven't
kept up on maintaining it.

If you'd like an alternative that supports the latest Java language features, one option is
[Palantir's JavaPoet](https://github.com/palantir/javapoet).

To switch to that project, you'll need new Maven coordinates:

```diff
- javapoet = { module = "com.squareup:javapoet", version = "1.13.0" }
+ javapoet = { module = "com.palantir.javapoet:javapoet", version = "0.5.0" }
```

And new imports:

```
sed -i "" \
  's/com.squareup.javapoet.\([A-Za-z]*\)/com.palantir.javapoet.\1/g' \
  `find . -name "*.kt" -or -name "*.java"`
```

And you might need to track some API changes where fields became functions:

```diff
- javaFile.packageName
+ javaFile.packageName()
```

### Example

Here's a (boring) `HelloWorld` class:

```java
package com.example.helloworld;

public final class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, JavaPoet!");
  }
}
```

And this is the (exciting) code to generate it with JavaPoet:

```java
MethodSpec main = MethodSpec.methodBuilder("main")
    .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
    .returns(void.class)
    .addParameter(String[].class, "args")
    .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
    .build();

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
    .addMethod(main)
    .build();

JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
    .build();

javaFile.writeTo(System.out);
```

To declare the main method, we've created a `MethodSpec` "main" configured with modifiers, return
type, parameters and code statements. We add the main method to a `HelloWorld` class, and then add
that to a `HelloWorld.java` file.

In this case we write the file to `System.out`, but we could also get it as a string
(`JavaFile.toString()`) or write it to the file system (`JavaFile.writeTo()`).

The [Javadoc][javadoc] catalogs the complete JavaPoet API, which we explore below.

### Code & Control Flow

Most of JavaPoet's API uses plain old immutable Java objects. There's also builders, method chaining
and varargs to make the API friendly. JavaPoet offers models for classes & interfaces (`TypeSpec`),
fields (`FieldSpec`), methods & constructors (`MethodSpec`), parameters (`ParameterSpec`) and
annotations (`AnnotationSpec`).

But the _body_ of methods and constructors is not modeled. There's no expression class, no
statement class or syntax tree nodes. Instead, JavaPoet uses strings for code blocks:

```java
MethodSpec main = MethodSpec.methodBuilder("main")
    .addCode(""
        + "int total = 0;\n"
        + "for (int i = 0; i < 10; i++) {\n"
        + "  total += i;\n"
        + "}\n")
    .build();
```

Which generates this:

```java
void main() {
  int total = 0;
  for (int i = 0; i < 10; i++) {
    total += i;
  }
}
```

The manual semicolons, line wrapping, and indentation are tedious and so JavaPoet offers APIs to
make it easier. There's `addStatement()` which takes care of semicolons and newline, and
`beginControlFlow()` + `endControlFlow()` which are used together for braces, newlines, and
indentation:

```java
MethodSpec main = MethodSpec.methodBuilder("main")
    .addStatement("int total = 0")
    .beginControlFlow("for (int i = 0; i < 10; i++)")
    .addStatement("total += i")
    .endControlFlow()
    .build();
```

This example is lame because the generated code is constant! Suppose instead of just adding 0 to 10,
we want to make the operation and range configurable. Here's a method that generates a method:

```java
private MethodSpec computeRange(String name, int from, int to, String op) {
  return MethodSpec.methodBuilder(name)
      .returns(int.class)
      .addStatement("int result = 1")
      .beginControlFlow("for (int i = " + from + "; i < " + to + "; i++)")
      .addStatement("result = result " + op + " i")
      .endControlFlow()
      .addStatement("return result")
      .build();
}
```

And here's what we get when we call `computeRange("multiply10to20", 10, 20, "*")`:

```java
int multiply10to20() {
  int result = 1;
  for (int i = 10; i < 20; i++) {
    result = result * i;
  }
  return result;
}
```

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

The string-concatenation in calls to `beginControlFlow()` and `addStatement` is distracting. Too
many operators. To address this, JavaPoet offers a syntax inspired-by but incompatible-with
[`String.format()`][formatter]. It accepts **`$L`** to emit a **literal** value in the output. This
works just like `Formatter`'s `%s`:

```java
private MethodSpec computeRange(String name, int from, int to, String op) {
  return MethodSpec.methodBuilder(name)
      .returns(int.class)
      .addStatement("int result = 0")
      .beginControlFlow("for (int i = $L; i < $L; i++)", from, to)
      .addStatement("result = result $L i", op)
      .endControlFlow()
      .addStatement("return result")
      .build();
}
```

Literals are emitted directly to the output code with no escaping. Arguments for literals may be
strings, primitives, and a few JavaPoet types described below.

### $S for Strings

When emitting code that includes string literals, we can use **`$S`** to emit a **string**, complete
with wrapping quotation marks and escaping. Here's a program that emits 3 methods, each of which
returns its own name:

```java
public static void main(String[] args) throws Exception {
  TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
      .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
      .addMethod(whatsMyName("slimShady"))
      .addMethod(whatsMyName("eminem"))
      .addMethod(whatsMyName("marshallMathers"))
      .build();

  JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
      .build();

  javaFile.writeTo(System.out);
}

private static MethodSpec whatsMyName(String name) {
  return MethodSpec.methodBuilder(name)
      .returns(String.class)
      .addStatement("return $S", name)
      .build();
}
```

In this case, using `$S` gives us quotation marks:

```java
public final class HelloWorld {
  String slimShady() {
    return "slimShady";
  }

  String eminem() {
    return "eminem";
  }

  String marshallMathers() {
    return "marshallMathers";
  }
}
```

### $T for Types

We Java programmers love our types: they make our code easier to understand. And JavaPoet is on
board. It has rich built-in support for types, including automatic generation of `import`
statements. Just use **`$T`** to reference **types**:

```java
MethodSpec today = MethodSpec.methodBuilder("today")
    .returns(Date.class)
    .addStatement("return new $T()", Date.class)
    .build();

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
    .addMethod(today)
    .build();

JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
    .build();

javaFile.writeTo(System.out);
```

That generates the following `.java` file, complete with the necessary `import`:

```java
package com.example.helloworld;

import java.util.Date;

public final class HelloWorld {
  Date today() {
    return new Date();
  }
}
```

We passed `Date.class` to reference a class that just-so-happens to be available when we're
generating code. This doesn't need to be the case. Here's a similar example, but this one
references a class that doesn't exist (yet):

```java
ClassName hoverboard = ClassName.get("com.mattel", "Hoverboard");

MethodSpec today = MethodSpec.methodBuilder("tomorrow")
    .returns(hoverboard)
    .addStatement("return new $T()", hoverboard)
    .build();
```

And that not-yet-existent class is imported as well:

```java
package com.example.helloworld;

import com.mattel.Hoverboard;

public final class HelloWorld {
  Hoverboard tomorrow() {
    return new Hoverboard();
  }
}
```

The `ClassName` type is very important, and you'll need it frequently when you're using JavaPoet.
It can identify any _declared_ class. Declared types are just the beginning of Java's rich type
system: we also have arrays, parameterized types, wildcard types, and type variables. JavaPoet has
classes for building each of these:

```java
ClassName hoverboard = ClassName.get("com.mattel", "Hoverboard");
ClassName list = ClassName.get("java.util", "List");
ClassName arrayList = ClassName.get("java.util", "ArrayList");
TypeName listOfHoverboards = ParameterizedTypeName.get(list, hoverboard);

MethodSpec beyond = MethodSpec.methodBuilder("beyond")
    .returns(listOfHoverboards)
    .addStatement("$T result = new $T<>()", listOfHoverboards, arrayList)
    .addStatement("result.add(new $T())", hoverboard)
    .addStatement("result.add(new $T())", hoverboard)
    .addStatement("result.add(new $T())", hoverboard)
    .addStatement("return result")
    .build();
```

JavaPoet will decompose each type and import its components where possible.

```java
package com.example.helloworld;

import com.mattel.Hoverboard;
import java.util.ArrayList;
import java.util.List;

public final class HelloWorld {
  List<Hoverboard> beyond() {
    List<Hoverboard> result = new ArrayList<>();
    result.add(new Hoverboard());
    result.add(new Hoverboard());
    result.add(new Hoverboard());
    return result;
  }
}
```

#### Import static

JavaPoet supports `import static`. It does it via explicitly collecting type member names. Let's
enhance the previous example with some static sugar:

```java
...
ClassName namedBoards = ClassName.get("com.mattel", "Hoverboard", "Boards");

MethodSpec beyond = MethodSpec.methodBuilder("beyond")
    .returns(listOfHoverboards)
    .addStatement("$T result = new $T<>()", listOfHoverboards, arrayList)
    .addStatement("result.add($T.createNimbus(2000))", hoverboard)
    .addStatement("result.add($T.createNimbus(\"2001\"))", hoverboard)
    .addStatement("result.add($T.createNimbus($T.THUNDERBOLT))", hoverboard, namedBoards)
    .addStatement("$T.sort(result)", Collections.class)
    .addStatement("return result.isEmpty() ? $T.emptyList() : result", Collections.class)
    .build();

TypeSpec hello = TypeSpec.classBuilder("HelloWorld")
    .addMethod(beyond)
    .build();

JavaFile.builder("com.example.helloworld", hello)
    .addStaticImport(hoverboard, "createNimbus")
    .addStaticImport(namedBoards, "*")
    .addStaticImport(Collections.class, "*")
    .build();
```

JavaPoet will first add your `import static` block to the file as configured, match and mangle
all calls accordingly and also import all other types as needed.

```java
package com.example.helloworld;

import static com.mattel.Hoverboard.Boards.*;
import static com.mattel.Hoverboard.createNimbus;
import static java.util.Collections.*;

import com.mattel.Hoverboard;
import java.util.ArrayList;
import java.util.List;

class HelloWorld {
  List<Hoverboard> beyond() {
    List<Hoverboard> result = new ArrayList<>();
    result.add(createNimbus(2000));
    result.add(createNimbus("2001"));
    result.add(createNimbus(THUNDERBOLT));
    sort(result);
    return result.isEmpty() ? emptyList() : result;
  }
}
```

### $N for Names

Generated code is often self-referential. Use **`$N`** to refer to another generated declaration by
its name. Here's a method that calls another:

```java
public String byteToHex(int b) {
  char[] result = new char[2];
  result[0] = hexDigit((b >>> 4) & 0xf);
  result[1] = hexDigit(b & 0xf);
  return new String(result);
}

public char hexDigit(int i) {
  return (char) (i < 10 ? i + '0' : i - 10 + 'a');
}
```

When generating the code above, we pass the `hexDigit()` method as an argument to the `byteToHex()`
method using `$N`:

```java
MethodSpec hexDigit = MethodSpec.methodBuilder("hexDigit")
    .addParameter(int.class, "i")
    .returns(char.class)
    .addStatement("return (char) (i < 10 ? i + '0' : i - 10 + 'a')")
    .build();

MethodSpec byteToHex = MethodSpec.methodBuilder("byteToHex")
    .addParameter(int.class, "b")
    .returns(String.class)
    .addStatement("char[] result = new char[2]")
    .addStatement("result[0] = $N((b >>> 4) & 0xf)", hexDigit)
    .addStatement("result[1] = $N(b & 0xf)", hexDigit)
    .addStatement("return new String(result)")
    .build();
```

### Code block format strings

Code blocks may specify the values for their placeholders in a few ways. Only one style may be used
for each operation on a code block.

#### Relative Arguments

Pass an argument value for each placeholder in the format string to `CodeBlock.add()`. In each
example, we generate code to say "I ate 3 tacos"

```java
CodeBlock.builder().add("I ate $L $L", 3, "tacos")
```

#### Positional Arguments

Place an integer index (1-based) before the placeholder in the format string to specify which
 argument to use.

```java
CodeBlock.builder().add("I ate $2L $1L", "tacos", 3)
```

#### Named Arguments

Use the syntax `$argumentName:X` where `X` is the format character and call `CodeBlock.addNamed()`
with a map containing all argument keys in the format string. Argument names use characters in
`a-z`, `A-Z`, `0-9`, and `_`, and must start with a lowercase character.

```java
Map<String, Object> map = new LinkedHashMap<>();
map.put("food", "tacos");
map.put("count", 3);
CodeBlock.builder().addNamed("I ate $count:L $food:L", map)
```

### Methods

All of the above methods have a code body. Use `Modifiers.ABSTRACT` to get a method without any
body. This is only legal if the enclosing class is either abstract or an interface.

```java
MethodSpec flux = MethodSpec.methodBuilder("flux")
    .addModifiers(Modifier.ABSTRACT, Modifier.PROTECTED)
    .build();

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
    .addMethod(flux)
    .build();
```

Which generates this:

```java
public abstract class HelloWorld {
  protected abstract void flux();
}
```

The other modifiers work where permitted. Note that when specifying modifiers, JavaPoet uses
[`javax.lang.model.element.Modifier`][modifier], a class that is not available on Android. This
limitation applies to code-generating-code only; the output code runs everywhere: JVMs, Android,
and GWT.

Methods also have parameters, exceptions, varargs, Javadoc, annotations, type variables, and a
return type. All of these are configured with `MethodSpec.Builder`.

### Constructors

`MethodSpec` is a slight misnomer; it can also be used for constructors:

```java
MethodSpec flux = MethodSpec.constructorBuilder()
    .addModifiers(Modifier.PUBLIC)
    .addParameter(String.class, "greeting")
    .addStatement("this.$N = $N", "greeting", "greeting")
    .build();

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC)
    .addField(String.class, "greeting", Modifier.PRIVATE, Modifier.FINAL)
    .addMethod(flux)
    .build();
```

Which generates this:

```java
public class HelloWorld {
  private final String greeting;

  public HelloWorld(String greeting) {
    this.greeting = greeting;
  }
}
```

For the most part, constructors work just like methods. When emitting code, JavaPoet will place
constructors before methods in the output file.

### Parameters

Declare parameters on methods and constructors with either `ParameterSpec.builder()` or
`MethodSpec`'s convenient `addParameter()` API:

```java
ParameterSpec android = ParameterSpec.builder(String.class, "android")
    .addModifiers(Modifier.FINAL)
    .build();

MethodSpec welcomeOverlords = MethodSpec.methodBuilder("welcomeOverlords")
    .addParameter(android)
    .addParameter(String.class, "robot", Modifier.FINAL)
    .build();
```

Though the code above to generate `android` and `robot` parameters is different, the output is the
same:

```java
void welcomeOverlords(final String android, final String robot) {
}
```

The extended `Builder` form is necessary when the parameter has annotations (such as `@Nullable`).

### Fields

Like parameters, fields can be created either with builders or by using convenient helper methods:

```java
FieldSpec android = FieldSpec.builder(String.class, "android")
    .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
    .build();

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC)
    .addField(android)
    .addField(String.class, "robot", Modifier.PRIVATE, Modifier.FINAL)
    .build();
```

Which generates:

```java
public class HelloWorld {
  private final String android;

  private final String robot;
}
```

The extended `Builder` form is necessary when a field has Javadoc, annotations, or a field
initializer. Field initializers use the same [`String.format()`][formatter]-like syntax as the code
blocks above:

```java
FieldSpec android = FieldSpec.builder(String.class, "android")
    .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
    .initializer("$S + $L", "Lollipop v.", 5.0d)
    .build();
```

Which generates:

```java
private final String android = "Lollipop v." + 5.0;
```

### Interfaces

JavaPoet has no trouble with interfaces. Note that interface methods must always be `PUBLIC
ABSTRACT` and interface fields must always be `PUBLIC STATIC FINAL`. These modifiers are necessary
when defining the interface:

```java
TypeSpec helloWorld = TypeSpec.interfaceBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC)
    .addField(FieldSpec.builder(String.class, "ONLY_THING_THAT_IS_CONSTANT")
        .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
        .initializer("$S", "change")
        .build())
    .addMethod(MethodSpec.methodBuilder("beep")
        .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
        .build())
    .build();
```

But these modifiers are omitted when the code is generated. These are the defaults so we don't need
to include them for `javac`'s benefit!

```java
public interface HelloWorld {
  String ONLY_THING_THAT_IS_CONSTANT = "change";

  void beep();
}
```

### Enums

Use `enumBuilder` to create the enum type, and `addEnumConstant()` for each value:

```java
TypeSpec helloWorld = TypeSpec.enumBuilder("Roshambo")
    .addModifiers(Modifier.PUBLIC)
    .addEnumConstant("ROCK")
    .addEnumConstant("SCISSORS")
    .addEnumConstant("PAPER")
    .build();
```

To generate this:

```java
public enum Roshambo {
  ROCK,

  SCISSORS,

  PAPER
}
```

Fancy enums are supported, where the enum values override methods or call a superclass constructor.
Here's a comprehensive example:

```java
TypeSpec helloWorld = TypeSpec.enumBuilder("Roshambo")
    .addModifiers(Modifier.PUBLIC)
    .addEnumConstant("ROCK", TypeSpec.anonymousClassBuilder("$S", "fist")
        .addMethod(MethodSpec.methodBuilder("toString")
            .addAnnotation(Override.class)
            .addModifiers(Modifier.PUBLIC)
            .addStatement("return $S", "avalanche!")
            .returns(String.class)
            .build())
        .build())
    .addEnumConstant("SCISSORS", TypeSpec.anonymousClassBuilder("$S", "peace")
        .build())
    .addEnumConstant("PAPER", TypeSpec.anonymousClassBuilder("$S", "flat")
        .build())
    .addField(String.class, "handsign", Modifier.PRIVATE, Modifier.FINAL)
    .addMethod(MethodSpec.constructorBuilder()
        .addParameter(String.class, "handsign")
        .addStatement("this.$N = $N", "handsign", "handsign")
        .build())
    .build();
```

Which generates this:

```java
public enum Roshambo {
  ROCK("fist") {
    @Override
    public String toString() {
      return "avalanche!";
    }
  },

  SCISSORS("peace"),

  PAPER("flat");

  private final String handsign;

  Roshambo(String handsign) {
    this.handsign = handsign;
  }
}
```

### Anonymous Inner Classes

In the enum code, we used `TypeSpec.anonymousInnerClass()`. Anonymous inner classes can also be used in
code blocks. They are values that can be referenced with `$L`:

```java
TypeSpec comparator = TypeSpec.anonymousClassBuilder("")
    .addSuperinterface(ParameterizedTypeName.get(Comparator.class, String.class))
    .addMethod(MethodSpec.methodBuilder("compare")
        .addAnnotation(Override.class)
        .addModifiers(Modifier.PUBLIC)
        .addParameter(String.class, "a")
        .addParameter(String.class, "b")
        .returns(int.class)
        .addStatement("return $N.length() - $N.length()", "a", "b")
        .build())
    .build();

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addMethod(MethodSpec.methodBuilder("sortByLength")
        .addParameter(ParameterizedTypeName.get(List.class, String.class), "strings")
        .addStatement("$T.sort($N, $L)", Collections.class, "strings", comparator)
        .build())
    .build();
```

This generates a method that contains a class that contains a method:

```java
void sortByLength(List<String> strings) {
  Collections.sort(strings, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
      return a.length() - b.length();
    }
  });
}
```

One particularly tricky part of defining anonymous inner classes is the arguments to the superclass
constructor. In the above code we're passing the empty string for no arguments:
`TypeSpec.anonymousClassBuilder("")`. To pass different parameters use JavaPoet's code block
syntax with commas to separate arguments.


### Annotations

Simple annotations are easy:

```java
MethodSpec toString = MethodSpec.methodBuilder("toString")
    .addAnnotation(Override.class)
    .returns(String.class)
    .addModifiers(Modifier.PUBLIC)
    .addStatement("return $S", "Hoverboard")
    .build();
```

Which generates this method with an `@Override` annotation:

```java
  @Override
  public String toString() {
    return "Hoverboard";
  }
```

Use `AnnotationSpec.builder()` to set properties on annotations:

```java
MethodSpec logRecord = MethodSpec.methodBuilder("recordEvent")
    .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
    .addAnnotation(AnnotationSpec.builder(Headers.class)
        .addMember("accept", "$S", "application/json; charset=utf-8")
        .addMember("userAgent", "$S", "Square Cash")
        .build())
    .addParameter(LogRecord.class, "logRecord")
    .returns(LogReceipt.class)
    .build();
```

Which generates this annotation with `accept` and `userAgent` properties:

```java
@Headers(
    accept = "application/json; charset=utf-8",
    userAgent = "Square Cash"
)
LogReceipt recordEvent(LogRecord logRecord);
```

When you get fancy, annotation values can be annotations themselves. Use `$L` for embedded
annotations:

```java
MethodSpec logRecord = MethodSpec.methodBuilder("recordEvent")
    .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
    .addAnnotation(AnnotationSpec.builder(HeaderList.class)
        .addMember("value", "$L", AnnotationSpec.builder(Header.class)
            .addMember("name", "$S", "Accept")
            .addMember("value", "$S", "application/json; charset=utf-8")
            .build())
        .addMember("value", "$L", AnnotationSpec.builder(Header.class)
            .addMember("name", "$S", "User-Agent")
            .addMember("value", "$S", "Square Cash")
            .build())
        .build())
    .addParameter(LogRecord.class, "logRecord")
    .returns(LogReceipt.class)
    .build();
```

Which generates this:

```java
@HeaderList({
    @Header(name = "Accept", value = "application/json; charset=utf-8"),
    @Header(name = "User-Agent", value = "Square Cash")
})
LogReceipt recordEvent(LogRecord logRecord);
```

Note that you can call `addMember()` multiple times with the same property name to populate a list
of values for that property.

### Javadoc

Fields, methods and types can be documented with Javadoc:

```java
MethodSpec dismiss = MethodSpec.methodBuilder("dismiss")
    .addJavadoc("Hides {@code message} from the caller's history. Other\n"
        + "participants in the conversation will continue to see the\n"
        + "message in their own history unless they also delete it.\n")
    .addJavadoc("\n")
    .addJavadoc("<p>Use {@link #delete($T)} to delete the entire\n"
        + "conversation for all participants.\n", Conversation.class)
    .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
    .addParameter(Message.class, "message")
    .build();
```

Which generates this:

```java
  /**
   * Hides {@code message} from the caller's history. Other
   * participants in the conversation will continue to see the
   * message in their own history unless they also delete it.
   *
   * <p>Use {@link #delete(Conversation)} to delete the entire
   * conversation for all participants.
   */
  void dismiss(Message message);
```

Use `$T` when referencing types in Javadoc to get automatic imports.

Download
--------

Download [the latest .jar][dl] or depend via Maven:
```xml
<dependency>
  <groupId>com.squareup</groupId>
  <artifactId>javapoet</artifactId>
  <version>1.13.0</version>
</dependency>
```
or Gradle:
```groovy
compile 'com.squareup:javapoet:1.13.0'
```

Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap].



License
-------

    Copyright 2015 Square, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.



JavaWriter
==========

JavaPoet is the successor to [JavaWriter][javawriter]. New projects should prefer JavaPoet because
it has a stronger code model: it understands types and can manage imports automatically. JavaPoet is
also better suited to composition: rather than streaming the contents of a `.java` file
top-to-bottom in a single pass, a file can be assembled as a tree of declarations.

JavaWriter continues to be available in [GitHub][javawriter] and [Maven Central][javawriter_maven].


 [dl]: https://search.maven.org/remote_content?g=com.squareup&a=javapoet&v=LATEST
 [snap]: https://oss.sonatype.org/content/repositories/snapshots/com/squareup/javapoet/
 [javadoc]: https://square.github.io/javapoet/1.x/javapoet/
 [javawriter]: https://github.com/square/javapoet/tree/javawriter_2
 [javawriter_maven]: https://search.maven.org/#artifactdetails%7Ccom.squareup%7Cjavawriter%7C2.5.1%7Cjar
 [formatter]: https://developer.android.com/reference/java/util/Formatter.html
 [modifier]: https://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/Modifier.html


================================================
FILE: RELEASING.md
================================================
Releasing
=========

1. Update the CHANGELOG.md for the impending release.
2. Update the README.md with the new version.
3. `git commit -am "Update changelog for X.Y.Z."` (where X.Y.Z is the new version).
4. `mvn-release`.
    * `What is the release version for "JavaPoet"? (com.squareup.javapoet) X.Y.Z:` - hit Enter.
    * `What is SCM release tag or label for "JavaPoet"? (com.squareup.javapoet) javapoet-X.Y.Z:` - hit Enter.
    * `What is the new development version for "JavaPoet"? (com.squareup.javapoet) X.Y.(Z + 1)-SNAPSHOT:` - enter `X.(Y + 1).0-SNAPSHOT`.
    * Enter your GPG Passphrase when prompted.
5. Visit Sonatype Nexus and promote the artifact.

If step 4 or 5 fails:

  * Drop the Sonatype repo, 
  * Fix the problem,
  * Manully revert the version change in `pom.xml` made by `mvn-release`,
  * Commit,
  * And start again at step 4.

Prerequisites
-------------

In `~/.m2/settings.xml`, set the following:

```xml
<settings>
  <servers>
    <server>
      <id>sonatype-nexus-staging</id>
      <username>your-nexus-username</username>
      <password>your-nexus-password</password>
    </server>
  </servers>
</settings>
```

In your shell's `.rc` file, set the following:

```
alias mvn-release='mvn clean source:jar javadoc:jar verify && mvn clean release:clean && mvn release:prepare release:perform'
```

Refer to the [GPG Keys][gpg_keys] guide if you need to set up GPG keys for signing.

 [gpg_keys]: https://square.github.io/okio/releasing/#prerequisite-gpg-keys


================================================
FILE: checkstyle.xml
================================================
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
    "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">

<module name="Checker">
  <module name="SuppressWarningsFilter"/>
  <module name="NewlineAtEndOfFile"/>
  <module name="FileLength"/>
  <module name="FileTabCharacter"/>

  <!-- Trailing spaces -->
  <module name="RegexpSingleline">
    <property name="format" value="\s+$"/>
    <property name="message" value="Line has trailing spaces."/>
  </module>

  <!-- Space after 'for' and 'if' -->
  <module name="RegexpSingleline">
    <property name="format" value="^\s*(for|if)\b[^ ]"/>
    <property name="message" value="Space needed before opening parenthesis."/>
  </module>

  <!-- For each spacing -->
  <module name="RegexpSingleline">
    <property name="format" value="^\s*for \(.*?([^ ]:|:[^ ])"/>
    <property name="message" value="Space needed around ':' character."/>
  </module>

  <module name="TreeWalker">
    <property name="cacheFile" value="${checkstyle.cache.file}"/>

    <!-- Checks for Javadoc comments.                     -->
    <!-- See http://checkstyle.sf.net/config_javadoc.html -->
    <!--module name="JavadocMethod"/-->
    <!--module name="JavadocType"/-->
    <!--module name="JavadocVariable"/-->
    <module name="JavadocStyle"/>


    <!-- Checks for Naming Conventions.                  -->
    <!-- See http://checkstyle.sf.net/config_naming.html -->
    <module name="ConstantName"/>
    <module name="LocalFinalVariableName"/>
    <module name="LocalVariableName"/>
    <module name="MemberName"/>
    <module name="MethodName"/>
    <module name="PackageName"/>
    <module name="ParameterName"/>
    <module name="StaticVariableName"/>
    <module name="TypeName"/>


    <!-- Checks for imports                              -->
    <!-- See http://checkstyle.sf.net/config_import.html -->
    <module name="AvoidStarImport"/>
    <module name="IllegalImport"/>
    <!-- defaults to sun.* packages -->
    <module name="RedundantImport"/>
    <module name="UnusedImports">
      <property name="processJavadoc" value="true"/>
    </module>


    <!-- Checks for Size Violations.                    -->
    <!-- See http://checkstyle.sf.net/config_sizes.html -->
    <module name="LineLength">
      <property name="max" value="100"/>
    </module>
    <module name="MethodLength">
      <property name="max" value="160"/>
    </module>
    <module name="ParameterNumber"/>


    <!-- Checks for whitespace                               -->
    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
    <module name="GenericWhitespace"/>
    <!--<module name="EmptyForIteratorPad"/>-->
    <module name="MethodParamPad"/>
    <module name="NoWhitespaceAfter"/>
    <module name="NoWhitespaceBefore"/>
    <module name="OperatorWrap"/>
    <module name="ParenPad"/>
    <module name="TypecastParenPad"/>
    <module name="WhitespaceAfter"/>
    <module name="WhitespaceAround">
      <property name="tokens"
          value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN,
          COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_CATCH,
          LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
          LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
          MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, SL, SLIST,
          SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
    </module>


    <!-- Modifier Checks                                    -->
    <!-- See http://checkstyle.sf.net/config_modifiers.html -->
    <module name="ModifierOrder"/>
    <module name="RedundantModifier"/>


    <!-- Checks for blocks. You know, those {}'s         -->
    <!-- See http://checkstyle.sf.net/config_blocks.html -->
    <module name="AvoidNestedBlocks"/>
    <!--module name="EmptyBlock"/-->
    <module name="LeftCurly"/>
    <!--<module name="NeedBraces"/>-->
    <module name="RightCurly"/>


    <!-- Checks for common coding problems               -->
    <!-- See http://checkstyle.sf.net/config_coding.html -->
    <!--module name="AvoidInlineConditionals"/-->
    <module name="CovariantEquals"/>
    <module name="EmptyStatement"/>
    <!--<module name="EqualsAvoidNull"/>-->
    <module name="EqualsHashCode"/>
    <!--module name="HiddenField"/-->
    <module name="IllegalInstantiation"/>
    <module name="InnerAssignment"/>
    <!--<module name="MagicNumber"/>-->
    <module name="MissingSwitchDefault"/>
    <!--module name="RedundantThrows"/-->
    <module name="SimplifyBooleanExpression"/>
    <module name="SimplifyBooleanReturn"/>

    <!-- Checks for class design                         -->
    <!-- See http://checkstyle.sf.net/config_design.html -->
    <!--module name="DesignForExtension"/-->
    <module name="FinalClass"/>
    <module name="HideUtilityClassConstructor"/>
    <module name="InterfaceIsType"/>
    <!--module name="VisibilityModifier"/-->


    <!-- Miscellaneous other checks.                   -->
    <!-- See http://checkstyle.sf.net/config_misc.html -->
    <module name="ArrayTypeStyle"/>
    <!--module name="FinalParameters"/-->
    <module name="TodoComment"/>
    <module name="UpperEll"/>

    <!-- Make the @SuppressWarnings annotations available to Checkstyle -->
    <module name="SuppressWarningsHolder"/>
  </module>
</module>


================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.sonatype.oss</groupId>
    <artifactId>oss-parent</artifactId>
    <version>7</version>
  </parent>

  <groupId>com.squareup</groupId>
  <artifactId>javapoet</artifactId>
  <version>1.14.0-SNAPSHOT</version>

  <name>JavaPoet</name>
  <description>Use beautiful Java code to generate beautiful Java code.</description>
  <url>http://github.com/square/javapoet/</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <java.version>1.8</java.version>
    <junit.version>4.13.2</junit.version>
    <truth.version>1.4.4</truth.version>
    <compile-testing.version>0.21.0</compile-testing.version>
  </properties>

  <scm>
    <url>http://github.com/square/javapoet/</url>
    <connection>scm:git:git://github.com/square/javapoet.git</connection>
    <developerConnection>scm:git:ssh://git@github.com/square/javapoet.git</developerConnection>
    <tag>HEAD</tag>
  </scm>

  <issueManagement>
    <system>GitHub Issues</system>
    <url>http://github.com/square/javapoet/issues</url>
  </issueManagement>

  <licenses>
    <license>
      <name>Apache 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
    </license>
  </licenses>

  <organization>
    <name>Square, Inc.</name>
    <url>http://squareup.com</url>
  </organization>

  <dependencies>
    <dependency>
      <groupId>com.google.truth</groupId>
      <artifactId>truth</artifactId>
      <version>${truth.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.google.testing.compile</groupId>
      <artifactId>compile-testing</artifactId>
      <version>${compile-testing.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.google.jimfs</groupId>
      <artifactId>jimfs</artifactId>
      <version>1.3.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>4.11.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jdt.core.compiler</groupId>
      <artifactId>ecj</artifactId>
      <version>4.6.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.12.1</version>
        <configuration>
          <compilerId>javac-with-errorprone</compilerId>
          <forceJavacCompilerUse>true</forceJavacCompilerUse>
          <source>${java.version}</source>
          <target>${java.version}</target>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-javac-errorprone</artifactId>
            <version>2.8.2</version>
          </dependency>
          <dependency>
            <groupId>com.google.errorprone</groupId>
            <artifactId>error_prone_core</artifactId>
            <version>2.3.1</version>
          </dependency>
        </dependencies>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
        <version>3.5.0</version>
        <dependencies>
          <dependency>
            <groupId>com.puppycrawl.tools</groupId>
            <artifactId>checkstyle</artifactId>
            <version>8.18</version>
          </dependency>
        </dependencies>
        <configuration>
          <failsOnError>true</failsOnError>
          <configLocation>checkstyle.xml</configLocation>
          <consoleOutput>true</consoleOutput>
        </configuration>
        <executions>
          <execution>
            <phase>verify</phase>
            <goals>
              <goal>checkstyle</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.4.2</version>
        <configuration>
          <archive>
            <manifestEntries>
              <Automatic-Module-Name>com.squareup.javapoet</Automatic-Module-Name>
            </manifestEntries>
          </archive>
        </configuration>
      </plugin>

    </plugins>
  </build>
</project>


================================================
FILE: renovate.json
================================================
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:base"
  ]
}


================================================
FILE: src/main/java/com/squareup/javapoet/AnnotationSpec.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleAnnotationValueVisitor8;

import static com.squareup.javapoet.Util.characterLiteralWithoutSingleQuotes;
import static com.squareup.javapoet.Util.checkArgument;
import static com.squareup.javapoet.Util.checkNotNull;

/** A generated annotation on a declaration. */
public final class AnnotationSpec {
  public static final String VALUE = "value";

  public final TypeName type;
  public final Map<String, List<CodeBlock>> members;

  private AnnotationSpec(Builder builder) {
    this.type = builder.type;
    this.members = Util.immutableMultimap(builder.members);
  }

  void emit(CodeWriter codeWriter, boolean inline) throws IOException {
    String whitespace = inline ? "" : "\n";
    String memberSeparator = inline ? ", " : ",\n";
    if (members.isEmpty()) {
      // @Singleton
      codeWriter.emit("@$T", type);
    } else if (members.size() == 1 && members.containsKey("value")) {
      // @Named("foo")
      codeWriter.emit("@$T(", type);
      emitAnnotationValues(codeWriter, whitespace, memberSeparator, members.get("value"));
      codeWriter.emit(")");
    } else {
      // Inline:
      //   @Column(name = "updated_at", nullable = false)
      //
      // Not inline:
      //   @Column(
      //       name = "updated_at",
      //       nullable = false
      //   )
      codeWriter.emit("@$T(" + whitespace, type);
      codeWriter.indent(2);
      for (Iterator<Map.Entry<String, List<CodeBlock>>> i
          = members.entrySet().iterator(); i.hasNext(); ) {
        Map.Entry<String, List<CodeBlock>> entry = i.next();
        codeWriter.emit("$L = ", entry.getKey());
        emitAnnotationValues(codeWriter, whitespace, memberSeparator, entry.getValue());
        if (i.hasNext()) codeWriter.emit(memberSeparator);
      }
      codeWriter.unindent(2);
      codeWriter.emit(whitespace + ")");
    }
  }

  private void emitAnnotationValues(CodeWriter codeWriter, String whitespace,
      String memberSeparator, List<CodeBlock> values) throws IOException {
    if (values.size() == 1) {
      codeWriter.indent(2);
      codeWriter.emit(values.get(0));
      codeWriter.unindent(2);
      return;
    }

    codeWriter.emit("{" + whitespace);
    codeWriter.indent(2);
    boolean first = true;
    for (CodeBlock codeBlock : values) {
      if (!first) codeWriter.emit(memberSeparator);
      codeWriter.emit(codeBlock);
      first = false;
    }
    codeWriter.unindent(2);
    codeWriter.emit(whitespace + "}");
  }

  public static AnnotationSpec get(Annotation annotation) {
    return get(annotation, false);
  }

  public static AnnotationSpec get(Annotation annotation, boolean includeDefaultValues) {
    Builder builder = builder(annotation.annotationType());
    try {
      Method[] methods = annotation.annotationType().getDeclaredMethods();
      Arrays.sort(methods, Comparator.comparing(Method::getName));
      for (Method method : methods) {
        Object value = method.invoke(annotation);
        if (!includeDefaultValues) {
          if (Objects.deepEquals(value, method.getDefaultValue())) {
            continue;
          }
        }
        if (value.getClass().isArray()) {
          for (int i = 0; i < Array.getLength(value); i++) {
            builder.addMemberForValue(method.getName(), Array.get(value, i));
          }
          continue;
        }
        if (value instanceof Annotation) {
          builder.addMember(method.getName(), "$L", get((Annotation) value));
          continue;
        }
        builder.addMemberForValue(method.getName(), value);
      }
    } catch (Exception e) {
      throw new RuntimeException("Reflecting " + annotation + " failed!", e);
    }
    return builder.build();
  }

  public static AnnotationSpec get(AnnotationMirror annotation) {
    TypeElement element = (TypeElement) annotation.getAnnotationType().asElement();
    AnnotationSpec.Builder builder = AnnotationSpec.builder(ClassName.get(element));
    Visitor visitor = new Visitor(builder);
    for (ExecutableElement executableElement : annotation.getElementValues().keySet()) {
      String name = executableElement.getSimpleName().toString();
      AnnotationValue value = annotation.getElementValues().get(executableElement);
      value.accept(visitor, name);
    }
    return builder.build();
  }

  public static Builder builder(ClassName type) {
    checkNotNull(type, "type == null");
    return new Builder(type);
  }

  public static Builder builder(Class<?> type) {
    return builder(ClassName.get(type));
  }

  public Builder toBuilder() {
    Builder builder = new Builder(type);
    for (Map.Entry<String, List<CodeBlock>> entry : members.entrySet()) {
      builder.members.put(entry.getKey(), new ArrayList<>(entry.getValue()));
    }
    return builder;
  }

  @Override public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null) return false;
    if (getClass() != o.getClass()) return false;
    return toString().equals(o.toString());
  }

  @Override public int hashCode() {
    return toString().hashCode();
  }

  @Override public String toString() {
    StringBuilder out = new StringBuilder();
    try {
      CodeWriter codeWriter = new CodeWriter(out);
      codeWriter.emit("$L", this);
      return out.toString();
    } catch (IOException e) {
      throw new AssertionError();
    }
  }

  public static final class Builder {
    private final TypeName type;

    public final Map<String, List<CodeBlock>> members = new LinkedHashMap<>();

    private Builder(TypeName type) {
      this.type = type;
    }

    public Builder addMember(String name, String format, Object... args) {
      return addMember(name, CodeBlock.of(format, args));
    }

    public Builder addMember(String name, CodeBlock codeBlock) {
      List<CodeBlock> values = members.computeIfAbsent(name, k -> new ArrayList<>());
      values.add(codeBlock);
      return this;
    }

    /**
     * Delegates to {@link #addMember(String, String, Object...)}, with parameter {@code format}
     * depending on the given {@code value} object. Falls back to {@code "$L"} literal format if
     * the class of the given {@code value} object is not supported.
     */
    Builder addMemberForValue(String memberName, Object value) {
      checkNotNull(memberName, "memberName == null");
      checkNotNull(value, "value == null, constant non-null value expected for %s", memberName);
      checkArgument(SourceVersion.isName(memberName), "not a valid name: %s", memberName);
      if (value instanceof Class<?>) {
        return addMember(memberName, "$T.class", value);
      }
      if (value instanceof Enum) {
        return addMember(memberName, "$T.$L", value.getClass(), ((Enum<?>) value).name());
      }
      if (value instanceof String) {
        return addMember(memberName, "$S", value);
      }
      if (value instanceof Float) {
        return addMember(memberName, "$Lf", value);
      }
      if (value instanceof Long) {
        return addMember(memberName, "$LL", value);
      }
      if (value instanceof Character) {
        return addMember(memberName, "'$L'", characterLiteralWithoutSingleQuotes((char) value));
      }
      return addMember(memberName, "$L", value);
    }

    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);
    }
  }

  /**
   * Annotation value visitor adding members to the given builder instance.
   */
  private static class Visitor extends SimpleAnnotationValueVisitor8<Builder, String> {
    final Builder builder;

    Visitor(Builder builder) {
      super(builder);
      this.builder = builder;
    }

    @Override protected Builder defaultAction(Object o, String name) {
      return builder.addMemberForValue(name, o);
    }

    @Override public Builder visitAnnotation(AnnotationMirror a, String name) {
      return builder.addMember(name, "$L", get(a));
    }

    @Override public Builder visitEnumConstant(VariableElement c, String name) {
      return builder.addMember(name, "$T.$L", c.asType(), c.getSimpleName());
    }

    @Override public Builder visitType(TypeMirror t, String name) {
      return builder.addMember(name, "$T.class", t);
    }

    @Override public Builder visitArray(List<? extends AnnotationValue> values, String name) {
      for (AnnotationValue value : values) {
        value.accept(this, name);
      }
      return builder;
    }
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/ArrayTypeName.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.ArrayType;

import static com.squareup.javapoet.Util.checkNotNull;

public final class ArrayTypeName extends TypeName {
  public final TypeName componentType;

  private ArrayTypeName(TypeName componentType) {
    this(componentType, new ArrayList<>());
  }

  private ArrayTypeName(TypeName componentType, List<AnnotationSpec> annotations) {
    super(annotations);
    this.componentType = checkNotNull(componentType, "rawType == null");
  }

  @Override public ArrayTypeName annotated(List<AnnotationSpec> annotations) {
    return new ArrayTypeName(componentType, concatAnnotations(annotations));
  }

  @Override public TypeName withoutAnnotations() {
    return new ArrayTypeName(componentType);
  }

  @Override CodeWriter emit(CodeWriter out) throws IOException {
    return emit(out, false);
  }

  CodeWriter emit(CodeWriter out, boolean varargs) throws IOException {
    emitLeafType(out);
    return emitBrackets(out, varargs);
  }

  private CodeWriter emitLeafType(CodeWriter out) throws IOException {
    if (TypeName.asArray(componentType) != null) {
      return TypeName.asArray(componentType).emitLeafType(out);
    }
    return componentType.emit(out);
  }

  private CodeWriter emitBrackets(CodeWriter out, boolean varargs) throws IOException {
    if (isAnnotated()) {
      out.emit(" ");
      emitAnnotations(out);
    }

    if (TypeName.asArray(componentType) == null) {
      // Last bracket.
      return out.emit(varargs ? "..." : "[]");
    }
    out.emit("[]");
    return TypeName.asArray(componentType) .emitBrackets(out, varargs);
  }


  /** Returns an array type whose elements are all instances of {@code componentType}. */
  public static ArrayTypeName of(TypeName componentType) {
    return new ArrayTypeName(componentType);
  }

  /** Returns an array type whose elements are all instances of {@code componentType}. */
  public static ArrayTypeName of(Type componentType) {
    return of(TypeName.get(componentType));
  }

  /** Returns an array type equivalent to {@code mirror}. */
  public static ArrayTypeName get(ArrayType mirror) {
    return get(mirror, new LinkedHashMap<>());
  }

  static ArrayTypeName get(
      ArrayType mirror, Map<TypeParameterElement, TypeVariableName> typeVariables) {
    return new ArrayTypeName(get(mirror.getComponentType(), typeVariables));
  }

  /** Returns an array type equivalent to {@code type}. */
  public static ArrayTypeName get(GenericArrayType type) {
    return get(type, new LinkedHashMap<>());
  }

  static ArrayTypeName get(GenericArrayType type, Map<Type, TypeVariableName> map) {
    return ArrayTypeName.of(get(type.getGenericComponentType(), map));
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/ClassName.java
================================================
/*
 * Copyright (C) 2014 Google, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
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;
import javax.lang.model.util.SimpleElementVisitor8;

import static com.squareup.javapoet.Util.checkArgument;
import static com.squareup.javapoet.Util.checkNotNull;

/** A fully-qualified class name for top-level and member classes. */
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;

  /** The enclosing class, or null if this is not enclosed in another class. */
  final ClassName enclosingClassName;

  /** 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;

  private ClassName(String packageName, ClassName enclosingClassName, String simpleName) {
    this(packageName, enclosingClassName, simpleName, Collections.emptyList());
  }

  private ClassName(String packageName, ClassName enclosingClassName, String simpleName,
      List<AnnotationSpec> annotations) {
    super(annotations);
    this.packageName = Objects.requireNonNull(packageName, "packageName == null");
    this.enclosingClassName = enclosingClassName;
    this.simpleName = simpleName;
    this.canonicalName = enclosingClassName != null
        ? (enclosingClassName.canonicalName + '.' + simpleName)
        : (packageName.isEmpty() ? simpleName : packageName + '.' + simpleName);
  }

  @Override public ClassName annotated(List<AnnotationSpec> annotations) {
    return new ClassName(packageName, enclosingClassName, simpleName,
        concatAnnotations(annotations));
  }

  @Override public ClassName withoutAnnotations() {
    if (!isAnnotated()) return this;
    ClassName resultEnclosingClassName = enclosingClassName != null
        ? enclosingClassName.withoutAnnotations()
        : null;
    return new ClassName(packageName, resultEnclosingClassName, simpleName);
  }

  @Override public boolean isAnnotated() {
    return super.isAnnotated() || (enclosingClassName != null && enclosingClassName.isAnnotated());
  }

  /**
   * Returns the package name, like {@code "java.util"} for {@code Map.Entry}. Returns the empty
   * string for the default package.
   */
  public String packageName() {
    return packageName;
  }

  /**
   * Returns the enclosing class, like {@link Map} for {@code Map.Entry}. Returns null if this class
   * is not nested in another class.
   */
  public ClassName enclosingClassName() {
    return enclosingClassName;
  }

  /**
   * Returns the top class in this nesting group. Equivalent to chained calls to {@link
   * #enclosingClassName()} until the result's enclosing class is null.
   */
  public ClassName topLevelClassName() {
    return enclosingClassName != null ? enclosingClassName.topLevelClassName() : this;
  }

  /** Return the binary name of a class. */
  public String reflectionName() {
    return enclosingClassName != null
        ? (enclosingClassName.reflectionName() + '$' + simpleName)
        : (packageName.isEmpty() ? simpleName : packageName + '.' + simpleName);
  }

  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);
    }
    return simpleNames;
  }

  /**
   * Returns a class that shares the same enclosing package or class. If this class is enclosed by
   * another class, this is equivalent to {@code enclosingClassName().nestedClass(name)}. Otherwise
   * it is equivalent to {@code get(packageName(), name)}.
   */
  public ClassName peerClass(String name) {
    return new ClassName(packageName, enclosingClassName, name);
  }

  /**
   * Returns a new {@link ClassName} instance for the specified {@code name} as nested inside this
   * class.
   */
  public ClassName nestedClass(String name) {
    return new ClassName(packageName, this, name);
  }

  /** Returns the simple name of this class, like {@code "Entry"} for {@link Map.Entry}. */
  public String simpleName() {
    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");
    checkArgument(!void.class.equals(clazz), "'void' type cannot be represented as a ClassName");
    checkArgument(!clazz.isArray(), "array types cannot be represented as a ClassName");

    String anonymousSuffix = "";
    while (clazz.isAnonymousClass()) {
      int lastDollar = clazz.getName().lastIndexOf('$');
      anonymousSuffix = clazz.getName().substring(lastDollar) + anonymousSuffix;
      clazz = clazz.getEnclosingClass();
    }
    String name = clazz.getSimpleName() + anonymousSuffix;

    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;
      return new ClassName(packageName, null, name);
    }

    return ClassName.get(clazz.getEnclosingClass()).nestedClass(name);
  }

  /**
   * Returns a new {@link ClassName} instance for the given fully-qualified class name string. This
   * method assumes that the input is ASCII and follows typical Java style (lowercase package
   * names, UpperCamelCase class names) and may produce incorrect results or throw
   * {@link IllegalArgumentException} otherwise. For that reason, {@link #get(Class)} and
   * {@link #get(Class)} should be preferred as they can correctly create {@link ClassName}
   * instances without such restrictions.
   */
  public static ClassName bestGuess(String classNameString) {
    // Add the package name, like "java.util.concurrent", or "" for no package.
    int p = 0;
    while (p < classNameString.length() && Character.isLowerCase(classNameString.codePointAt(p))) {
      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);

    // Add class names like "Map" and "Entry".
    ClassName className = null;
    for (String simpleName : classNameString.substring(p).split("\\.", -1)) {
      checkArgument(!simpleName.isEmpty() && Character.isUpperCase(simpleName.codePointAt(0)),
          "couldn't make a guess for %s", classNameString);
      className = new ClassName(packageName, className, simpleName);
    }

    return className;
  }

  /**
   * Returns a class name created from the given parts. For example, calling this with package name
   * {@code "java.util"} and simple names {@code "Map"}, {@code "Entry"} yields {@link Map.Entry}.
   */
  public static ClassName get(String packageName, String simpleName, String... simpleNames) {
    ClassName className = new ClassName(packageName, null, simpleName);
    for (String name : simpleNames) {
      className = className.nestedClass(name);
    }
    return className;
  }

  /** Returns the class name for {@code element}. */
  public static ClassName get(TypeElement element) {
    checkNotNull(element, "element == null");
    String simpleName = element.getSimpleName().toString();

    return element.getEnclosingElement().accept(new SimpleElementVisitor8<ClassName, Void>() {
      @Override public ClassName visitPackage(PackageElement packageElement, Void p) {
        return new ClassName(packageElement.getQualifiedName().toString(), null, simpleName);
      }

      @Override public ClassName visitType(TypeElement enclosingClass, Void p) {
        return ClassName.get(enclosingClass).nestedClass(simpleName);
      }

      @Override public ClassName visitUnknown(Element unknown, Void p) {
        return get("", simpleName);
      }

      @Override public ClassName defaultAction(Element enclosingElement, Void p) {
        throw new IllegalArgumentException("Unexpected type nesting: " + element);
      }
    }, null);
  }

  @Override public int compareTo(ClassName o) {
    return canonicalName.compareTo(o.canonicalName);
  }

  @Override CodeWriter emit(CodeWriter out) throws IOException {
    boolean charsEmitted = false;
    for (ClassName className : enclosingClasses()) {
      String simpleName;
      if (charsEmitted) {
        // We've already emitted an enclosing class. Emit as we go.
        out.emit(".");
        simpleName = className.simpleName;

      } else if (className.isAnnotated() || className == this) {
        // We encountered the first enclosing class that must be emitted.
        String qualifiedName = out.lookupName(className);
        int dot = qualifiedName.lastIndexOf('.');
        if (dot != -1) {
          out.emitAndIndent(qualifiedName.substring(0, dot + 1));
          simpleName = qualifiedName.substring(dot + 1);
          charsEmitted = true;
        } else {
          simpleName = qualifiedName;
        }

      } else {
        // Don't emit this enclosing type. Keep going so we can be more precise.
        continue;
      }

      if (className.isAnnotated()) {
        if (charsEmitted) out.emit(" ");
        className.emitAnnotations(out);
      }

      out.emit(simpleName);
      charsEmitted = true;
    }

    return out;
  }

  /** Returns all enclosing classes in this, outermost first. */
  private List<ClassName> enclosingClasses() {
    List<ClassName> result = new ArrayList<>();
    for (ClassName c = this; c != null; c = c.enclosingClassName) {
      result.add(c);
    }
    Collections.reverse(result);
    return result;
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/CodeBlock.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collector;
import java.util.stream.StreamSupport;
import javax.lang.model.element.Element;
import javax.lang.model.type.TypeMirror;

import static com.squareup.javapoet.Util.checkArgument;

/**
 * A fragment of a .java file, potentially containing declarations, statements, and documentation.
 * Code blocks are not necessarily well-formed Java code, and are not validated. This class assumes
 * javac will check correctness later!
 *
 * <p>Code blocks support placeholders like {@link java.text.Format}. Where {@link String#format}
 * uses percent {@code %} to reference target values, this class uses dollar sign {@code $} and has
 * its own set of permitted placeholders:
 *
 * <ul>
 *   <li>{@code $L} emits a <em>literal</em> value with no escaping. Arguments for literals may be
 *       strings, primitives, {@linkplain TypeSpec type declarations}, {@linkplain AnnotationSpec
 *       annotations} and even other code blocks.
 *   <li>{@code $N} emits a <em>name</em>, using name collision avoidance where necessary. Arguments
 *       for names may be strings (actually any {@linkplain CharSequence character sequence}),
 *       {@linkplain ParameterSpec parameters}, {@linkplain FieldSpec fields}, {@linkplain
 *       MethodSpec methods}, and {@linkplain TypeSpec types}.
 *   <li>{@code $S} escapes the value as a <em>string</em>, wraps it with double quotes, and emits
 *       that. For example, {@code 6" sandwich} is emitted {@code "6\" sandwich"}.
 *   <li>{@code $T} emits a <em>type</em> reference. Types will be imported if possible. Arguments
 *       for types may be {@linkplain Class classes}, {@linkplain javax.lang.model.type.TypeMirror
,*       type mirrors}, and {@linkplain javax.lang.model.element.Element elements}.
 *   <li>{@code $$} emits a dollar sign.
 *   <li>{@code $W} emits a space or a newline, depending on its position on the line. This prefers
 *       to wrap lines before 100 columns.
 *   <li>{@code $Z} acts as a zero-width space. This prefers to wrap lines before 100 columns.
 *   <li>{@code $>} increases the indentation level.
 *   <li>{@code $<} decreases the indentation level.
 *   <li>{@code $[} begins a statement. For multiline statements, every line after the first line
 *       is double-indented.
 *   <li>{@code $]} ends a statement.
 * </ul>
 */
public final class CodeBlock {
  private static final Pattern NAMED_ARGUMENT =
      Pattern.compile("\\$(?<argumentName>[\\w_]+):(?<typeChar>[\\w]).*");
  private static final Pattern LOWERCASE = Pattern.compile("[a-z]+[\\w_]*");

  /** A heterogeneous list containing string literals and value placeholders. */
  final List<String> formatParts;
  final List<Object> args;

  private CodeBlock(Builder builder) {
    this.formatParts = Util.immutableList(builder.formatParts);
    this.args = Util.immutableList(builder.args);
  }

  public boolean isEmpty() {
    return formatParts.isEmpty();
  }

  @Override public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null) return false;
    if (getClass() != o.getClass()) return false;
    return toString().equals(o.toString());
  }

  @Override public int hashCode() {
    return toString().hashCode();
  }

  @Override public String toString() {
    StringBuilder out = new StringBuilder();
    try {
      new CodeWriter(out).emit(this);
      return out.toString();
    } catch (IOException e) {
      throw new AssertionError();
    }
  }

  public static CodeBlock of(String format, Object... args) {
    return new Builder().add(format, args).build();
  }

  /**
   * Joins {@code codeBlocks} into a single {@link CodeBlock}, each separated by {@code separator}.
   * For example, joining {@code String s}, {@code Object o} and {@code int i} using {@code ", "}
   * would produce {@code String s, Object o, int i}.
   */
  public static CodeBlock join(Iterable<CodeBlock> codeBlocks, String separator) {
    return StreamSupport.stream(codeBlocks.spliterator(), false).collect(joining(separator));
  }

  /**
   * A {@link Collector} implementation that joins {@link CodeBlock} instances together into one
   * separated by {@code separator}. For example, joining {@code String s}, {@code Object o} and
   * {@code int i} using {@code ", "} would produce {@code String s, Object o, int i}.
   */
  public static Collector<CodeBlock, ?, CodeBlock> joining(String separator) {
    return Collector.of(
        () -> new CodeBlockJoiner(separator, builder()),
        CodeBlockJoiner::add,
        CodeBlockJoiner::merge,
        CodeBlockJoiner::join);
  }

  /**
   * A {@link Collector} implementation that joins {@link CodeBlock} instances together into one
   * separated by {@code separator}. For example, joining {@code String s}, {@code Object o} and
   * {@code int i} using {@code ", "} would produce {@code String s, Object o, int i}.
   */
  public static Collector<CodeBlock, ?, CodeBlock> joining(
      String separator, String prefix, String suffix) {
    Builder builder = builder().add("$N", prefix);
    return Collector.of(
        () -> new CodeBlockJoiner(separator, builder),
        CodeBlockJoiner::add,
        CodeBlockJoiner::merge,
        joiner -> {
            builder.add(CodeBlock.of("$N", suffix));
            return joiner.join();
        });
  }

  public static Builder builder() {
    return new Builder();
  }

  public Builder toBuilder() {
    Builder builder = new Builder();
    builder.formatParts.addAll(formatParts);
    builder.args.addAll(args);
    return builder;
  }

  public static final class Builder {
    final List<String> formatParts = new ArrayList<>();
    final List<Object> args = new ArrayList<>();

    private Builder() {
    }

    public boolean isEmpty() {
      return formatParts.isEmpty();
    }

    /**
     * Adds code using named arguments.
     *
     * <p>Named arguments specify their name after the '$' followed by : and the corresponding type
     * character. Argument names consist of characters in {@code a-z, A-Z, 0-9, and _} and must
     * start with a lowercase character.
     *
     * <p>For example, to refer to the type {@link java.lang.Integer} with the argument name {@code
     * clazz} use a format string containing {@code $clazz:T} and include the key {@code clazz} with
     * value {@code java.lang.Integer.class} in the argument map.
     */
    public Builder addNamed(String format, Map<String, ?> arguments) {
      int p = 0;

      for (String argument : arguments.keySet()) {
        checkArgument(LOWERCASE.matcher(argument).matches(),
            "argument '%s' must start with a lowercase character", argument);
      }

      while (p < format.length()) {
        int nextP = format.indexOf("$", p);
        if (nextP == -1) {
          formatParts.add(format.substring(p));
          break;
        }

        if (p != nextP) {
          formatParts.add(format.substring(p, nextP));
          p = nextP;
        }

        Matcher matcher = null;
        int colon = format.indexOf(':', p);
        if (colon != -1) {
          int endIndex = Math.min(colon + 2, format.length());
          matcher = NAMED_ARGUMENT.matcher(format.substring(p, endIndex));
        }
        if (matcher != null && matcher.lookingAt()) {
          String argumentName = matcher.group("argumentName");
          checkArgument(arguments.containsKey(argumentName), "Missing named argument for $%s",
              argumentName);
          char formatChar = matcher.group("typeChar").charAt(0);
          addArgument(format, formatChar, arguments.get(argumentName));
          formatParts.add("$" + formatChar);
          p += matcher.regionEnd();
        } else {
          checkArgument(p < format.length() - 1, "dangling $ at end");
          checkArgument(isNoArgPlaceholder(format.charAt(p + 1)),
              "unknown format $%s at %s in '%s'", format.charAt(p + 1), p + 1, format);
          formatParts.add(format.substring(p, p + 2));
          p += 2;
        }
      }

      return this;
    }

    /**
     * Add code with positional or relative arguments.
     *
     * <p>Relative arguments map 1:1 with the placeholders in the format string.
     *
     * <p>Positional arguments use an index after the placeholder to identify which argument index
     * to use. For example, for a literal to reference the 3rd argument: "$3L" (1 based index)
     *
     * <p>Mixing relative and positional arguments in a call to add is invalid and will result in an
     * error.
     */
    public Builder add(String format, Object... args) {
      boolean hasRelative = false;
      boolean hasIndexed = false;

      int relativeParameterCount = 0;
      int[] indexedParameterCount = new int[args.length];

      for (int p = 0; p < format.length(); ) {
        if (format.charAt(p) != '$') {
          int nextP = format.indexOf('$', p + 1);
          if (nextP == -1) nextP = format.length();
          formatParts.add(format.substring(p, nextP));
          p = nextP;
          continue;
        }

        p++; // '$'.

        // Consume zero or more digits, leaving 'c' as the first non-digit char after the '$'.
        int indexStart = p;
        char c;
        do {
          checkArgument(p < format.length(), "dangling format characters in '%s'", format);
          c = format.charAt(p++);
        } while (c >= '0' && c <= '9');
        int indexEnd = p - 1;

        // If 'c' doesn't take an argument, we're done.
        if (isNoArgPlaceholder(c)) {
          checkArgument(
              indexStart == indexEnd, "$$, $>, $<, $[, $], $W, and $Z may not have an index");
          formatParts.add("$" + c);
          continue;
        }

        // Find either the indexed argument, or the relative argument. (0-based).
        int index;
        if (indexStart < indexEnd) {
          index = Integer.parseInt(format.substring(indexStart, indexEnd)) - 1;
          hasIndexed = true;
          if (args.length > 0) {
            indexedParameterCount[index % args.length]++; // modulo is needed, checked below anyway
          }
        } else {
          index = relativeParameterCount;
          hasRelative = true;
          relativeParameterCount++;
        }

        checkArgument(index >= 0 && index < args.length,
            "index %d for '%s' not in range (received %s arguments)",
            index + 1, format.substring(indexStart - 1, indexEnd + 1), args.length);
        checkArgument(!hasIndexed || !hasRelative, "cannot mix indexed and positional parameters");

        addArgument(format, c, args[index]);

        formatParts.add("$" + c);
      }

      if (hasRelative) {
        checkArgument(relativeParameterCount >= args.length,
            "unused arguments: expected %s, received %s", relativeParameterCount, args.length);
      }
      if (hasIndexed) {
        List<String> unused = new ArrayList<>();
        for (int i = 0; i < args.length; i++) {
          if (indexedParameterCount[i] == 0) {
            unused.add("$" + (i + 1));
          }
        }
        String s = unused.size() == 1 ? "" : "s";
        checkArgument(unused.isEmpty(), "unused argument%s: %s", s, String.join(", ", unused));
      }
      return this;
    }

    private boolean isNoArgPlaceholder(char c) {
      return c == '$' || c == '>' || c == '<' || c == '[' || c == ']' || c == 'W' || c == 'Z';
    }

    private void addArgument(String format, char c, Object arg) {
      switch (c) {
        case 'N':
          this.args.add(argToName(arg));
          break;
        case 'L':
          this.args.add(argToLiteral(arg));
          break;
        case 'S':
          this.args.add(argToString(arg));
          break;
        case 'T':
          this.args.add(argToType(arg));
          break;
        default:
          throw new IllegalArgumentException(
              String.format("invalid format string: '%s'", format));
      }
    }

    private String argToName(Object o) {
      if (o instanceof CharSequence) return o.toString();
      if (o instanceof ParameterSpec) return ((ParameterSpec) o).name;
      if (o instanceof FieldSpec) return ((FieldSpec) o).name;
      if (o instanceof MethodSpec) return ((MethodSpec) o).name;
      if (o instanceof TypeSpec) return ((TypeSpec) o).name;
      throw new IllegalArgumentException("expected name but was " + o);
    }

    private Object argToLiteral(Object o) {
      return o;
    }

    private String argToString(Object o) {
      return o != null ? String.valueOf(o) : null;
    }

    private TypeName argToType(Object o) {
      if (o instanceof TypeName) return (TypeName) o;
      if (o instanceof TypeMirror) return TypeName.get((TypeMirror) o);
      if (o instanceof Element) return TypeName.get(((Element) o).asType());
      if (o instanceof Type) return TypeName.get((Type) o);
      throw new IllegalArgumentException("expected type but was " + o);
    }

    /**
     * @param controlFlow the control flow construct and its code, such as "if (foo == 5)".
     * Shouldn't contain braces or newline characters.
     */
    public Builder beginControlFlow(String controlFlow, Object... args) {
      add(controlFlow + " {\n", args);
      indent();
      return this;
    }

    /**
     * @param controlFlow the control flow construct and its code, such as "else if (foo == 10)".
     *     Shouldn't contain braces or newline characters.
     */
    public Builder nextControlFlow(String controlFlow, Object... args) {
      unindent();
      add("} " + controlFlow + " {\n", args);
      indent();
      return this;
    }

    public Builder endControlFlow() {
      unindent();
      add("}\n");
      return this;
    }

    /**
     * @param controlFlow the optional control flow construct and its code, such as
     *     "while(foo == 20)". Only used for "do/while" control flows.
     */
    public Builder endControlFlow(String controlFlow, Object... args) {
      unindent();
      add("} " + controlFlow + ";\n", args);
      return this;
    }

    public Builder addStatement(String format, Object... args) {
      add("$[");
      add(format, args);
      add(";\n$]");
      return this;
    }

    public Builder addStatement(CodeBlock codeBlock) {
      return addStatement("$L", codeBlock);
    }

    public Builder add(CodeBlock codeBlock) {
      formatParts.addAll(codeBlock.formatParts);
      args.addAll(codeBlock.args);
      return this;
    }

    public Builder indent() {
      this.formatParts.add("$>");
      return this;
    }

    public Builder unindent() {
      this.formatParts.add("$<");
      return this;
    }

    public Builder clear() {
      formatParts.clear();
      args.clear();
      return this;
    }

    public CodeBlock build() {
      return new CodeBlock(this);
    }
  }

  private static final class CodeBlockJoiner {
    private final String delimiter;
    private final Builder builder;
    private boolean first = true;

    CodeBlockJoiner(String delimiter, Builder builder) {
      this.delimiter = delimiter;
      this.builder = builder;
    }

    CodeBlockJoiner add(CodeBlock codeBlock) {
      if (!first) {
        builder.add(delimiter);
      }
      first = false;

      builder.add(codeBlock);
      return this;
    }

    CodeBlockJoiner merge(CodeBlockJoiner other) {
      CodeBlock otherBlock = other.builder.build();
      if (!otherBlock.isEmpty()) {
        add(otherBlock);
      }
      return this;
    }

    CodeBlock join() {
      return builder.build();
    }
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/CodeWriter.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Modifier;

import static com.squareup.javapoet.Util.checkArgument;
import static com.squareup.javapoet.Util.checkNotNull;
import static com.squareup.javapoet.Util.checkState;
import static com.squareup.javapoet.Util.stringLiteralWithDoubleQuotes;
import static java.lang.String.join;

/**
 * Converts a {@link JavaFile} to a string suitable to both human- and javac-consumption. This
 * honors imports, indentation, and deferred variable names.
 */
final class CodeWriter {
  /** Sentinel value that indicates that no user-provided package has been set. */
  private static final String NO_PACKAGE = new String();
  private static final Pattern LINE_BREAKING_PATTERN = Pattern.compile("\\R");

  private final String indent;
  private final LineWrapper out;
  private int indentLevel;

  private boolean javadoc = false;
  private boolean comment = false;
  private String packageName = NO_PACKAGE;
  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;

  /**
   * When emitting a statement, this is the line of the statement currently being written. The first
   * line of a statement is indented normally and subsequent wrapped lines are double-indented. This
   * is -1 when the currently-written line isn't part of a statement.
   */
  int statementLine = -1;

  CodeWriter(Appendable out) {
    this(out, "  ", Collections.emptySet(), 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,
      Map<String, ClassName> importedTypes,
      Set<String> staticImports,
      Set<String> alwaysQualify) {
    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('.')));
    }
  }

  public Map<String, ClassName> importedTypes() {
    return importedTypes;
  }

  public CodeWriter indent() {
    return indent(1);
  }

  public CodeWriter indent(int levels) {
    indentLevel += levels;
    return this;
  }

  public CodeWriter unindent() {
    return unindent(1);
  }

  public CodeWriter unindent(int levels) {
    checkArgument(indentLevel - levels >= 0, "cannot unindent %s from %s", levels, indentLevel);
    indentLevel -= levels;
    return this;
  }

  public CodeWriter pushPackage(String packageName) {
    checkState(this.packageName == NO_PACKAGE, "package already set: %s", this.packageName);
    this.packageName = checkNotNull(packageName, "packageName == null");
    return this;
  }

  public CodeWriter popPackage() {
    checkState(this.packageName != NO_PACKAGE, "package not set");
    this.packageName = NO_PACKAGE;
    return this;
  }

  public CodeWriter pushType(TypeSpec type) {
    this.typeSpecStack.add(type);
    return this;
  }

  public CodeWriter popType() {
    this.typeSpecStack.remove(typeSpecStack.size() - 1);
    return this;
  }

  public void emitComment(CodeBlock codeBlock) throws IOException {
    trailingNewline = true; // Force the '//' prefix for the comment.
    comment = true;
    try {
      emit(codeBlock);
      emit("\n");
    } finally {
      comment = false;
    }
  }

  public void emitJavadoc(CodeBlock javadocCodeBlock) throws IOException {
    if (javadocCodeBlock.isEmpty()) return;

    emit("/**\n");
    javadoc = true;
    try {
      emit(javadocCodeBlock, true);
    } finally {
      javadoc = false;
    }
    emit(" */\n");
  }

  public void emitAnnotations(List<AnnotationSpec> annotations, boolean inline) throws IOException {
    for (AnnotationSpec annotationSpec : annotations) {
      annotationSpec.emit(this, inline);
      emit(inline ? " " : "\n");
    }
  }

  /**
   * Emits {@code modifiers} in the standard order. Modifiers in {@code implicitModifiers} will not
   * be emitted.
   */
  public void emitModifiers(Set<Modifier> modifiers, Set<Modifier> implicitModifiers)
      throws IOException {
    if (modifiers.isEmpty()) return;
    for (Modifier modifier : EnumSet.copyOf(modifiers)) {
      if (implicitModifiers.contains(modifier)) continue;
      emitAndIndent(modifier.name().toLowerCase(Locale.US));
      emitAndIndent(" ");
    }
  }

  public void emitModifiers(Set<Modifier> modifiers) throws IOException {
    emitModifiers(modifiers, Collections.emptySet());
  }

  /**
   * Emit type variables with their bounds. This should only be used when declaring type variables;
   * everywhere else bounds are omitted.
   */
  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) {
      if (!firstTypeVariable) emit(", ");
      emitAnnotations(typeVariable.annotations, true);
      emit("$L", typeVariable.name);
      boolean firstBound = true;
      for (TypeName bound : typeVariable.bounds) {
        emit(firstBound ? " extends $T" : " & $T", bound);
        firstBound = false;
      }
      firstTypeVariable = false;
    }
    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);
  }

  public CodeWriter emit(String format, Object... args) throws IOException {
    return emit(CodeBlock.of(format, args));
  }

  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();
    while (partIterator.hasNext()) {
      String part = partIterator.next();
      switch (part) {
        case "$L":
          emitLiteral(codeBlock.args.get(a++));
          break;

        case "$N":
          emitAndIndent((String) codeBlock.args.get(a++));
          break;

        case "$S":
          String string = (String) codeBlock.args.get(a++);
          // Emit null as a literal null: no quotes.
          emitAndIndent(string != null
              ? stringLiteralWithDoubleQuotes(string, indent)
              : "null");
          break;

        case "$T":
          TypeName typeName = (TypeName) codeBlock.args.get(a++);
          // defer "typeName.emit(this)" if next format part will be handled by the default case
          if (typeName instanceof ClassName && partIterator.hasNext()) {
            if (!codeBlock.formatParts.get(partIterator.nextIndex()).startsWith("$")) {
              ClassName candidate = (ClassName) typeName;
              if (staticImportClassNames.contains(candidate.canonicalName)) {
                checkState(deferredTypeName == null, "pending type for static import?!");
                deferredTypeName = candidate;
                break;
              }
            }
          }
          typeName.emit(this);
          break;

        case "$$":
          emitAndIndent("$");
          break;

        case "$>":
          indent();
          break;

        case "$<":
          unindent();
          break;

        case "$[":
          checkState(statementLine == -1, "statement enter $[ followed by statement enter $[");
          statementLine = 0;
          break;

        case "$]":
          checkState(statementLine != -1, "statement exit $] has no matching statement enter $[");
          if (statementLine > 0) {
            unindent(2); // End a multi-line statement. Decrease the indentation level.
          }
          statementLine = -1;
          break;

        case "$W":
          out.wrappingSpace(indentLevel + 2);
          break;

        case "$Z":
          out.zeroWidthSpace(indentLevel + 2);
          break;

        default:
          // handle deferred type
          if (deferredTypeName != null) {
            if (part.startsWith(".")) {
              if (emitStaticImportMember(deferredTypeName.canonicalName, part)) {
                // okay, static import hit and all was emitted, so clean-up and jump to next part
                deferredTypeName = null;
                break;
              }
            }
            deferredTypeName.emit(this);
            deferredTypeName = null;
          }
          emitAndIndent(part);
          break;
      }
    }
    if (ensureTrailingNewline && out.lastChar() != '\n') {
      emit("\n");
    }
    return this;
  }

  public CodeWriter emitWrappingSpace() throws IOException {
    out.wrappingSpace(indentLevel + 2);
    return this;
  }

  private static String extractMemberName(String part) {
    checkArgument(Character.isJavaIdentifierStart(part.charAt(0)), "not an identifier: %s", part);
    for (int i = 1; i <= part.length(); i++) {
      if (!SourceVersion.isIdentifier(part.substring(0, i))) {
        return part.substring(0, i - 1);
      }
    }
    return part;
  }

  private boolean emitStaticImportMember(String canonical, String part) throws IOException {
    String partWithoutLeadingDot = part.substring(1);
    if (partWithoutLeadingDot.isEmpty()) return false;
    char first = partWithoutLeadingDot.charAt(0);
    if (!Character.isJavaIdentifierStart(first)) return false;
    String explicit = canonical + "." + extractMemberName(partWithoutLeadingDot);
    String wildcard = canonical + ".*";
    if (staticImports.contains(explicit) || staticImports.contains(wildcard)) {
      emitAndIndent(partWithoutLeadingDot);
      return true;
    }
    return false;
  }

  private void emitLiteral(Object o) throws IOException {
    if (o instanceof TypeSpec) {
      TypeSpec typeSpec = (TypeSpec) o;
      typeSpec.emit(this, null, Collections.emptySet());
    } else if (o instanceof AnnotationSpec) {
      AnnotationSpec annotationSpec = (AnnotationSpec) o;
      annotationSpec.emit(this, true);
    } else if (o instanceof CodeBlock) {
      CodeBlock codeBlock = (CodeBlock) o;
      emit(codeBlock);
    } else {
      emitAndIndent(String.valueOf(o));
    }
  }

  /**
   * Returns the best name to identify {@code className} with in the current context. This uses the
   * available imports and the current scope to find the shortest name available. It does not honor
   * 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;
    for (ClassName c = className; c != null; c = c.enclosingClassName()) {
      ClassName resolved = resolve(c.simpleName());
      nameResolved = resolved != null;

      if (resolved != null && Objects.equals(resolved.canonicalName, c.canonicalName)) {
        int suffixOffset = c.simpleNames().size() - 1;
        return join(".", className.simpleNames().subList(
            suffixOffset, className.simpleNames().size()));
      }
    }

    // If the name resolved but wasn't a match, we're stuck with the fully qualified name.
    if (nameResolved) {
      return className.canonicalName;
    }

    // If the class is in the same package, we're done.
    if (Objects.equals(packageName, className.packageName())) {
      referencedNames.add(topLevelSimpleName);
      return join(".", className.simpleNames());
    }

    // We'll have to use the fully-qualified name. Mark the type as importable for a future pass.
    if (!javadoc) {
      importableType(className);
    }

    return className.canonicalName;
  }

  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();
    ClassName replaced = importableTypes.put(simpleName, topLevelClassName);
    if (replaced != null) {
      importableTypes.put(simpleName, replaced); // On collision, prefer the first inserted.
    }
  }

  /**
   * Returns the class referenced by {@code simpleName}, using the current nesting context and
   * imports.
   */
  // TODO(jwilson): also honor superclass members when resolving names.
  private ClassName resolve(String simpleName) {
    // 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);
      }
    }

    // Match the top-level class.
    if (typeSpecStack.size() > 0 && Objects.equals(typeSpecStack.get(0).name, simpleName)) {
      return ClassName.get(packageName, simpleName);
    }

    // Match an imported type.
    ClassName importedType = importedTypes.get(simpleName);
    if (importedType != null) return importedType;

    // No match.
    return null;
  }

  /** Returns the class named {@code simpleName} when nested in the class at {@code stackDepth}. */
  private ClassName stackClassName(int stackDepth, String simpleName) {
    ClassName className = ClassName.get(packageName, typeSpecStack.get(0).name);
    for (int i = 1; i <= stackDepth; i++) {
      className = className.nestedClass(typeSpecStack.get(i).name);
    }
    return className.nestedClass(simpleName);
  }

  /**
   * Emits {@code s} with indentation as required. It's important that all code that writes to
   * {@link #out} does it through here, since we emit indentation lazily in order to avoid
   * unnecessary trailing whitespace.
   */
  CodeWriter emitAndIndent(String s) throws IOException {
    boolean first = true;
    for (String line : LINE_BREAKING_PATTERN.split(s, -1)) {
      // Emit a newline character. Make sure blank lines in Javadoc & comments look good.
      if (!first) {
        if ((javadoc || comment) && trailingNewline) {
          emitIndentation();
          out.append(javadoc ? " *" : "//");
        }
        out.append("\n");
        trailingNewline = true;
        if (statementLine != -1) {
          if (statementLine == 0) {
            indent(2); // Begin multiple-line statement. Increase the indentation level.
          }
          statementLine++;
        }
      }

      first = false;
      if (line.isEmpty()) continue; // Don't indent empty lines.

      // Emit indentation and comment prefix if necessary.
      if (trailingNewline) {
        emitIndentation();
        if (javadoc) {
          out.append(" * ");
        } else if (comment) {
          out.append("// ");
        }
      }

      out.append(line);
      trailingNewline = false;
    }
    return this;
  }

  private void emitIndentation() throws IOException {
    for (int j = 0; j < indentLevel; j++) {
      out.append(indent);
    }
  }

  /**
   * Returns the types that should have been imported for this code. If there were any simple name
   * collisions, that type's first use is imported.
   */
  Map<String, ClassName> suggestedImports() {
    Map<String, ClassName> result = new LinkedHashMap<>(importableTypes);
    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;
    }
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/FieldSpec.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Modifier;

import static com.squareup.javapoet.Util.checkArgument;
import static com.squareup.javapoet.Util.checkNotNull;
import static com.squareup.javapoet.Util.checkState;

/** A generated field declaration. */
public final class FieldSpec {
  public final TypeName type;
  public final String name;
  public final CodeBlock javadoc;
  public final List<AnnotationSpec> annotations;
  public final Set<Modifier> modifiers;
  public final CodeBlock initializer;

  private FieldSpec(Builder builder) {
    this.type = checkNotNull(builder.type, "type == null");
    this.name = checkNotNull(builder.name, "name == null");
    this.javadoc = builder.javadoc.build();
    this.annotations = Util.immutableList(builder.annotations);
    this.modifiers = Util.immutableSet(builder.modifiers);
    this.initializer = (builder.initializer == null)
        ? CodeBlock.builder().build()
        : builder.initializer;
  }

  public boolean hasModifier(Modifier modifier) {
    return modifiers.contains(modifier);
  }

  void emit(CodeWriter codeWriter, Set<Modifier> implicitModifiers) throws IOException {
    codeWriter.emitJavadoc(javadoc);
    codeWriter.emitAnnotations(annotations, false);
    codeWriter.emitModifiers(modifiers, implicitModifiers);
    codeWriter.emit("$T $L", type, name);
    if (!initializer.isEmpty()) {
      codeWriter.emit(" = ");
      codeWriter.emit(initializer);
    }
    codeWriter.emit(";\n");
  }

  @Override public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null) return false;
    if (getClass() != o.getClass()) return false;
    return toString().equals(o.toString());
  }

  @Override public int hashCode() {
    return toString().hashCode();
  }

  @Override public String toString() {
    StringBuilder out = new StringBuilder();
    try {
      CodeWriter codeWriter = new CodeWriter(out);
      emit(codeWriter, Collections.emptySet());
      return out.toString();
    } catch (IOException e) {
      throw new AssertionError();
    }
  }

  public static Builder builder(TypeName type, String name, Modifier... modifiers) {
    checkNotNull(type, "type == null");
    checkArgument(SourceVersion.isName(name), "not a valid name: %s", name);
    return new Builder(type, name)
        .addModifiers(modifiers);
  }

  public static Builder builder(Type type, String name, Modifier... modifiers) {
    return builder(TypeName.get(type), name, modifiers);
  }

  public Builder toBuilder() {
    Builder builder = new Builder(type, name);
    builder.javadoc.add(javadoc);
    builder.annotations.addAll(annotations);
    builder.modifiers.addAll(modifiers);
    builder.initializer = initializer.isEmpty() ? null : initializer;
    return builder;
  }

  public static final class Builder {
    private final TypeName type;
    private final String name;

    private final CodeBlock.Builder javadoc = CodeBlock.builder();
    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;
    }

    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) {
        this.annotations.add(annotationSpec);
      }
      return this;
    }

    public Builder addAnnotation(AnnotationSpec annotationSpec) {
      this.annotations.add(annotationSpec);
      return this;
    }

    public Builder addAnnotation(ClassName annotation) {
      this.annotations.add(AnnotationSpec.builder(annotation).build());
      return this;
    }

    public Builder addAnnotation(Class<?> annotation) {
      return addAnnotation(ClassName.get(annotation));
    }

    public Builder addModifiers(Modifier... modifiers) {
      Collections.addAll(this.modifiers, modifiers);
      return this;
    }

    public Builder initializer(String format, Object... args) {
      return initializer(CodeBlock.of(format, args));
    }

    public Builder initializer(CodeBlock codeBlock) {
      checkState(this.initializer == null, "initializer was already set");
      this.initializer = checkNotNull(codeBlock, "codeBlock == null");
      return this;
    }

    public FieldSpec build() {
      return new FieldSpec(this);
    }
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/JavaFile.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
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;
import java.util.TreeSet;
import javax.annotation.processing.Filer;
import javax.lang.model.element.Element;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;

import static com.squareup.javapoet.Util.checkArgument;
import static com.squareup.javapoet.Util.checkNotNull;
import static java.nio.charset.StandardCharsets.UTF_8;

/** A Java file containing a single top level class. */
public final class JavaFile {
  private static final Appendable NULL_APPENDABLE = new Appendable() {
    @Override public Appendable append(CharSequence charSequence) {
      return this;
    }
    @Override public Appendable append(CharSequence charSequence, int start, int end) {
      return this;
    }
    @Override public Appendable append(char c) {
      return this;
    }
  };

  public final CodeBlock fileComment;
  public final String packageName;
  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) {
    this.fileComment = builder.fileComment.build();
    this.packageName = builder.packageName;
    this.typeSpec = builder.typeSpec;
    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
    );
    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);
    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;
    if (!packageName.isEmpty()) {
      for (String packageComponent : packageName.split("\\.")) {
        outputDirectory = outputDirectory.resolve(packageComponent);
      }
      Files.createDirectories(outputDirectory);
    }

    Path outputPath = outputDirectory.resolve(typeSpec.name + ".java");
    try (Writer writer = new OutputStreamWriter(Files.newOutputStream(outputPath), charset)) {
      writeTo(writer);
    }

    return outputPath;
  }

  /** Writes this to {@code directory} as UTF-8 using the standard directory structure. */
  public void writeTo(File directory) throws IOException {
    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()
        ? typeSpec.name
        : packageName + "." + typeSpec.name;
    List<Element> originatingElements = typeSpec.originatingElements;
    JavaFileObject filerSourceFile = filer.createSourceFile(fileName,
        originatingElements.toArray(new Element[originatingElements.size()]));
    try (Writer writer = filerSourceFile.openWriter()) {
      writeTo(writer);
    } catch (Exception e) {
      try {
        filerSourceFile.delete();
      } catch (Exception ignored) {
      }
      throw e;
    }
  }

  private void emit(CodeWriter codeWriter) throws IOException {
    codeWriter.pushPackage(packageName);

    if (!fileComment.isEmpty()) {
      codeWriter.emitComment(fileComment);
    }

    if (!packageName.isEmpty()) {
      codeWriter.emit("package $L;\n", packageName);
      codeWriter.emit("\n");
    }

    if (!staticImports.isEmpty()) {
      for (String signature : staticImports) {
        codeWriter.emit("import static $L;\n", signature);
      }
      codeWriter.emit("\n");
    }

    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;
      }
      codeWriter.emit("import $L;\n", className.withoutAnnotations());
      importedTypesCount++;
    }

    if (importedTypesCount > 0) {
      codeWriter.emit("\n");
    }

    typeSpec.emit(codeWriter, null, Collections.emptySet());

    codeWriter.popPackage();
  }

  @Override public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null) return false;
    if (getClass() != o.getClass()) return false;
    return toString().equals(o.toString());
  }

  @Override public int hashCode() {
    return toString().hashCode();
  }

  @Override public String toString() {
    try {
      StringBuilder result = new StringBuilder();
      writeTo(result);
      return result.toString();
    } catch (IOException e) {
      throw new AssertionError();
    }
  }

  public JavaFileObject toJavaFileObject() {
    URI uri = URI.create((packageName.isEmpty()
        ? typeSpec.name
        : packageName.replace('.', '/') + '/' + typeSpec.name)
        + Kind.SOURCE.extension);
    return new SimpleJavaFileObject(uri, Kind.SOURCE) {
      private final long lastModified = System.currentTimeMillis();
      @Override public String getCharContent(boolean ignoreEncodingErrors) {
        return JavaFile.this.toString();
      }
      @Override public InputStream openInputStream() throws IOException {
        return new ByteArrayInputStream(getCharContent(true).getBytes(UTF_8));
      }
      @Override public long getLastModified() {
        return lastModified;
      }
    };
  }

  public static Builder builder(String packageName, TypeSpec typeSpec) {
    checkNotNull(packageName, "packageName == null");
    checkNotNull(typeSpec, "typeSpec == null");
    return new Builder(packageName, typeSpec);
  }

  public Builder toBuilder() {
    Builder builder = new Builder(packageName, typeSpec);
    builder.fileComment.add(fileComment);
    builder.skipJavaLangImports = skipJavaLangImports;
    builder.indent = indent;
    return builder;
  }

  public static final class Builder {
    private final String packageName;
    private final TypeSpec typeSpec;
    private final CodeBlock.Builder fileComment = CodeBlock.builder();
    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;
    }

    public Builder addFileComment(String format, Object... args) {
      this.fileComment.add(format, args);
      return this;
    }

    public Builder addStaticImport(Enum<?> constant) {
      return addStaticImport(ClassName.get(constant.getDeclaringClass()), constant.name());
    }

    public Builder addStaticImport(Class<?> clazz, String... names) {
      return addStaticImport(ClassName.get(clazz), names);
    }

    public Builder addStaticImport(ClassName className, String... names) {
      checkArgument(className != null, "className == null");
      checkArgument(names != null, "names == null");
      checkArgument(names.length > 0, "names array is empty");
      for (String name : names) {
        checkArgument(name != null, "null entry in names array: %s", Arrays.toString(names));
        staticImports.add(className.canonicalName + "." + name);
      }
      return this;
    }

    /**
     * Call this to omit imports for classes in {@code java.lang}, such as {@code java.lang.String}.
     *
     * <p>By default, JavaPoet explicitly imports types in {@code java.lang} to defend against
     * naming conflicts. Suppose an (ill-advised) class is named {@code com.example.String}. When
     * {@code java.lang} imports are skipped, generated code in {@code com.example} that references
     * {@code java.lang.String} will get {@code com.example.String} instead.
     */
    public Builder skipJavaLangImports(boolean skipJavaLangImports) {
      this.skipJavaLangImports = skipJavaLangImports;
      return this;
    }

    public Builder indent(String indent) {
      this.indent = indent;
      return this;
    }

    public JavaFile build() {
      return new JavaFile(this);
    }
  }
}


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

import java.io.IOException;

import static com.squareup.javapoet.Util.checkNotNull;

/**
 * Implements soft line wrapping on an appendable. To use, append characters using {@link #append}
 * or soft-wrapping spaces using {@link #wrappingSpace}.
 */
final class LineWrapper {
  private final RecordingAppendable out;
  private final String indent;
  private final int columnLimit;
  private boolean closed;

  /** Characters written since the last wrapping space that haven't yet been flushed. */
  private final StringBuilder buffer = new StringBuilder();

  /** The number of characters since the most recent newline. Includes both out and the buffer. */
  private int column = 0;

  /**
   * -1 if we have no buffering; otherwise the number of {@code indent}s to write after wrapping.
   */
  private int indentLevel = -1;

  /**
   * Null if we have no buffering; otherwise the type to pass to the next call to {@link #flush}.
   */
  private FlushType nextFlush;

  LineWrapper(Appendable out, String indent, int columnLimit) {
    checkNotNull(out, "out == null");
    this.out = new RecordingAppendable(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");

    if (nextFlush != null) {
      int nextNewline = s.indexOf('\n');

      // If s doesn't cause the current line to cross the limit, buffer it and return. We'll decide
      // whether or not we have to wrap it later.
      if (nextNewline == -1 && column + s.length() <= columnLimit) {
        buffer.append(s);
        column += s.length();
        return;
      }

      // Wrap if appending s would overflow the current line.
      boolean wrap = nextNewline == -1 || column + nextNewline > columnLimit;
      flush(wrap ? FlushType.WRAP : nextFlush);
    }

    out.append(s);
    int lastNewline = s.lastIndexOf('\n');
    column = lastNewline != -1
        ? s.length() - lastNewline - 1
        : column + s.length();
  }

  /** Emit either a space or a newline character. */
  void wrappingSpace(int indentLevel) throws IOException {
    if (closed) throw new IllegalStateException("closed");

    if (this.nextFlush != null) flush(nextFlush);
    column++; // Increment the column even though the space is deferred to next call to flush().
    this.nextFlush = FlushType.SPACE;
    this.indentLevel = indentLevel;
  }

  /** Emit a newline character if the line will exceed it's limit, otherwise do nothing. */
  void zeroWidthSpace(int indentLevel) throws IOException {
    if (closed) throw new IllegalStateException("closed");

    if (column == 0) return;
    if (this.nextFlush != null) flush(nextFlush);
    this.nextFlush = FlushType.EMPTY;
    this.indentLevel = indentLevel;
  }

  /** Flush any outstanding text and forbid future writes to this line wrapper. */
  void close() throws IOException {
    if (nextFlush != null) flush(nextFlush);
    closed = true;
  }

  /** Write the space followed by any buffered text that follows it. */
  private void flush(FlushType flushType) throws IOException {
    switch (flushType) {
      case WRAP:
        out.append('\n');
        for (int i = 0; i < indentLevel; i++) {
          out.append(indent);
        }
        column = indentLevel * indent.length();
        column += buffer.length();
        break;
      case SPACE:
        out.append(' ');
        break;
      case EMPTY:
        break;
      default:
        throw new IllegalArgumentException("Unknown FlushType: " + flushType);
    }

    out.append(buffer);
    buffer.delete(0, buffer.length());
    indentLevel = -1;
    nextFlush = null;
  }

  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);
    }
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/MethodSpec.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.Types;

import static com.squareup.javapoet.Util.checkArgument;
import static com.squareup.javapoet.Util.checkNotNull;
import static com.squareup.javapoet.Util.checkState;

/** A generated constructor or method declaration. */
public final class MethodSpec {
  static final String CONSTRUCTOR = "<init>";

  public final String name;
  public final CodeBlock javadoc;
  public final List<AnnotationSpec> annotations;
  public final Set<Modifier> modifiers;
  public final List<TypeVariableName> typeVariables;
  public final TypeName returnType;
  public final List<ParameterSpec> parameters;
  public final boolean varargs;
  public final List<TypeName> exceptions;
  public final CodeBlock code;
  public final CodeBlock defaultValue;

  private MethodSpec(Builder builder) {
    CodeBlock code = builder.code.build();
    checkArgument(code.isEmpty() || !builder.modifiers.contains(Modifier.ABSTRACT),
        "abstract method %s cannot have code", builder.name);
    checkArgument(!builder.varargs || lastParameterIsArray(builder.parameters),
        "last parameter of varargs method %s must be an array", builder.name);

    this.name = checkNotNull(builder.name, "name == null");
    this.javadoc = builder.javadoc.build();
    this.annotations = Util.immutableList(builder.annotations);
    this.modifiers = Util.immutableSet(builder.modifiers);
    this.typeVariables = Util.immutableList(builder.typeVariables);
    this.returnType = builder.returnType;
    this.parameters = Util.immutableList(builder.parameters);
    this.varargs = builder.varargs;
    this.exceptions = Util.immutableList(builder.exceptions);
    this.defaultValue = builder.defaultValue;
    this.code = code;
  }

  private boolean lastParameterIsArray(List<ParameterSpec> parameters) {
    return !parameters.isEmpty()
        && TypeName.asArray((parameters.get(parameters.size() - 1).type)) != null;
  }

  void emit(CodeWriter codeWriter, String enclosingName, Set<Modifier> implicitModifiers)
      throws IOException {
    codeWriter.emitJavadoc(javadocWithParameters());
    codeWriter.emitAnnotations(annotations, false);
    codeWriter.emitModifiers(modifiers, implicitModifiers);

    if (!typeVariables.isEmpty()) {
      codeWriter.emitTypeVariables(typeVariables);
      codeWriter.emit(" ");
    }

    if (isConstructor()) {
      codeWriter.emit("$L($Z", enclosingName);
    } else {
      codeWriter.emit("$T $L($Z", returnType, name);
    }

    boolean firstParameter = true;
    for (Iterator<ParameterSpec> i = parameters.iterator(); i.hasNext(); ) {
      ParameterSpec parameter = i.next();
      if (!firstParameter) codeWriter.emit(",").emitWrappingSpace();
      parameter.emit(codeWriter, !i.hasNext() && varargs);
      firstParameter = false;
    }

    codeWriter.emit(")");

    if (defaultValue != null && !defaultValue.isEmpty()) {
      codeWriter.emit(" default ");
      codeWriter.emit(defaultValue);
    }

    if (!exceptions.isEmpty()) {
      codeWriter.emitWrappingSpace().emit("throws");
      boolean firstException = true;
      for (TypeName exception : exceptions) {
        if (!firstException) codeWriter.emit(",");
        codeWriter.emitWrappingSpace().emit("$T", exception);
        firstException = false;
      }
    }

    if (hasModifier(Modifier.ABSTRACT)) {
      codeWriter.emit(";\n");
    } else if (hasModifier(Modifier.NATIVE)) {
      // Code is allowed to support stuff like GWT JSNI.
      codeWriter.emit(code);
      codeWriter.emit(";\n");
    } else {
      codeWriter.emit(" {\n");

      codeWriter.indent();
      codeWriter.emit(code, true);
      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) {
    return modifiers.contains(modifier);
  }

  public boolean isConstructor() {
    return name.equals(CONSTRUCTOR);
  }

  @Override public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null) return false;
    if (getClass() != o.getClass()) return false;
    return toString().equals(o.toString());
  }

  @Override public int hashCode() {
    return toString().hashCode();
  }

  @Override public String toString() {
    StringBuilder out = new StringBuilder();
    try {
      CodeWriter codeWriter = new CodeWriter(out);
      emit(codeWriter, "Constructor", Collections.emptySet());
      return out.toString();
    } catch (IOException e) {
      throw new AssertionError();
    }
  }

  public static Builder methodBuilder(String name) {
    return new Builder(name);
  }

  public static Builder constructorBuilder() {
    return new Builder(CONSTRUCTOR);
  }

  /**
   * Returns a new method spec builder that overrides {@code method}.
   *
   * <p>This will copy its visibility modifiers, type parameters, return type, name, parameters, and
   * throws declarations. An {@link Override} annotation will be added.
   *
   * <p>Note that in JavaPoet 1.2 through 1.7 this method retained annotations from the method and
   * parameters of the overridden method. Since JavaPoet 1.8 annotations must be added separately.
   */
  public static Builder overriding(ExecutableElement method) {
    checkNotNull(method, "method == null");

    Element enclosingClass = method.getEnclosingElement();
    if (enclosingClass.getModifiers().contains(Modifier.FINAL)) {
      throw new IllegalArgumentException("Cannot override method on final class " + enclosingClass);
    }

    Set<Modifier> modifiers = method.getModifiers();
    if (modifiers.contains(Modifier.PRIVATE)
        || modifiers.contains(Modifier.FINAL)
        || modifiers.contains(Modifier.STATIC)) {
      throw new IllegalArgumentException("cannot override method with modifiers: " + modifiers);
    }

    String methodName = method.getSimpleName().toString();
    MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(methodName);

    methodBuilder.addAnnotation(Override.class);

    modifiers = new LinkedHashSet<>(modifiers);
    modifiers.remove(Modifier.ABSTRACT);
    modifiers.remove(Modifier.DEFAULT);
    methodBuilder.addModifiers(modifiers);

    for (TypeParameterElement typeParameterElement : method.getTypeParameters()) {
      TypeVariable var = (TypeVariable) typeParameterElement.asType();
      methodBuilder.addTypeVariable(TypeVariableName.get(var));
    }

    methodBuilder.returns(TypeName.get(method.getReturnType()));
    methodBuilder.addParameters(ParameterSpec.parametersOf(method));
    methodBuilder.varargs(method.isVarArgs());

    for (TypeMirror thrownType : method.getThrownTypes()) {
      methodBuilder.addException(TypeName.get(thrownType));
    }

    return methodBuilder;
  }

  /**
   * Returns a new method spec builder that overrides {@code method} as a member of {@code
   * enclosing}. This will resolve type parameters: for example overriding {@link
   * Comparable#compareTo} in a type that implements {@code Comparable<Movie>}, the {@code T}
   * parameter will be resolved to {@code Movie}.
   *
   * <p>This will copy its visibility modifiers, type parameters, return type, name, parameters, and
   * throws declarations. An {@link Override} annotation will be added.
   *
   * <p>Note that in JavaPoet 1.2 through 1.7 this method retained annotations from the method and
   * parameters of the overridden method. Since JavaPoet 1.8 annotations must be added separately.
   */
  public static Builder overriding(
      ExecutableElement method, DeclaredType enclosing, Types types) {
    ExecutableType executableType = (ExecutableType) types.asMemberOf(enclosing, method);
    List<? extends TypeMirror> resolvedParameterTypes = executableType.getParameterTypes();
    List<? extends TypeMirror> resolvedThrownTypes = executableType.getThrownTypes();
    TypeMirror resolvedReturnType = executableType.getReturnType();

    Builder builder = overriding(method);
    builder.returns(TypeName.get(resolvedReturnType));
    for (int i = 0, size = builder.parameters.size(); i < size; i++) {
      ParameterSpec parameter = builder.parameters.get(i);
      TypeName type = TypeName.get(resolvedParameterTypes.get(i));
      builder.parameters.set(i, parameter.toBuilder(type, parameter.name).build());
    }
    builder.exceptions.clear();
    for (int i = 0, size = resolvedThrownTypes.size(); i < size; i++) {
      builder.addException(TypeName.get(resolvedThrownTypes.get(i)));
    }

    return builder;
  }

  public Builder toBuilder() {
    Builder builder = new Builder(name);
    builder.javadoc.add(javadoc);
    builder.annotations.addAll(annotations);
    builder.modifiers.addAll(modifiers);
    builder.typeVariables.addAll(typeVariables);
    builder.returnType = returnType;
    builder.parameters.addAll(parameters);
    builder.exceptions.addAll(exceptions);
    builder.code.add(code);
    builder.varargs = varargs;
    builder.defaultValue = defaultValue;
    return builder;
  }

  public static final class Builder {
    private String name;

    private final CodeBlock.Builder javadoc = CodeBlock.builder();
    private TypeName returnType;
    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) {
      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) {
        this.annotations.add(annotationSpec);
      }
      return this;
    }

    public Builder addAnnotation(AnnotationSpec annotationSpec) {
      this.annotations.add(annotationSpec);
      return this;
    }

    public Builder addAnnotation(ClassName annotation) {
      this.annotations.add(AnnotationSpec.builder(annotation).build());
      return this;
    }

    public Builder addAnnotation(Class<?> annotation) {
      return addAnnotation(ClassName.get(annotation));
    }

    public Builder addModifiers(Modifier... modifiers) {
      checkNotNull(modifiers, "modifiers == null");
      Collections.addAll(this.modifiers, modifiers);
      return this;
    }

    public Builder addModifiers(Iterable<Modifier> modifiers) {
      checkNotNull(modifiers, "modifiers == null");
      for (Modifier modifier : modifiers) {
        this.modifiers.add(modifier);
      }
      return this;
    }

    public Builder addTypeVariables(Iterable<TypeVariableName> typeVariables) {
      checkArgument(typeVariables != null, "typeVariables == null");
      for (TypeVariableName typeVariable : typeVariables) {
        this.typeVariables.add(typeVariable);
      }
      return this;
    }

    public Builder addTypeVariable(TypeVariableName typeVariable) {
      typeVariables.add(typeVariable);
      return this;
    }

    public Builder returns(TypeName returnType) {
      checkState(!name.equals(CONSTRUCTOR), "constructor cannot have return type.");
      this.returnType = returnType;
      return this;
    }

    public Builder returns(Type returnType) {
      return returns(TypeName.get(returnType));
    }

    public Builder addParameters(Iterable<ParameterSpec> parameterSpecs) {
      checkArgument(parameterSpecs != null, "parameterSpecs == null");
      for (ParameterSpec parameterSpec : parameterSpecs) {
        this.parameters.add(parameterSpec);
      }
      return this;
    }

    public Builder addParameter(ParameterSpec parameterSpec) {
      this.parameters.add(parameterSpec);
      return this;
    }

    public Builder addParameter(TypeName type, String name, Modifier... modifiers) {
      return addParameter(ParameterSpec.builder(type, name, modifiers).build());
    }

    public Builder addParameter(Type type, String name, Modifier... modifiers) {
      return addParameter(TypeName.get(type), name, modifiers);
    }

    public Builder varargs() {
      return varargs(true);
    }

    public Builder varargs(boolean varargs) {
      this.varargs = varargs;
      return this;
    }

    public Builder addExceptions(Iterable<? extends TypeName> exceptions) {
      checkArgument(exceptions != null, "exceptions == null");
      for (TypeName exception : exceptions) {
        this.exceptions.add(exception);
      }
      return this;
    }

    public Builder addException(TypeName exception) {
      this.exceptions.add(exception);
      return this;
    }

    public Builder addException(Type exception) {
      return addException(TypeName.get(exception));
    }

    public Builder addCode(String format, Object... args) {
      code.add(format, args);
      return this;
    }

    public Builder addNamedCode(String format, Map<String, ?> args) {
      code.addNamed(format, args);
      return this;
    }

    public Builder addCode(CodeBlock codeBlock) {
      code.add(codeBlock);
      return this;
    }

    public Builder addComment(String format, Object... args) {
      code.add("// " + format + "\n", args);
      return this;
    }

    public Builder defaultValue(String format, Object... args) {
      return defaultValue(CodeBlock.of(format, args));
    }

    public Builder defaultValue(CodeBlock codeBlock) {
      checkState(this.defaultValue == null, "defaultValue was already set");
      this.defaultValue = checkNotNull(codeBlock, "codeBlock == null");
      return this;
    }

    /**
     * @param controlFlow the control flow construct and its code, such as "if (foo == 5)".
     * Shouldn't contain braces or newline characters.
     */
    public Builder beginControlFlow(String controlFlow, Object... args) {
      code.beginControlFlow(controlFlow, args);
      return this;
    }

    /**
     * @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.
     */
    public Builder nextControlFlow(String controlFlow, Object... args) {
      code.nextControlFlow(controlFlow, args);
      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;
    }

    /**
     * @param controlFlow the optional control flow construct and its code, such as
     *     "while(foo == 20)". Only used for "do/while" control flows.
     */
    public Builder endControlFlow(String controlFlow, Object... args) {
      code.endControlFlow(controlFlow, args);
      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;
    }

    public Builder addStatement(CodeBlock codeBlock) {
      code.addStatement(codeBlock);
      return this;
    }

    public MethodSpec build() {
      return new MethodSpec(this);
    }
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/NameAllocator.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.lang.model.SourceVersion;

import static com.squareup.javapoet.Util.checkNotNull;

/**
 * Assigns Java identifier names to avoid collisions, keywords, and invalid characters. To use,
 * first create an instance and allocate all of the names that you need. Typically this is a
 * mix of user-supplied names and constants: <pre>   {@code
 *
 *   NameAllocator nameAllocator = new NameAllocator();
 *   for (MyProperty property : properties) {
 *     nameAllocator.newName(property.name(), property);
 *   }
 *   nameAllocator.newName("sb", "string builder");
 * }</pre>
 *
 * Pass a unique tag object to each allocation. The tag scopes the name, and can be used to look up
 * the allocated name later. Typically the tag is the object that is being named. In the above
 * example we use {@code property} for the user-supplied property names, and {@code "string
 * builder"} for our constant string builder.
 *
 * <p>Once we've allocated names we can use them when generating code: <pre>   {@code
 *
 *   MethodSpec.Builder builder = MethodSpec.methodBuilder("toString")
 *       .addAnnotation(Override.class)
 *       .addModifiers(Modifier.PUBLIC)
 *       .returns(String.class);
 *
 *   builder.addStatement("$1T $2N = new $1T()",
 *       StringBuilder.class, nameAllocator.get("string builder"));
 *   for (MyProperty property : properties) {
 *     builder.addStatement("$N.append($N)",
 *         nameAllocator.get("string builder"), nameAllocator.get(property));
 *   }
 *   builder.addStatement("return $N", nameAllocator.get("string builder"));
 *   return builder.build();
 * }</pre>
 *
 * The above code generates unique names if presented with conflicts. Given user-supplied properties
 * with names {@code ab} and {@code sb} this generates the following:  <pre>   {@code
 *
 *   &#64;Override
 *   public String toString() {
 *     StringBuilder sb_ = new StringBuilder();
 *     sb_.append(ab);
 *     sb_.append(sb);
 *     return sb_.toString();
 *   }
 * }</pre>
 *
 * The underscore is appended to {@code sb} to avoid conflicting with the user-supplied {@code sb}
 * property. Underscores are also prefixed for names that start with a digit, and used to replace
 * name-unsafe characters like space or dash.
 *
 * <p>When dealing with multiple independent inner scopes, use a {@link #clone()} of the
 * NameAllocator used for the outer scope to further refine name allocation for a specific inner
 * scope.
 */
public final class NameAllocator implements Cloneable {
  private final Set<String> allocatedNames;
  private final Map<Object, String> tagToName;

  public NameAllocator() {
    this(new LinkedHashSet<>(), new LinkedHashMap<>());
  }

  private NameAllocator(LinkedHashSet<String> allocatedNames,
                        LinkedHashMap<Object, String> tagToName) {
    this.allocatedNames = allocatedNames;
    this.tagToName = tagToName;
  }

  /**
   * Return a new name using {@code suggestion} that will not be a Java identifier or clash with
   * other names.
   */
  public String newName(String suggestion) {
    return newName(suggestion, UUID.randomUUID().toString());
  }

  /**
   * Return a new name using {@code suggestion} that will not be a Java identifier or clash with
   * other names. The returned value can be queried multiple times by passing {@code tag} to
   * {@link #get(Object)}.
   */
  public String newName(String suggestion, Object tag) {
    checkNotNull(suggestion, "suggestion");
    checkNotNull(tag, "tag");

    suggestion = toJavaIdentifier(suggestion);

    while (SourceVersion.isKeyword(suggestion) || !allocatedNames.add(suggestion)) {
      suggestion = suggestion + "_";
    }

    String replaced = tagToName.put(tag, suggestion);
    if (replaced != null) {
      tagToName.put(tag, replaced); // Put things back as they were!
      throw new IllegalArgumentException("tag " + tag + " cannot be used for both '" + replaced
          + "' and '" + suggestion + "'");
    }

    return suggestion;
  }

  public static String toJavaIdentifier(String suggestion) {
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < suggestion.length(); ) {
      int codePoint = suggestion.codePointAt(i);
      if (i == 0
          && !Character.isJavaIdentifierStart(codePoint)
          && Character.isJavaIdentifierPart(codePoint)) {
        result.append("_");
      }

      int validCodePoint = Character.isJavaIdentifierPart(codePoint) ? codePoint : '_';
      result.appendCodePoint(validCodePoint);
      i += Character.charCount(codePoint);
    }
    return result.toString();
  }

  /** Retrieve a name created with {@link #newName(String, Object)}. */
  public String get(Object tag) {
    String result = tagToName.get(tag);
    if (result == null) {
      throw new IllegalArgumentException("unknown tag: " + tag);
    }
    return result;
  }

  /**
   * Create a deep copy of this NameAllocator. Useful to create multiple independent refinements
   * of a NameAllocator to be used in the respective definition of multiples, independently-scoped,
   * inner code blocks.
   *
   * @return A deep copy of this NameAllocator.
   */
  @Override
  public NameAllocator clone() {
    return new NameAllocator(
        new LinkedHashSet<>(this.allocatedNames),
        new LinkedHashMap<>(this.tagToName));
  }

}


================================================
FILE: src/main/java/com/squareup/javapoet/ParameterSpec.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.VariableElement;

import static com.squareup.javapoet.Util.checkArgument;
import static com.squareup.javapoet.Util.checkNotNull;

/** A generated parameter declaration. */
public final class ParameterSpec {
  public final String name;
  public final 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) {
    return modifiers.contains(modifier);
  }

  void emit(CodeWriter codeWriter, boolean varargs) throws IOException {
    codeWriter.emitAnnotations(annotations, true);
    codeWriter.emitModifiers(modifiers);
    if (varargs) {
      TypeName.asArray(type).emit(codeWriter, true);
    } else {
      type.emit(codeWriter);
    }
    codeWriter.emit(" $L", name);
  }

  @Override public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null) return false;
    if (getClass() != o.getClass()) return false;
    return toString().equals(o.toString());
  }

  @Override public int hashCode() {
    return toString().hashCode();
  }

  @Override public String toString() {
    StringBuilder out = new StringBuilder();
    try {
      CodeWriter codeWriter = new CodeWriter(out);
      emit(codeWriter, false);
      return out.toString();
    } catch (IOException e) {
      throw new AssertionError();
    }
  }

  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();
  }

  static List<ParameterSpec> parametersOf(ExecutableElement method) {
    List<ParameterSpec> result = new ArrayList<>();
    for (VariableElement parameter : method.getParameters()) {
      result.add(ParameterSpec.get(parameter));
    }
    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);
    return new Builder(type, name)
        .addModifiers(modifiers);
  }

  public static Builder builder(Type type, String name, Modifier... modifiers) {
    return builder(TypeName.get(type), name, modifiers);
  }

  public Builder toBuilder() {
    return toBuilder(type, name);
  }

  Builder toBuilder(TypeName type, String name) {
    Builder builder = new Builder(type, name);
    builder.annotations.addAll(annotations);
    builder.modifiers.addAll(modifiers);
    return builder;
  }

  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 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) {
        this.annotations.add(annotationSpec);
      }
      return this;
    }

    public Builder addAnnotation(AnnotationSpec annotationSpec) {
      this.annotations.add(annotationSpec);
      return this;
    }

    public Builder addAnnotation(ClassName annotation) {
      this.annotations.add(AnnotationSpec.builder(annotation).build());
      return this;
    }

    public Builder addAnnotation(Class<?> annotation) {
      return addAnnotation(ClassName.get(annotation));
    }

    public Builder addModifiers(Modifier... modifiers) {
      Collections.addAll(this.modifiers, modifiers);
      return this;
    }

    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;
    }

    public ParameterSpec build() {
      return new ParameterSpec(this);
    }
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/ParameterizedTypeName.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static com.squareup.javapoet.Util.checkArgument;
import static com.squareup.javapoet.Util.checkNotNull;

public final class ParameterizedTypeName extends TypeName {
  private final ParameterizedTypeName enclosingType;
  public final ClassName rawType;
  public final List<TypeName> typeArguments;

  ParameterizedTypeName(ParameterizedTypeName enclosingType, ClassName rawType,
      List<TypeName> typeArguments) {
    this(enclosingType, rawType, typeArguments, new ArrayList<>());
  }

  private ParameterizedTypeName(ParameterizedTypeName enclosingType, ClassName rawType,
      List<TypeName> typeArguments, List<AnnotationSpec> annotations) {
    super(annotations);
    this.rawType = checkNotNull(rawType, "rawType == null").annotated(annotations);
    this.enclosingType = enclosingType;
    this.typeArguments = Util.immutableList(typeArguments);

    checkArgument(!this.typeArguments.isEmpty() || enclosingType != null,
        "no type arguments: %s", rawType);
    for (TypeName typeArgument : this.typeArguments) {
      checkArgument(!typeArgument.isPrimitive() && typeArgument != VOID,
          "invalid type parameter: %s", typeArgument);
    }
  }

  @Override public ParameterizedTypeName annotated(List<AnnotationSpec> annotations) {
    return new ParameterizedTypeName(
        enclosingType, rawType, typeArguments, concatAnnotations(annotations));
  }

  @Override
  public TypeName withoutAnnotations() {
    return new ParameterizedTypeName(
        enclosingType, rawType.withoutAnnotations(), typeArguments, new ArrayList<>());
  }

  @Override CodeWriter emit(CodeWriter out) throws IOException {
    if (enclosingType != null) {
      enclosingType.emit(out);
      out.emit(".");
      if (isAnnotated()) {
        out.emit(" ");
        emitAnnotations(out);
      }
      out.emit(rawType.simpleName());
    } else {
      rawType.emit(out);
    }
    if (!typeArguments.isEmpty()) {
      out.emitAndIndent("<");
      boolean firstParameter = true;
      for (TypeName parameter : typeArguments) {
        if (!firstParameter) out.emitAndIndent(", ");
        parameter.emit(out);
        firstParameter = false;
      }
      out.emitAndIndent(">");
    }
    return out;
  }

  /**
   * Returns a new {@link ParameterizedTypeName} instance for the specified {@code name} as nested
   * inside this class.
   */
  public ParameterizedTypeName nestedClass(String name) {
    checkNotNull(name, "name == null");
    return new ParameterizedTypeName(this, rawType.nestedClass(name), new ArrayList<>(),
        new ArrayList<>());
  }

  /**
   * Returns a new {@link ParameterizedTypeName} instance for the specified {@code name} as nested
   * inside this class, with the specified {@code typeArguments}.
   */
  public ParameterizedTypeName nestedClass(String name, List<TypeName> typeArguments) {
    checkNotNull(name, "name == null");
    return new ParameterizedTypeName(this, rawType.nestedClass(name), typeArguments,
        new ArrayList<>());
  }

  /** Returns a parameterized type, applying {@code typeArguments} to {@code rawType}. */
  public static ParameterizedTypeName get(ClassName rawType, TypeName... typeArguments) {
    return new ParameterizedTypeName(null, rawType, Arrays.asList(typeArguments));
  }

  /** Returns a parameterized type, applying {@code typeArguments} to {@code rawType}. */
  public static ParameterizedTypeName get(Class<?> rawType, Type... typeArguments) {
    return new ParameterizedTypeName(null, ClassName.get(rawType), list(typeArguments));
  }

  /** Returns a parameterized type equivalent to {@code type}. */
  public static ParameterizedTypeName get(ParameterizedType type) {
    return get(type, new LinkedHashMap<>());
  }

  /** Returns a parameterized type equivalent to {@code type}. */
  static ParameterizedTypeName get(ParameterizedType type, Map<Type, TypeVariableName> map) {
    ClassName rawType = ClassName.get((Class<?>) type.getRawType());
    ParameterizedType ownerType = (type.getOwnerType() instanceof ParameterizedType)
        && !Modifier.isStatic(((Class<?>) type.getRawType()).getModifiers())
        ? (ParameterizedType) type.getOwnerType() : null;
    List<TypeName> typeArguments = TypeName.list(type.getActualTypeArguments(), map);
    return (ownerType != null)
        ? get(ownerType, map).nestedClass(rawType.simpleName(), typeArguments)
        : new ParameterizedTypeName(null, rawType, typeArguments);
  }
}


================================================
FILE: src/main/java/com/squareup/javapoet/TypeName.java
================================================
/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.javapoet;

import java.io.IOException;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ErrorType;
import javax.lang.model.type.NoType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleTypeVisitor8;

/**
 * Any type in Java's type system, plus {@code void}. This class is an identifier for primitive
 * types like {@code int} and raw reference types like {@code String} and {@code List}. It also
 * 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
 * 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
 * hashCode()} properly.
 *
 * <h3>Referencing existing types</h3>
 *
 * <p>Primitives and void are constants that you can reference directly: see {@link #INT}, {@link
 * #DOUBLE}, and {@link #VOID}.
 *
 * <p>In an annotation processor you can get a type name instance for a type mirror by calling
 * {@link #get(TypeMirror)}. In reflection code, you can use {@link #get(Type)}.
 *
 * <h3>Defining new types</h3>
 *
 * <p>Create new reference types like {@code com.example.HelloWorld} with {@link
 * ClassName#get(String, String, String...)}. To build composite types like {@code char[]} and
 * {@code Set<Long>}, use the factory methods on {@link ArrayTypeName}, {@link
 * ParameterizedTypeName}, {@link TypeVariableName}, and {@link WildcardTypeName}.
 */
public class TypeName {
  public static final TypeName VOID = new TypeName("void");
  public static final TypeName BOOLEAN = new TypeName("boolean");
  public static final TypeName BYTE = new TypeName("byte");
  public static final TypeName SHORT = new TypeName("short");
  public static final TypeName INT = new TypeName("int");
  public static final TypeName LONG = new TypeName("long");
  public static final TypeName CHAR = new TypeName("char");
  public static final TypeName FLOAT = new TypeName("float");
  public static final TypeName DOUBLE = new TypeName("double");
  public static final ClassName OBJECT = ClassName.get("java.lang", "Object");

  private static final ClassName BOXED_VOID = ClassName.get("java.lang", "Void");
  private static final ClassName BOXED_BOOLEAN = ClassName.get("java.lang", "Boolean");
  private static final ClassName BOXED_BYTE = ClassName.get("java.lang", "Byte");
  private static final ClassName BOXED_SHORT = ClassName.get("java.lang", "Short");
  private static final ClassName BOXED_INT = ClassName.get("java.lang", "Integer");
  private static final ClassName BOXED_LONG = ClassName.get("java.lang", "Long");
  private static final ClassName BOXED_CHAR = ClassName.get("java.lang", "Character");
  private static final ClassName BOXED_FLOAT = ClassName.get("java.lang", "Float");
  private static final ClassName BOXED_DOUBLE = ClassName.get("java.lang", "Double");

  /** The name of this type if it is a keyword, or null. */
  private final String keyword;
  public final List<AnnotationSpec> annotations;

  /** Lazily-initialized toString of this type name. */
  private String cachedString;

  private TypeName(String keyword) {
    this(keyword, new ArrayList<>());
  }

  private TypeName(String keyword, List<AnnotationSpec> annotations) {
    this.keyword = keyword;
    this.annotations = Util.immutableList(annotations);
  }

  // Package-private constructor to prevent third-party subclasses.
  TypeName(List<AnnotationSpec> annotations) {
    this(null, annotations);
  }

  public final TypeName annotated(AnnotationSpec... annotations) {
    return annotated(Arrays.asList(annotations));
  }

  public TypeName annotated(List<AnnotationSpec> annotations) {
    Util.checkNotNull(annotations, "annotations == null");
    return new TypeName(keyword, concatAnnotations(annotations));
  }

  public TypeName withoutAnnotations() {
    if (annotations.isEmpty()) {
      return this;
    }
    return new TypeName(keyword);
  }

  protected final List<AnnotationSpec> concatAnnotations(List<AnnotationSpec> annotations) {
    List<AnnotationSpec> allAnnotations = new ArrayList<>(this.annotations);
    allAnnotations.addAll(annotations);
    return allAnnotations;
  }

  public boolean isAnnotated() {
    return !annotations.isEmpty();
  }

  /**
   * Returns true if this is a primitive type like {@code int}. Returns false for all other types
   * types including boxed primitives and {@code void}.
   */
  public boolean isPrimitive() {
    return keyword != null && this != VOID;
  }

  /**
   * Returns true if this is a boxed primitive type like {@code Integer}. Returns false for all
   * other types types including unboxed primitives and {@code java.lang.Void}.
   */
  public boolean isBoxedPrimitive() {
    TypeName thisWithoutAnnotations = withoutAnnotations();
    return thisWithoutAnnotations.equals(BOXED_BOOLEAN)
        || thisWithoutAnnotations.equals(BOXED_BYTE)
        || thisWithoutAnnotations.equals(BOXED_SHORT)
        || thisWithoutAnnotations.equals(BOXED_INT)
        || thisWithoutAnnotations.equals(BOXED_LONG)
        || thisWithoutAnnotations.equals(BOXED_CHAR)
        || thisWithoutAnnotations.equals(BOXED_FLOAT)
        || thisWithoutAnnotations.equals(BOXED_DOUBLE);
  }

  /**
   * Returns a boxed type if this is a primitive type (like {@code Integer} for {@code int}) or
   * {@code void}. Returns this type if boxing doesn't apply.
   */
  public TypeName box() {
    if (keyword == null) return this; // Doesn't need boxing.
    TypeName boxed = null;
    if (keyword.equals(VOID.keyword)) boxed = BOXED_VOID;
    else if (keyword.equals(BOOLEAN.keyword)) boxed = BOXED_BOOLEAN;
    else if (keyword.equals(BYTE.keyword)) boxed = BOXED_BYTE;
    else if (keyword.equals(SHORT.keyword)) boxed = BOXED_SHORT;
    else if (keyword.equals(INT.keyword)) boxed = BOXED_INT;
    else if (keyword.equals(LONG.keyword)) boxed = BOXED_LONG;
    else if (keyword.equals(CHAR.keyword)) boxed = BOXED_CHAR;
    else if (keyword.equals(FLOAT.keyword)) boxed = BOXED_FLOAT;
    else if (keyword.equals(DOUBLE.keyword)) boxed = BOXED_DOUBLE;
    else throw new AssertionError(keyword);
    return annotations.isEmpty() ? boxed : boxed.annotated(annotations);
  }

  /**
   * Returns an unboxed type if this is a boxed primitive type (like {@code int} for {@code
   * Integer}) or {@code Void}. Returns this type if it is already unboxed.
   *
   * @throws UnsupportedOperationException if this type isn't eligible for unboxing.
   */
  public TypeName unbox() {
    if (keyword != null) return this; // Already unboxed.
    TypeName thisWithoutAnnotations = withoutAnnotations();
    TypeName unboxed = null;
    if (thisWithoutAnnotations.equals(BOXED_VOID)) unboxed = VOID;
    else if (thisWithoutAnnotations.equals(BOXED_BOOLEAN)) unboxed = BOOLEAN;
    else if (thisWithoutAnnotations.equals(BOXED_BYTE)) unboxed = BYTE;
    else if (thisWithoutAnnotations.equals(BOXED_SHORT)) unboxed = SHORT;
    else if (thisWithoutAnnotations.equals(BOXED_INT)) unboxed = INT;
    else if (thisWithoutAnnotations.equals(BOXED_LONG)) unboxed = LONG;
    else if (thisWithoutAnnotations.equals(BOXED_CHAR)) unboxed = CHAR;
    else if (thisWithoutAnnotations.equals(BOXED_FLOAT)) unboxed = FLOAT;
    else if (thisWithoutAnnotations.equals(BOXED_DOUBLE)) unboxed = DOUBLE;
    else throw new UnsupportedOperationException("cannot unbox " + this);
    return annotations.isEmpty() ? unboxed : unboxed.annotated(annotations);
  }

  @Override public final boolean equals(Object o) {
    if (this == o) return true;
    if (o == null) return false;
    if (getClass() != o.getClass()) return false;
    return toString().equals(o.toString());
  }

  @Override public final int hashCode() {
    return toString().hashCode();
  }

  @Override public final String toString() {
    String result = cachedString;
    if (result == null) {
      try {
        StringBuilder resultBuilder = new StringBuilder();
        CodeWriter codeWriter = new CodeWriter(resultBuilder);
        emit(codeWriter);
        result = resultBuilder.toString();
        cachedString = result;
      } catch (IOException e) {
        throw new AssertionError();
      }
    }
    return result;
  }

  CodeWriter emit(CodeWriter out) throws IOException {
    if (keyword == null) throw new AssertionError();

    if (isAnnotated()) {
      out.emit("");
      emitAnnotations(out);
    }
    return out.emitAndIndent(keyword);
  }

  CodeWriter emitAnnotations(CodeWriter out) throws IOException {
    for (AnnotationSpec annotation : annotations) {
      annotation.emit(out, true);
      out.emit(" ");
    }
    return out;
  }


  /** Returns a type name equivalent to {@code mirror}. */
  public static TypeName get(TypeMirror mirror) {
    return get(mirror, new LinkedHashMap<>());
  }

  static TypeName get(TypeMirror mirror,
      final Map<TypeParameterElement, TypeVariableName> typeVariables) {
    return mirror.accept(new SimpleTypeVisitor8<TypeName, Void>() {
      @Override public TypeName visitPrimitive(PrimitiveType t, Void p) {
        switch (t.getKind()) {
          case BOOLEAN:
            return TypeName.BOOLEAN;
          case BYTE:
            return TypeName.BYTE;
          case SHORT:
            return TypeName.SHORT;
          case INT:
            return TypeName.INT;
          case LONG:
            return TypeName.LONG;
          case CHAR:
            return TypeName.CHAR;
          case FLOAT:
            return TypeName.FLOAT;
          case DOUBLE:
            return TypeName.DOUBLE;
          default:
            throw new AssertionError();
        }
      }

      @Override public TypeName visitDeclared(DeclaredType t, Void p) {
        ClassName rawType = ClassName.get((TypeElement) t.asElement());
        TypeMirror enclosingType = t.getEnclosingType();
        TypeName enclosing =
            (enclosingType.getKind() != TypeKind.NONE)
                    && !t.asElement().getModifiers().contains(Modifier.STATIC)
                ? enclosingType.accept(this, null)
                : null;
        if (t.getTypeArguments().isEmpty() && !(enclosing instanceof ParameterizedTypeName)) {
          return rawType;
        }

        List<TypeName> typeArgumentNames = new ArrayList<>();
        for (TypeMirror mirror : t.getTypeArguments()) {
          typeArgumentNames.add(get(mirror, typeVariables));
        }
        return enclosing instanceof ParameterizedTypeName
            ? ((ParameterizedTypeName) enclosing).nestedClass(
            rawType.simpleName(), typeArgumentNames)
            : new ParameterizedTypeName(null, rawType, typeArgumentNames);
      }

      @Override public TypeName visitError(ErrorType t, Void p) {
        return visitDeclared(t, p);
      }

      @Override public ArrayTypeName visitArray(ArrayType t, Void p) {
        return ArrayTypeName.get(t, typeVariables);
      }

      @Override public TypeName visitTypeVar
Download .txt
gitextract_4emi2l0t/

├── .github/
│   ├── CONTRIBUTING.md
│   └── workflows/
│       ├── build.yml
│       └── settings.xml
├── .gitignore
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── RELEASING.md
├── checkstyle.xml
├── pom.xml
├── renovate.json
└── src/
    ├── main/
    │   └── java/
    │       └── com/
    │           └── squareup/
    │               └── javapoet/
    │                   ├── AnnotationSpec.java
    │                   ├── ArrayTypeName.java
    │                   ├── ClassName.java
    │                   ├── CodeBlock.java
    │                   ├── CodeWriter.java
    │                   ├── FieldSpec.java
    │                   ├── JavaFile.java
    │                   ├── LineWrapper.java
    │                   ├── MethodSpec.java
    │                   ├── NameAllocator.java
    │                   ├── ParameterSpec.java
    │                   ├── ParameterizedTypeName.java
    │                   ├── TypeName.java
    │                   ├── TypeSpec.java
    │                   ├── TypeVariableName.java
    │                   ├── Util.java
    │                   └── WildcardTypeName.java
    └── test/
        └── java/
            ├── ClassNameNoPackageTest.java
            └── com/
                └── squareup/
                    └── javapoet/
                        ├── AbstractTypesTest.java
                        ├── AnnotatedTypeNameTest.java
                        ├── AnnotationSpecTest.java
                        ├── ClassNameTest.java
                        ├── CodeBlockTest.java
                        ├── CodeWriterTest.java
                        ├── FieldSpecTest.java
                        ├── FileReadingTest.java
                        ├── FileWritingTest.java
                        ├── JavaFileTest.java
                        ├── LineWrapperTest.java
                        ├── MethodSpecTest.java
                        ├── NameAllocatorTest.java
                        ├── ParameterSpecTest.java
                        ├── TestFiler.java
                        ├── TestUtil.java
                        ├── TypeNameTest.java
                        ├── TypeSpecTest.java
                        ├── TypesEclipseTest.java
                        ├── TypesTest.java
                        └── UtilTest.java
Download .txt
SYMBOL INDEX (920 symbols across 39 files)

FILE: src/main/java/com/squareup/javapoet/AnnotationSpec.java
  class AnnotationSpec (line 44) | public final class AnnotationSpec {
    method AnnotationSpec (line 50) | private AnnotationSpec(Builder builder) {
    method emit (line 55) | void emit(CodeWriter codeWriter, boolean inline) throws IOException {
    method emitAnnotationValues (line 89) | private void emitAnnotationValues(CodeWriter codeWriter, String whites...
    method get (line 110) | public static AnnotationSpec get(Annotation annotation) {
    method get (line 114) | public static AnnotationSpec get(Annotation annotation, boolean includ...
    method get (line 144) | public static AnnotationSpec get(AnnotationMirror annotation) {
    method builder (line 156) | public static Builder builder(ClassName type) {
    method builder (line 161) | public static Builder builder(Class<?> type) {
    method toBuilder (line 165) | public Builder toBuilder() {
    method equals (line 173) | @Override public boolean equals(Object o) {
    method hashCode (line 180) | @Override public int hashCode() {
    method toString (line 184) | @Override public String toString() {
    class Builder (line 195) | public static final class Builder {
      method Builder (line 200) | private Builder(TypeName type) {
      method addMember (line 204) | public Builder addMember(String name, String format, Object... args) {
      method addMember (line 208) | public Builder addMember(String name, CodeBlock codeBlock) {
      method addMemberForValue (line 219) | Builder addMemberForValue(String memberName, Object value) {
      method build (line 244) | public AnnotationSpec build() {
    class Visitor (line 256) | private static class Visitor extends SimpleAnnotationValueVisitor8<Bui...
      method Visitor (line 259) | Visitor(Builder builder) {
      method defaultAction (line 264) | @Override protected Builder defaultAction(Object o, String name) {
      method visitAnnotation (line 268) | @Override public Builder visitAnnotation(AnnotationMirror a, String ...
      method visitEnumConstant (line 272) | @Override public Builder visitEnumConstant(VariableElement c, String...
      method visitType (line 276) | @Override public Builder visitType(TypeMirror t, String name) {
      method visitArray (line 280) | @Override public Builder visitArray(List<? extends AnnotationValue> ...

FILE: src/main/java/com/squareup/javapoet/ArrayTypeName.java
  class ArrayTypeName (line 30) | public final class ArrayTypeName extends TypeName {
    method ArrayTypeName (line 33) | private ArrayTypeName(TypeName componentType) {
    method ArrayTypeName (line 37) | private ArrayTypeName(TypeName componentType, List<AnnotationSpec> ann...
    method annotated (line 42) | @Override public ArrayTypeName annotated(List<AnnotationSpec> annotati...
    method withoutAnnotations (line 46) | @Override public TypeName withoutAnnotations() {
    method emit (line 50) | @Override CodeWriter emit(CodeWriter out) throws IOException {
    method emit (line 54) | CodeWriter emit(CodeWriter out, boolean varargs) throws IOException {
    method emitLeafType (line 59) | private CodeWriter emitLeafType(CodeWriter out) throws IOException {
    method emitBrackets (line 66) | private CodeWriter emitBrackets(CodeWriter out, boolean varargs) throw...
    method of (line 82) | public static ArrayTypeName of(TypeName componentType) {
    method of (line 87) | public static ArrayTypeName of(Type componentType) {
    method get (line 92) | public static ArrayTypeName get(ArrayType mirror) {
    method get (line 96) | static ArrayTypeName get(
    method get (line 102) | public static ArrayTypeName get(GenericArrayType type) {
    method get (line 106) | static ArrayTypeName get(GenericArrayType type, Map<Type, TypeVariable...

FILE: src/main/java/com/squareup/javapoet/ClassName.java
  class ClassName (line 33) | public final class ClassName extends TypeName implements Comparable<Clas...
    method ClassName (line 53) | private ClassName(String packageName, ClassName enclosingClassName, St...
    method ClassName (line 57) | private ClassName(String packageName, ClassName enclosingClassName, St...
    method annotated (line 68) | @Override public ClassName annotated(List<AnnotationSpec> annotations) {
    method withoutAnnotations (line 73) | @Override public ClassName withoutAnnotations() {
    method isAnnotated (line 81) | @Override public boolean isAnnotated() {
    method packageName (line 89) | public String packageName() {
    method enclosingClassName (line 97) | public ClassName enclosingClassName() {
    method topLevelClassName (line 105) | public ClassName topLevelClassName() {
    method reflectionName (line 110) | public String reflectionName() {
    method simpleNames (line 116) | public List<String> simpleNames() {
    method peerClass (line 137) | public ClassName peerClass(String name) {
    method nestedClass (line 145) | public ClassName nestedClass(String name) {
    method simpleName (line 150) | public String simpleName() {
    method canonicalName (line 158) | public String canonicalName() {
    method get (line 162) | public static ClassName get(Class<?> clazz) {
    method bestGuess (line 194) | public static ClassName bestGuess(String classNameString) {
    method get (line 218) | public static ClassName get(String packageName, String simpleName, Str...
    method get (line 227) | public static ClassName get(TypeElement element) {
    method compareTo (line 250) | @Override public int compareTo(ClassName o) {
    method emit (line 254) | @Override CodeWriter emit(CodeWriter out) throws IOException {
    method enclosingClasses (line 293) | private List<ClassName> enclosingClasses() {

FILE: src/main/java/com/squareup/javapoet/CodeBlock.java
  class CodeBlock (line 65) | public final class CodeBlock {
    method CodeBlock (line 74) | private CodeBlock(Builder builder) {
    method isEmpty (line 79) | public boolean isEmpty() {
    method equals (line 83) | @Override public boolean equals(Object o) {
    method hashCode (line 90) | @Override public int hashCode() {
    method toString (line 94) | @Override public String toString() {
    method of (line 104) | public static CodeBlock of(String format, Object... args) {
    method join (line 113) | public static CodeBlock join(Iterable<CodeBlock> codeBlocks, String se...
    method joining (line 122) | public static Collector<CodeBlock, ?, CodeBlock> joining(String separa...
    method joining (line 135) | public static Collector<CodeBlock, ?, CodeBlock> joining(
    method builder (line 148) | public static Builder builder() {
    method toBuilder (line 152) | public Builder toBuilder() {
    class Builder (line 159) | public static final class Builder {
      method Builder (line 163) | private Builder() {
      method isEmpty (line 166) | public boolean isEmpty() {
      method addNamed (line 181) | public Builder addNamed(String format, Map<String, ?> arguments) {
      method add (line 238) | public Builder add(String format, Object... args) {
      method isNoArgPlaceholder (line 314) | private boolean isNoArgPlaceholder(char c) {
      method addArgument (line 318) | private void addArgument(String format, char c, Object arg) {
      method argToName (line 338) | private String argToName(Object o) {
      method argToLiteral (line 347) | private Object argToLiteral(Object o) {
      method argToString (line 351) | private String argToString(Object o) {
      method argToType (line 355) | private TypeName argToType(Object o) {
      method beginControlFlow (line 367) | public Builder beginControlFlow(String controlFlow, Object... args) {
      method nextControlFlow (line 377) | public Builder nextControlFlow(String controlFlow, Object... args) {
      method endControlFlow (line 384) | public Builder endControlFlow() {
      method endControlFlow (line 394) | public Builder endControlFlow(String controlFlow, Object... args) {
      method addStatement (line 400) | public Builder addStatement(String format, Object... args) {
      method addStatement (line 407) | public Builder addStatement(CodeBlock codeBlock) {
      method add (line 411) | public Builder add(CodeBlock codeBlock) {
      method indent (line 417) | public Builder indent() {
      method unindent (line 422) | public Builder unindent() {
      method clear (line 427) | public Builder clear() {
      method build (line 433) | public CodeBlock build() {
    class CodeBlockJoiner (line 438) | private static final class CodeBlockJoiner {
      method CodeBlockJoiner (line 443) | CodeBlockJoiner(String delimiter, Builder builder) {
      method add (line 448) | CodeBlockJoiner add(CodeBlock codeBlock) {
      method merge (line 458) | CodeBlockJoiner merge(CodeBlockJoiner other) {
      method join (line 466) | CodeBlock join() {

FILE: src/main/java/com/squareup/javapoet/CodeWriter.java
  class CodeWriter (line 44) | final class CodeWriter {
    method CodeWriter (line 73) | CodeWriter(Appendable out) {
    method CodeWriter (line 77) | CodeWriter(Appendable out, String indent, Set<String> staticImports, S...
    method CodeWriter (line 81) | CodeWriter(Appendable out,
    method importedTypes (line 97) | public Map<String, ClassName> importedTypes() {
    method indent (line 101) | public CodeWriter indent() {
    method indent (line 105) | public CodeWriter indent(int levels) {
    method unindent (line 110) | public CodeWriter unindent() {
    method unindent (line 114) | public CodeWriter unindent(int levels) {
    method pushPackage (line 120) | public CodeWriter pushPackage(String packageName) {
    method popPackage (line 126) | public CodeWriter popPackage() {
    method pushType (line 132) | public CodeWriter pushType(TypeSpec type) {
    method popType (line 137) | public CodeWriter popType() {
    method emitComment (line 142) | public void emitComment(CodeBlock codeBlock) throws IOException {
    method emitJavadoc (line 153) | public void emitJavadoc(CodeBlock javadocCodeBlock) throws IOException {
    method emitAnnotations (line 166) | public void emitAnnotations(List<AnnotationSpec> annotations, boolean ...
    method emitModifiers (line 177) | public void emitModifiers(Set<Modifier> modifiers, Set<Modifier> impli...
    method emitModifiers (line 187) | public void emitModifiers(Set<Modifier> modifiers) throws IOException {
    method emitTypeVariables (line 195) | public void emitTypeVariables(List<TypeVariableName> typeVariables) th...
    method popTypeVariables (line 216) | public void popTypeVariables(List<TypeVariableName> typeVariables) thr...
    method emit (line 220) | public CodeWriter emit(String s) throws IOException {
    method emit (line 224) | public CodeWriter emit(String format, Object... args) throws IOExcepti...
    method emit (line 228) | public CodeWriter emit(CodeBlock codeBlock) throws IOException {
    method emit (line 232) | public CodeWriter emit(CodeBlock codeBlock, boolean ensureTrailingNewl...
    method emitWrappingSpace (line 327) | public CodeWriter emitWrappingSpace() throws IOException {
    method extractMemberName (line 332) | private static String extractMemberName(String part) {
    method emitStaticImportMember (line 342) | private boolean emitStaticImportMember(String canonical, String part) ...
    method emitLiteral (line 356) | private void emitLiteral(Object o) throws IOException {
    method lookupName (line 376) | String lookupName(ClassName className) {
    method importableType (line 416) | private void importableType(ClassName className) {
    method resolve (line 436) | private ClassName resolve(String simpleName) {
    method stackClassName (line 459) | private ClassName stackClassName(int stackDepth, String simpleName) {
    method emitAndIndent (line 472) | CodeWriter emitAndIndent(String s) throws IOException {
    method emitIndentation (line 510) | private void emitIndentation() throws IOException {
    method suggestedImports (line 520) | Map<String, ClassName> suggestedImports() {
    class Multiset (line 527) | private static final class Multiset<T> {
      method add (line 530) | void add(T t) {
      method remove (line 535) | void remove(T t) {
      method contains (line 543) | boolean contains(T t) {

FILE: src/main/java/com/squareup/javapoet/FieldSpec.java
  class FieldSpec (line 32) | public final class FieldSpec {
    method FieldSpec (line 40) | private FieldSpec(Builder builder) {
    method hasModifier (line 51) | public boolean hasModifier(Modifier modifier) {
    method emit (line 55) | void emit(CodeWriter codeWriter, Set<Modifier> implicitModifiers) thro...
    method equals (line 67) | @Override public boolean equals(Object o) {
    method hashCode (line 74) | @Override public int hashCode() {
    method toString (line 78) | @Override public String toString() {
    method builder (line 89) | public static Builder builder(TypeName type, String name, Modifier... ...
    method builder (line 96) | public static Builder builder(Type type, String name, Modifier... modi...
    method toBuilder (line 100) | public Builder toBuilder() {
    class Builder (line 109) | public static final class Builder {
      method Builder (line 119) | private Builder(TypeName type, String name) {
      method addJavadoc (line 124) | public Builder addJavadoc(String format, Object... args) {
      method addJavadoc (line 129) | public Builder addJavadoc(CodeBlock block) {
      method addAnnotations (line 134) | public Builder addAnnotations(Iterable<AnnotationSpec> annotationSpe...
      method addAnnotation (line 142) | public Builder addAnnotation(AnnotationSpec annotationSpec) {
      method addAnnotation (line 147) | public Builder addAnnotation(ClassName annotation) {
      method addAnnotation (line 152) | public Builder addAnnotation(Class<?> annotation) {
      method addModifiers (line 156) | public Builder addModifiers(Modifier... modifiers) {
      method initializer (line 161) | public Builder initializer(String format, Object... args) {
      method initializer (line 165) | public Builder initializer(CodeBlock codeBlock) {
      method build (line 171) | public FieldSpec build() {

FILE: src/main/java/com/squareup/javapoet/JavaFile.java
  class JavaFile (line 46) | public final class JavaFile {
    method append (line 48) | @Override public Appendable append(CharSequence charSequence) {
    method append (line 51) | @Override public Appendable append(CharSequence charSequence, int star...
    method append (line 54) | @Override public Appendable append(char c) {
    method JavaFile (line 67) | private JavaFile(Builder builder) {
    method fillAlwaysQualifiedNames (line 80) | private void fillAlwaysQualifiedNames(TypeSpec spec, Set<String> alway...
    method writeTo (line 87) | public void writeTo(Appendable out) throws IOException {
    method writeTo (line 105) | public void writeTo(Path directory) throws IOException {
    method writeTo (line 113) | public void writeTo(Path directory, Charset charset) throws IOException {
    method writeToPath (line 121) | public Path writeToPath(Path directory) throws IOException {
    method writeToPath (line 130) | public Path writeToPath(Path directory, Charset charset) throws IOExce...
    method writeTo (line 150) | public void writeTo(File directory) throws IOException {
    method writeToFile (line 158) | public File writeToFile(File directory) throws IOException {
    method writeTo (line 164) | public void writeTo(Filer filer) throws IOException {
    method emit (line 182) | private void emit(CodeWriter codeWriter) throws IOException {
    method equals (line 222) | @Override public boolean equals(Object o) {
    method hashCode (line 229) | @Override public int hashCode() {
    method toString (line 233) | @Override public String toString() {
    method toJavaFileObject (line 243) | public JavaFileObject toJavaFileObject() {
    method builder (line 262) | public static Builder builder(String packageName, TypeSpec typeSpec) {
    method toBuilder (line 268) | public Builder toBuilder() {
    class Builder (line 276) | public static final class Builder {
      method Builder (line 285) | private Builder(String packageName, TypeSpec typeSpec) {
      method addFileComment (line 290) | public Builder addFileComment(String format, Object... args) {
      method addStaticImport (line 295) | public Builder addStaticImport(Enum<?> constant) {
      method addStaticImport (line 299) | public Builder addStaticImport(Class<?> clazz, String... names) {
      method addStaticImport (line 303) | public Builder addStaticImport(ClassName className, String... names) {
      method skipJavaLangImports (line 322) | public Builder skipJavaLangImports(boolean skipJavaLangImports) {
      method indent (line 327) | public Builder indent(String indent) {
      method build (line 332) | public JavaFile build() {

FILE: src/main/java/com/squareup/javapoet/LineWrapper.java
  class LineWrapper (line 26) | final class LineWrapper {
    method LineWrapper (line 48) | LineWrapper(Appendable out, String indent, int columnLimit) {
    method lastChar (line 56) | char lastChar() {
    method append (line 61) | void append(String s) throws IOException {
    method wrappingSpace (line 88) | void wrappingSpace(int indentLevel) throws IOException {
    method zeroWidthSpace (line 98) | void zeroWidthSpace(int indentLevel) throws IOException {
    method close (line 108) | void close() throws IOException {
    method flush (line 114) | private void flush(FlushType flushType) throws IOException {
    type FlushType (line 139) | private enum FlushType {
    class RecordingAppendable (line 144) | static final class RecordingAppendable implements Appendable {
      method RecordingAppendable (line 149) | RecordingAppendable(Appendable delegate) {
      method append (line 153) | @Override public Appendable append(CharSequence csq) throws IOExcept...
      method append (line 161) | @Override public Appendable append(CharSequence csq, int start, int ...
      method append (line 166) | @Override public Appendable append(char c) throws IOException {

FILE: src/main/java/com/squareup/javapoet/MethodSpec.java
  class MethodSpec (line 43) | public final class MethodSpec {
    method MethodSpec (line 58) | private MethodSpec(Builder builder) {
    method lastParameterIsArray (line 78) | private boolean lastParameterIsArray(List<ParameterSpec> parameters) {
    method emit (line 83) | void emit(CodeWriter codeWriter, String enclosingName, Set<Modifier> i...
    method javadocWithParameters (line 143) | private CodeBlock javadocWithParameters() {
    method hasModifier (line 157) | public boolean hasModifier(Modifier modifier) {
    method isConstructor (line 161) | public boolean isConstructor() {
    method equals (line 165) | @Override public boolean equals(Object o) {
    method hashCode (line 172) | @Override public int hashCode() {
    method toString (line 176) | @Override public String toString() {
    method methodBuilder (line 187) | public static Builder methodBuilder(String name) {
    method constructorBuilder (line 191) | public static Builder constructorBuilder() {
    method overriding (line 204) | public static Builder overriding(ExecutableElement method) {
    method overriding (line 257) | public static Builder overriding(
    method toBuilder (line 279) | public Builder toBuilder() {
    class Builder (line 294) | public static final class Builder {
      method Builder (line 309) | private Builder(String name) {
      method setName (line 313) | public Builder setName(String name) {
      method addJavadoc (line 322) | public Builder addJavadoc(String format, Object... args) {
      method addJavadoc (line 327) | public Builder addJavadoc(CodeBlock block) {
      method addAnnotations (line 332) | public Builder addAnnotations(Iterable<AnnotationSpec> annotationSpe...
      method addAnnotation (line 340) | public Builder addAnnotation(AnnotationSpec annotationSpec) {
      method addAnnotation (line 345) | public Builder addAnnotation(ClassName annotation) {
      method addAnnotation (line 350) | public Builder addAnnotation(Class<?> annotation) {
      method addModifiers (line 354) | public Builder addModifiers(Modifier... modifiers) {
      method addModifiers (line 360) | public Builder addModifiers(Iterable<Modifier> modifiers) {
      method addTypeVariables (line 368) | public Builder addTypeVariables(Iterable<TypeVariableName> typeVaria...
      method addTypeVariable (line 376) | public Builder addTypeVariable(TypeVariableName typeVariable) {
      method returns (line 381) | public Builder returns(TypeName returnType) {
      method returns (line 387) | public Builder returns(Type returnType) {
      method addParameters (line 391) | public Builder addParameters(Iterable<ParameterSpec> parameterSpecs) {
      method addParameter (line 399) | public Builder addParameter(ParameterSpec parameterSpec) {
      method addParameter (line 404) | public Builder addParameter(TypeName type, String name, Modifier... ...
      method addParameter (line 408) | public Builder addParameter(Type type, String name, Modifier... modi...
      method varargs (line 412) | public Builder varargs() {
      method varargs (line 416) | public Builder varargs(boolean varargs) {
      method addExceptions (line 421) | public Builder addExceptions(Iterable<? extends TypeName> exceptions) {
      method addException (line 429) | public Builder addException(TypeName exception) {
      method addException (line 434) | public Builder addException(Type exception) {
      method addCode (line 438) | public Builder addCode(String format, Object... args) {
      method addNamedCode (line 443) | public Builder addNamedCode(String format, Map<String, ?> args) {
      method addCode (line 448) | public Builder addCode(CodeBlock codeBlock) {
      method addComment (line 453) | public Builder addComment(String format, Object... args) {
      method defaultValue (line 458) | public Builder defaultValue(String format, Object... args) {
      method defaultValue (line 462) | public Builder defaultValue(CodeBlock codeBlock) {
      method beginControlFlow (line 472) | public Builder beginControlFlow(String controlFlow, Object... args) {
      method beginControlFlow (line 481) | public Builder beginControlFlow(CodeBlock codeBlock) {
      method nextControlFlow (line 489) | public Builder nextControlFlow(String controlFlow, Object... args) {
      method nextControlFlow (line 498) | public Builder nextControlFlow(CodeBlock codeBlock) {
      method endControlFlow (line 502) | public Builder endControlFlow() {
      method endControlFlow (line 511) | public Builder endControlFlow(String controlFlow, Object... args) {
      method endControlFlow (line 520) | public Builder endControlFlow(CodeBlock codeBlock) {
      method addStatement (line 524) | public Builder addStatement(String format, Object... args) {
      method addStatement (line 529) | public Builder addStatement(CodeBlock codeBlock) {
      method build (line 534) | public MethodSpec build() {

FILE: src/main/java/com/squareup/javapoet/NameAllocator.java
  class NameAllocator (line 81) | public final class NameAllocator implements Cloneable {
    method NameAllocator (line 85) | public NameAllocator() {
    method NameAllocator (line 89) | private NameAllocator(LinkedHashSet<String> allocatedNames,
    method newName (line 99) | public String newName(String suggestion) {
    method newName (line 108) | public String newName(String suggestion, Object tag) {
    method toJavaIdentifier (line 128) | public static String toJavaIdentifier(String suggestion) {
    method get (line 146) | public String get(Object tag) {
    method clone (line 161) | @Override

FILE: src/main/java/com/squareup/javapoet/ParameterSpec.java
  class ParameterSpec (line 34) | public final class ParameterSpec {
    method ParameterSpec (line 41) | private ParameterSpec(Builder builder) {
    method hasModifier (line 49) | public boolean hasModifier(Modifier modifier) {
    method emit (line 53) | void emit(CodeWriter codeWriter, boolean varargs) throws IOException {
    method equals (line 64) | @Override public boolean equals(Object o) {
    method hashCode (line 71) | @Override public int hashCode() {
    method toString (line 75) | @Override public String toString() {
    method get (line 86) | public static ParameterSpec get(VariableElement element) {
    method parametersOf (line 98) | static List<ParameterSpec> parametersOf(ExecutableElement method) {
    method isValidParameterName (line 106) | private static boolean isValidParameterName(String name) {
    method builder (line 115) | public static Builder builder(TypeName type, String name, Modifier... ...
    method builder (line 122) | public static Builder builder(Type type, String name, Modifier... modi...
    method toBuilder (line 126) | public Builder toBuilder() {
    method toBuilder (line 130) | Builder toBuilder(TypeName type, String name) {
    class Builder (line 137) | public static final class Builder {
      method Builder (line 145) | private Builder(TypeName type, String name) {
      method addJavadoc (line 150) | public Builder addJavadoc(String format, Object... args) {
      method addJavadoc (line 155) | public Builder addJavadoc(CodeBlock block) {
      method addAnnotations (line 160) | public Builder addAnnotations(Iterable<AnnotationSpec> annotationSpe...
      method addAnnotation (line 168) | public Builder addAnnotation(AnnotationSpec annotationSpec) {
      method addAnnotation (line 173) | public Builder addAnnotation(ClassName annotation) {
      method addAnnotation (line 178) | public Builder addAnnotation(Class<?> annotation) {
      method addModifiers (line 182) | public Builder addModifiers(Modifier... modifiers) {
      method addModifiers (line 187) | public Builder addModifiers(Iterable<Modifier> modifiers) {
      method build (line 198) | public ParameterSpec build() {

FILE: src/main/java/com/squareup/javapoet/ParameterizedTypeName.java
  class ParameterizedTypeName (line 31) | public final class ParameterizedTypeName extends TypeName {
    method ParameterizedTypeName (line 36) | ParameterizedTypeName(ParameterizedTypeName enclosingType, ClassName r...
    method ParameterizedTypeName (line 41) | private ParameterizedTypeName(ParameterizedTypeName enclosingType, Cla...
    method annotated (line 56) | @Override public ParameterizedTypeName annotated(List<AnnotationSpec> ...
    method withoutAnnotations (line 61) | @Override
    method emit (line 67) | @Override CodeWriter emit(CodeWriter out) throws IOException {
    method nestedClass (line 96) | public ParameterizedTypeName nestedClass(String name) {
    method nestedClass (line 106) | public ParameterizedTypeName nestedClass(String name, List<TypeName> t...
    method get (line 113) | public static ParameterizedTypeName get(ClassName rawType, TypeName......
    method get (line 118) | public static ParameterizedTypeName get(Class<?> rawType, Type... type...
    method get (line 123) | public static ParameterizedTypeName get(ParameterizedType type) {
    method get (line 128) | static ParameterizedTypeName get(ParameterizedType type, Map<Type, Typ...

FILE: src/main/java/com/squareup/javapoet/TypeName.java
  class TypeName (line 68) | public class TypeName {
    method TypeName (line 97) | private TypeName(String keyword) {
    method TypeName (line 101) | private TypeName(String keyword, List<AnnotationSpec> annotations) {
    method TypeName (line 107) | TypeName(List<AnnotationSpec> annotations) {
    method annotated (line 111) | public final TypeName annotated(AnnotationSpec... annotations) {
    method annotated (line 115) | public TypeName annotated(List<AnnotationSpec> annotations) {
    method withoutAnnotations (line 120) | public TypeName withoutAnnotations() {
    method concatAnnotations (line 127) | protected final List<AnnotationSpec> concatAnnotations(List<Annotation...
    method isAnnotated (line 133) | public boolean isAnnotated() {
    method isPrimitive (line 141) | public boolean isPrimitive() {
    method isBoxedPrimitive (line 149) | public boolean isBoxedPrimitive() {
    method box (line 165) | public TypeName box() {
    method unbox (line 187) | public TypeName unbox() {
    method equals (line 204) | @Override public final boolean equals(Object o) {
    method hashCode (line 211) | @Override public final int hashCode() {
    method toString (line 215) | @Override public final String toString() {
    method emit (line 231) | CodeWriter emit(CodeWriter out) throws IOException {
    method emitAnnotations (line 241) | CodeWriter emitAnnotations(CodeWriter out) throws IOException {
    method get (line 251) | public static TypeName get(TypeMirror mirror) {
    method get (line 255) | static TypeName get(TypeMirror mirror,
    method get (line 331) | public static TypeName get(Type type) {
    method get (line 335) | static TypeName get(Type type, Map<Type, TypeVariableName> map) {
    method list (line 368) | static List<TypeName> list(Type[] types) {
    method list (line 372) | static List<TypeName> list(Type[] types, Map<Type, TypeVariableName> m...
    method arrayComponent (line 381) | static TypeName arrayComponent(TypeName type) {
    method asArray (line 388) | static ArrayTypeName asArray(TypeName type) {

FILE: src/main/java/com/squareup/javapoet/TypeSpec.java
  class TypeSpec (line 48) | public final class TypeSpec {
    method TypeSpec (line 68) | private TypeSpec(Builder builder) {
    method TypeSpec (line 101) | private TypeSpec(TypeSpec type) {
    method hasModifier (line 123) | public boolean hasModifier(Modifier modifier) {
    method classBuilder (line 127) | public static Builder classBuilder(String name) {
    method classBuilder (line 131) | public static Builder classBuilder(ClassName className) {
    method interfaceBuilder (line 135) | public static Builder interfaceBuilder(String name) {
    method interfaceBuilder (line 139) | public static Builder interfaceBuilder(ClassName className) {
    method enumBuilder (line 143) | public static Builder enumBuilder(String name) {
    method enumBuilder (line 147) | public static Builder enumBuilder(ClassName className) {
    method anonymousClassBuilder (line 151) | public static Builder anonymousClassBuilder(String typeArgumentsFormat...
    method anonymousClassBuilder (line 155) | public static Builder anonymousClassBuilder(CodeBlock typeArguments) {
    method annotationBuilder (line 159) | public static Builder annotationBuilder(String name) {
    method annotationBuilder (line 163) | public static Builder annotationBuilder(ClassName className) {
    method toBuilder (line 167) | public Builder toBuilder() {
    method emit (line 186) | void emit(CodeWriter codeWriter, String enumName, Set<Modifier> implic...
    method equals (line 348) | @Override public boolean equals(Object o) {
    method hashCode (line 355) | @Override public int hashCode() {
    method toString (line 359) | @Override public String toString() {
    type Kind (line 370) | public enum Kind {
      method Kind (line 400) | Kind(Set<Modifier> implicitFieldModifiers,
    class Builder (line 411) | public static final class Builder {
      method Builder (line 432) | private Builder(Kind kind, String name,
      method addJavadoc (line 440) | public Builder addJavadoc(String format, Object... args) {
      method addJavadoc (line 445) | public Builder addJavadoc(CodeBlock block) {
      method addAnnotations (line 450) | public Builder addAnnotations(Iterable<AnnotationSpec> annotationSpe...
      method addAnnotation (line 458) | public Builder addAnnotation(AnnotationSpec annotationSpec) {
      method addAnnotation (line 464) | public Builder addAnnotation(ClassName annotation) {
      method addAnnotation (line 468) | public Builder addAnnotation(Class<?> annotation) {
      method addModifiers (line 472) | public Builder addModifiers(Modifier... modifiers) {
      method addTypeVariables (line 477) | public Builder addTypeVariables(Iterable<TypeVariableName> typeVaria...
      method addTypeVariable (line 485) | public Builder addTypeVariable(TypeVariableName typeVariable) {
      method superclass (line 490) | public Builder superclass(TypeName superclass) {
      method superclass (line 499) | public Builder superclass(Type superclass) {
      method superclass (line 503) | public Builder superclass(Type superclass, boolean avoidNestedTypeNa...
      method superclass (line 514) | public Builder superclass(TypeMirror superclass) {
      method superclass (line 518) | public Builder superclass(TypeMirror superclass, boolean avoidNested...
      method addSuperinterfaces (line 528) | public Builder addSuperinterfaces(Iterable<? extends TypeName> super...
      method addSuperinterface (line 536) | public Builder addSuperinterface(TypeName superinterface) {
      method addSuperinterface (line 542) | public Builder addSuperinterface(Type superinterface) {
      method addSuperinterface (line 546) | public Builder addSuperinterface(Type superinterface, boolean avoidN...
      method getRawType (line 557) | private Class<?> getRawType(Type type) {
      method addSuperinterface (line 567) | public Builder addSuperinterface(TypeMirror superinterface) {
      method addSuperinterface (line 571) | public Builder addSuperinterface(TypeMirror superinterface,
      method addEnumConstant (line 582) | public Builder addEnumConstant(String name) {
      method addEnumConstant (line 586) | public Builder addEnumConstant(String name, TypeSpec typeSpec) {
      method addFields (line 591) | public Builder addFields(Iterable<FieldSpec> fieldSpecs) {
      method addField (line 599) | public Builder addField(FieldSpec fieldSpec) {
      method addField (line 604) | public Builder addField(TypeName type, String name, Modifier... modi...
      method addField (line 608) | public Builder addField(Type type, String name, Modifier... modifier...
      method addStaticBlock (line 612) | public Builder addStaticBlock(CodeBlock block) {
      method addInitializerBlock (line 617) | public Builder addInitializerBlock(CodeBlock block) {
      method addMethods (line 629) | public Builder addMethods(Iterable<MethodSpec> methodSpecs) {
      method addMethod (line 637) | public Builder addMethod(MethodSpec methodSpec) {
      method addTypes (line 642) | public Builder addTypes(Iterable<TypeSpec> typeSpecs) {
      method addType (line 650) | public Builder addType(TypeSpec typeSpec) {
      method addOriginatingElement (line 655) | public Builder addOriginatingElement(Element originatingElement) {
      method alwaysQualify (line 660) | public Builder alwaysQualify(String... simpleNames) {
      method avoidClashesWithNestedClasses (line 697) | public Builder avoidClashesWithNestedClasses(TypeElement typeElement) {
      method avoidClashesWithNestedClasses (line 741) | public Builder avoidClashesWithNestedClasses(Class<?> clazz) {
      method build (line 756) | public TypeSpec build() {

FILE: src/main/java/com/squareup/javapoet/TypeVariableName.java
  class TypeVariableName (line 34) | public final class TypeVariableName extends TypeName {
    method TypeVariableName (line 38) | private TypeVariableName(String name, List<TypeName> bounds) {
    method TypeVariableName (line 42) | private TypeVariableName(String name, List<TypeName> bounds, List<Anno...
    method annotated (line 52) | @Override public TypeVariableName annotated(List<AnnotationSpec> annot...
    method withoutAnnotations (line 56) | @Override public TypeName withoutAnnotations() {
    method withBounds (line 60) | public TypeVariableName withBounds(Type... bounds) {
    method withBounds (line 64) | public TypeVariableName withBounds(TypeName... bounds) {
    method withBounds (line 68) | public TypeVariableName withBounds(List<? extends TypeName> bounds) {
    method of (line 75) | private static TypeVariableName of(String name, List<TypeName> bounds) {
    method emit (line 82) | @Override CodeWriter emit(CodeWriter out) throws IOException {
    method get (line 88) | public static TypeVariableName get(String name) {
    method get (line 93) | public static TypeVariableName get(String name, TypeName... bounds) {
    method get (line 98) | public static TypeVariableName get(String name, Type... bounds) {
    method get (line 103) | public static TypeVariableName get(TypeVariable mirror) {
    method get (line 115) | static TypeVariableName get(
    method get (line 135) | public static TypeVariableName get(TypeParameterElement element) {
    method get (line 148) | public static TypeVariableName get(java.lang.reflect.TypeVariable<?> t...
    method get (line 153) | static TypeVariableName get(java.lang.reflect.TypeVariable<?> type,

FILE: src/main/java/com/squareup/javapoet/Util.java
  class Util (line 35) | final class Util {
    method Util (line 36) | private Util() {
    method immutableMultimap (line 39) | static <K, V> Map<K, List<V>> immutableMultimap(Map<K, List<V>> multim...
    method immutableMap (line 48) | static <K, V> Map<K, V> immutableMap(Map<K, V> map) {
    method checkArgument (line 52) | static void checkArgument(boolean condition, String format, Object... ...
    method checkNotNull (line 56) | static <T> T checkNotNull(T reference, String format, Object... args) {
    method checkState (line 61) | static void checkState(boolean condition, String format, Object... arg...
    method immutableList (line 65) | static <T> List<T> immutableList(Collection<T> collection) {
    method immutableSet (line 69) | static <T> Set<T> immutableSet(Collection<T> set) {
    method union (line 73) | static <T> Set<T> union(Set<T> a, Set<T> b) {
    method requireExactlyOneOf (line 80) | static void requireExactlyOneOf(Set<Modifier> modifiers, Modifier... m...
    method characterLiteralWithoutSingleQuotes (line 89) | static String characterLiteralWithoutSingleQuotes(char c) {
    method stringLiteralWithDoubleQuotes (line 106) | static String stringLiteralWithDoubleQuotes(String value, String inden...

FILE: src/main/java/com/squareup/javapoet/WildcardTypeName.java
  class WildcardTypeName (line 31) | public final class WildcardTypeName extends TypeName {
    method WildcardTypeName (line 35) | private WildcardTypeName(List<TypeName> upperBounds, List<TypeName> lo...
    method WildcardTypeName (line 39) | private WildcardTypeName(List<TypeName> upperBounds, List<TypeName> lo...
    method annotated (line 56) | @Override public WildcardTypeName annotated(List<AnnotationSpec> annot...
    method withoutAnnotations (line 60) | @Override public TypeName withoutAnnotations() {
    method emit (line 64) | @Override CodeWriter emit(CodeWriter out) throws IOException {
    method subtypeOf (line 79) | public static WildcardTypeName subtypeOf(TypeName upperBound) {
    method subtypeOf (line 83) | public static WildcardTypeName subtypeOf(Type upperBound) {
    method supertypeOf (line 91) | public static WildcardTypeName supertypeOf(TypeName lowerBound) {
    method supertypeOf (line 96) | public static WildcardTypeName supertypeOf(Type lowerBound) {
    method get (line 100) | public static TypeName get(javax.lang.model.type.WildcardType mirror) {
    method get (line 104) | static TypeName get(
    method get (line 120) | public static TypeName get(WildcardType wildcardName) {
    method get (line 124) | static TypeName get(WildcardType wildcardName, Map<Type, TypeVariableN...

FILE: src/test/java/ClassNameNoPackageTest.java
  class ClassNameNoPackageTest (line 26) | public final class ClassNameNoPackageTest {
    method shouldSupportClassInDefaultPackage (line 27) | @Test public void shouldSupportClassInDefaultPackage() {

FILE: src/test/java/com/squareup/javapoet/AbstractTypesTest.java
  class AbstractTypesTest (line 52) | public abstract class AbstractTypesTest {
    method getElements (line 53) | protected abstract Elements getElements();
    method getTypes (line 54) | protected abstract Types getTypes();
    method getElement (line 56) | private TypeElement getElement(Class<?> clazz) {
    method getMirror (line 60) | private TypeMirror getMirror(Class<?> clazz) {
    method getBasicTypeMirror (line 64) | @Test public void getBasicTypeMirror() {
    method getParameterizedTypeMirror (line 73) | @Test public void getParameterizedTypeMirror() {
    method errorTypes (line 80) | @Test public void errorTypes() {
    class Parameterized (line 114) | static class Parameterized<
    method getTypeVariableTypeMirror (line 122) | @Test public void getTypeVariableTypeMirror() {
    class Recursive (line 147) | static class Recursive<T extends Map<List<T>, Set<T[]>>> {}
    method getTypeVariableTypeMirrorRecursive (line 149) | @Test
    method getPrimitiveTypeMirror (line 169) | @Test public void getPrimitiveTypeMirror() {
    method getArrayTypeMirror (line 188) | @Test public void getArrayTypeMirror() {
    method getVoidTypeMirror (line 193) | @Test public void getVoidTypeMirror() {
    method getNullTypeMirror (line 198) | @Test public void getNullTypeMirror() {
    method parameterizedType (line 206) | @Test public void parameterizedType() throws Exception {
    method arrayType (line 211) | @Test public void arrayType() throws Exception {
    method wildcardExtendsType (line 216) | @Test public void wildcardExtendsType() throws Exception {
    method wildcardExtendsObject (line 221) | @Test public void wildcardExtendsObject() throws Exception {
    method wildcardSuperType (line 226) | @Test public void wildcardSuperType() throws Exception {
    method wildcardMirrorNoBounds (line 231) | @Test public void wildcardMirrorNoBounds() throws Exception {
    method wildcardMirrorExtendsType (line 237) | @Test public void wildcardMirrorExtendsType() throws Exception {
    method wildcardMirrorSuperType (line 246) | @Test public void wildcardMirrorSuperType() throws Exception {
    method typeVariable (line 255) | @Test public void typeVariable() throws Exception {
    method box (line 260) | @Test public void box() throws Exception {
    method unbox (line 269) | @Test public void unbox() throws Exception {

FILE: src/test/java/com/squareup/javapoet/AnnotatedTypeNameTest.java
  class AnnotatedTypeNameTest (line 30) | public class AnnotatedTypeNameTest {
    method nullAnnotationArray (line 45) | @Test(expected=NullPointerException.class) public void nullAnnotationA...
    method nullAnnotationList (line 49) | @Test(expected=NullPointerException.class) public void nullAnnotationL...
    method annotated (line 53) | @Test public void annotated() {
    method annotatedType (line 63) | @Test public void annotatedType() {
    method annotatedTwice (line 69) | @Test public void annotatedTwice() {
    method annotatedParameterizedType (line 78) | @Test public void annotatedParameterizedType() {
    method annotatedArgumentOfParameterizedType (line 84) | @Test public void annotatedArgumentOfParameterizedType() {
    method annotatedWildcardTypeNameWithSuper (line 90) | @Test public void annotatedWildcardTypeNameWithSuper() {
    method annotatedWildcardTypeNameWithExtends (line 96) | @Test public void annotatedWildcardTypeNameWithExtends() {
    method annotatedEquivalence (line 102) | @Test public void annotatedEquivalence() {
    method annotatedEquivalence (line 111) | private void annotatedEquivalence(TypeName type) {
    method annotatedNestedType (line 123) | @Test public void annotatedNestedType() {
    method annotatedEnclosingAndNestedType (line 128) | @Test public void annotatedEnclosingAndNestedType() {
    method annotatedNestedParameterizedType (line 135) | @Test public void annotatedNestedParameterizedType() {
    method withoutAnnotationsOnAnnotatedEnclosingAndNestedType (line 142) | @Test public void withoutAnnotationsOnAnnotatedEnclosingAndNestedType() {
    method withoutAnnotationsOnAnnotatedEnclosingType (line 149) | @Test public void withoutAnnotationsOnAnnotatedEnclosingType() {
    method withoutAnnotationsOnAnnotatedNestedType (line 156) | @Test public void withoutAnnotationsOnAnnotatedNestedType() {
    method annotatedArrayType (line 164) | @Test public void annotatedArrayType() {
    method annotatedArrayElementType (line 169) | @Test public void annotatedArrayElementType() {
    method annotatedOuterMultidimensionalArrayType (line 175) | @Test public void annotatedOuterMultidimensionalArrayType() {
    method annotatedInnerMultidimensionalArrayType (line 182) | @Test public void annotatedInnerMultidimensionalArrayType() {
    method annotatedArrayTypeVarargsParameter (line 189) | @Test public void annotatedArrayTypeVarargsParameter() {
    method annotatedArrayTypeInVarargsParameter (line 204) | @Test public void annotatedArrayTypeInVarargsParameter() {

FILE: src/test/java/com/squareup/javapoet/AnnotationSpecTest.java
  class AnnotationSpecTest (line 32) | public final class AnnotationSpecTest {
    type Breakfast (line 48) | public enum Breakfast {
      method toString (line 50) | public String toString() { return name() + " with cherries!"; }
    class IsAnnotated (line 94) | @HasDefaultsAnnotation(
    method equalsAndHashCode (line 109) | @Test public void equalsAndHashCode() {
    method defaultAnnotation (line 120) | @Test public void defaultAnnotation() {
    method defaultAnnotationWithImport (line 157) | @Test public void defaultAnnotationWithImport() {
    method emptyArray (line 193) | @Test public void emptyArray() {
    method dynamicArrayOfEnumConstants (line 206) | @Test public void dynamicArrayOfEnumConstants() {
    method defaultAnnotationToBuilder (line 245) | @Test public void defaultAnnotationToBuilder() {
    method reflectAnnotation (line 264) | @Test public void reflectAnnotation() {
    method reflectAnnotationWithDefaults (line 298) | @Test public void reflectAnnotationWithDefaults() {
    method disallowsNullMemberName (line 356) | @Test public void disallowsNullMemberName() {
    method requiresValidMemberName (line 366) | @Test public void requiresValidMemberName() {
    method modifyMembers (line 376) | @Test public void modifyMembers() {
    method toString (line 386) | private String toString(TypeSpec typeSpec) {

FILE: src/test/java/com/squareup/javapoet/ClassNameTest.java
  class ClassNameTest (line 33) | @RunWith(JUnit4.class)
    method bestGuessForString_simpleClass (line 37) | @Test public void bestGuessForString_simpleClass() {
    method bestGuessNonAscii (line 42) | @Test public void bestGuessNonAscii() {
    class OuterClass (line 49) | static class OuterClass {
      class InnerClass (line 50) | static class InnerClass {}
    method bestGuessForString_nestedClass (line 53) | @Test public void bestGuessForString_nestedClass() {
    method bestGuessForString_defaultPackage (line 61) | @Test public void bestGuessForString_defaultPackage() {
    method bestGuessForString_confusingInput (line 70) | @Test public void bestGuessForString_confusingInput() {
    method assertBestGuessThrows (line 85) | private void assertBestGuessThrows(String s) {
    method createNestedClass (line 93) | @Test public void createNestedClass() {
    class $Outer (line 101) | static class $Outer {
      class $Inner (line 102) | static class $Inner {}
    method classNameFromTypeElement (line 105) | @Test public void classNameFromTypeElement() {
    method classNameFromTypeElementDoesntUseGetKind (line 119) | @Test public void classNameFromTypeElementDoesntUseGetKind() {
    method preventGetKind (line 133) | private TypeElement preventGetKind(TypeElement object) {
    method classNameFromClass (line 145) | @Test public void classNameFromClass() {
    method peerClass (line 160) | @Test public void peerClass() {
    method fromClassRejectionTypes (line 169) | @Test public void fromClassRejectionTypes() {
    method reflectionName (line 187) | @Test
    method canonicalName (line 197) | @Test

FILE: src/test/java/com/squareup/javapoet/CodeBlockTest.java
  class CodeBlockTest (line 29) | public final class CodeBlockTest {
    method equalsAndHashCode (line 30) | @Test public void equalsAndHashCode() {
    method of (line 41) | @Test public void of() {
    method isEmpty (line 46) | @Test public void isEmpty() {
    method indentCannotBeIndexed (line 52) | @Test public void indentCannotBeIndexed() {
    method deindentCannotBeIndexed (line 63) | @Test public void deindentCannotBeIndexed() {
    method dollarSignEscapeCannotBeIndexed (line 74) | @Test public void dollarSignEscapeCannotBeIndexed() {
    method statementBeginningCannotBeIndexed (line 85) | @Test public void statementBeginningCannotBeIndexed() {
    method statementEndingCannotBeIndexed (line 96) | @Test public void statementEndingCannotBeIndexed() {
    method nameFormatCanBeIndexed (line 107) | @Test public void nameFormatCanBeIndexed() {
    method literalFormatCanBeIndexed (line 112) | @Test public void literalFormatCanBeIndexed() {
    method stringFormatCanBeIndexed (line 117) | @Test public void stringFormatCanBeIndexed() {
    method typeFormatCanBeIndexed (line 122) | @Test public void typeFormatCanBeIndexed() {
    method simpleNamedArgument (line 127) | @Test public void simpleNamedArgument() {
    method repeatedNamedArgument (line 134) | @Test public void repeatedNamedArgument() {
    method namedAndNoArgFormat (line 144) | @Test public void namedAndNoArgFormat() {
    method missingNamedArgument (line 152) | @Test public void missingNamedArgument() {
    method lowerCaseNamed (line 162) | @Test public void lowerCaseNamed() {
    method multipleNamedArguments (line 173) | @Test public void multipleNamedArguments() {
    method namedNewline (line 186) | @Test public void namedNewline() {
    method danglingNamed (line 193) | @Test public void danglingNamed() {
    method indexTooHigh (line 204) | @Test public void indexTooHigh() {
    method indexIsZero (line 213) | @Test public void indexIsZero() {
    method indexIsNegative (line 222) | @Test public void indexIsNegative() {
    method indexWithoutFormatType (line 231) | @Test public void indexWithoutFormatType() {
    method indexWithoutFormatTypeNotAtStringEnd (line 240) | @Test public void indexWithoutFormatTypeNotAtStringEnd() {
    method indexButNoArguments (line 249) | @Test public void indexButNoArguments() {
    method formatIndicatorAlone (line 258) | @Test public void formatIndicatorAlone() {
    method formatIndicatorWithoutIndexOrFormatType (line 267) | @Test public void formatIndicatorWithoutIndexOrFormatType() {
    method sameIndexCanBeUsedWithDifferentFormats (line 276) | @Test public void sameIndexCanBeUsedWithDifferentFormats() {
    method tooManyStatementEnters (line 283) | @Test public void tooManyStatementEnters() {
    method statementExitWithoutStatementEnter (line 294) | @Test public void statementExitWithoutStatementEnter() {
    method join (line 305) | @Test public void join() {
    method joining (line 315) | @Test public void joining() {
    method joiningSingle (line 325) | @Test public void joiningSingle() {
    method joiningWithPrefixAndSuffix (line 333) | @Test public void joiningWithPrefixAndSuffix() {
    method clear (line 343) | @Test public void clear() {

FILE: src/test/java/com/squareup/javapoet/CodeWriterTest.java
  class CodeWriterTest (line 9) | public class CodeWriterTest {
    method emptyLineInJavaDocDosEndings (line 11) | @Test

FILE: src/test/java/com/squareup/javapoet/FieldSpecTest.java
  class FieldSpecTest (line 25) | public class FieldSpecTest {
    method equalsAndHashCode (line 26) | @Test public void equalsAndHashCode() {
    method nullAnnotationsAddition (line 39) | @Test public void nullAnnotationsAddition() {
    method modifyAnnotations (line 50) | @Test public void modifyAnnotations() {
    method modifyModifiers (line 59) | @Test public void modifyModifiers() {

FILE: src/test/java/com/squareup/javapoet/FileReadingTest.java
  class FileReadingTest (line 42) | @RunWith(JUnit4.class)
    method javaFileObjectUri (line 48) | @Test public void javaFileObjectUri() {
    method javaFileObjectKind (line 58) | @Test public void javaFileObjectKind() {
    method javaFileObjectCharacterContent (line 63) | @Test public void javaFileObjectCharacterContent() throws IOException {
    method javaFileObjectInputStreamIsUtf8 (line 76) | @Test public void javaFileObjectInputStreamIsUtf8() throws IOException {
    method compileJavaFile (line 86) | @Test public void compileJavaFile() throws Exception {

FILE: src/test/java/com/squareup/javapoet/FileWritingTest.java
  class FileWritingTest (line 39) | @RunWith(JUnit4.class)
    method pathNotDirectory (line 51) | @Test public void pathNotDirectory() throws IOException {
    method fileNotDirectory (line 65) | @Test public void fileNotDirectory() throws IOException {
    method pathDefaultPackage (line 79) | @Test public void pathDefaultPackage() throws IOException {
    method fileDefaultPackage (line 87) | @Test public void fileDefaultPackage() throws IOException {
    method filerDefaultPackage (line 95) | @Test public void filerDefaultPackage() throws IOException {
    method pathNestedClasses (line 103) | @Test public void pathNestedClasses() throws IOException {
    method fileNestedClasses (line 117) | @Test public void fileNestedClasses() throws IOException {
    method filerNestedClasses (line 134) | @Test public void filerNestedClasses() throws IOException {
    method filerPassesOriginatingElements (line 148) | @Test public void filerPassesOriginatingElements() throws IOException {
    method filerClassesWithTabIndent (line 170) | @Test public void filerClassesWithTabIndent() throws IOException {
    method fileIsUtf8 (line 205) | @Test public void fileIsUtf8() throws IOException {
    method writeToPathReturnsPath (line 220) | @Test public void writeToPathReturnsPath() throws IOException {

FILE: src/test/java/com/squareup/javapoet/JavaFileTest.java
  class JavaFileTest (line 37) | @RunWith(JUnit4.class)
    method getElement (line 42) | private TypeElement getElement(Class<?> clazz) {
    method importStaticReadmeExample (line 46) | @Test public void importStaticReadmeExample() {
    method importStaticForCrazyFormatsWorks (line 91) | @Test public void importStaticForCrazyFormatsWorks() {
    method importStaticMixed (line 115) | @Test public void importStaticMixed() {
    method importStaticDynamic (line 153) | @Ignore("addStaticImport doesn't support members with $L")
    method importStaticNone (line 175) | @Test public void importStaticNone() {
    method importStaticOnce (line 191) | @Test public void importStaticOnce() {
    method importStaticTwice (line 210) | @Test public void importStaticTwice() {
    method importStaticUsingWildcards (line 230) | @Test public void importStaticUsingWildcards() {
    method importStaticTypeSpec (line 248) | private TypeSpec importStaticTypeSpec(String name) {
    method noImports (line 259) | @Test public void noImports() throws Exception {
    method singleImport (line 271) | @Test public void singleImport() throws Exception {
    method conflictingImports (line 288) | @Test public void conflictingImports() throws Exception {
    method annotatedTypeParam (line 308) | @Test public void annotatedTypeParam() throws Exception {
    method skipJavaLangImportsWithConflictingClassLast (line 329) | @Test public void skipJavaLangImportsWithConflictingClassLast() throws...
    method skipJavaLangImportsWithConflictingClassFirst (line 349) | @Test public void skipJavaLangImportsWithConflictingClassFirst() throw...
    method conflictingParentName (line 371) | @Test public void conflictingParentName() throws Exception {
    method conflictingChildName (line 407) | @Test public void conflictingChildName() throws Exception {
    method conflictingNameOutOfScope (line 443) | @Test public void conflictingNameOutOfScope() throws Exception {
    method nestedClassAndSuperclassShareName (line 483) | @Test public void nestedClassAndSuperclassShareName() throws Exception {
    method classAndSuperclassShareName (line 504) | @Test public void classAndSuperclassShareName() throws Exception {
    method conflictingAnnotation (line 518) | @Test public void conflictingAnnotation() throws Exception {
    method conflictingAnnotationReferencedClass (line 533) | @Test public void conflictingAnnotationReferencedClass() throws Except...
    method conflictingTypeVariableBound (line 550) | @Test public void conflictingTypeVariableBound() throws Exception {
    method superclassReferencesSelf (line 565) | @Test public void superclassReferencesSelf() throws Exception {
    method annotationIsNestedClass (line 583) | @Test public void annotationIsNestedClass() throws Exception {
    method defaultPackage (line 606) | @Test public void defaultPackage() throws Exception {
    method defaultPackageTypesAreNotImported (line 628) | @Test public void defaultPackageTypesAreNotImported() throws Exception {
    method topOfFileComment (line 640) | @Test public void topOfFileComment() throws Exception {
    method emptyLinesInTopOfFileComment (line 654) | @Test public void emptyLinesInTopOfFileComment() throws Exception {
    method packageClassConflictsWithNestedClass (line 672) | @Test public void packageClassConflictsWithNestedClass() throws Except...
    method packageClassConflictsWithSuperlass (line 691) | @Test public void packageClassConflictsWithSuperlass() throws Exception {
    method modifyStaticImports (line 707) | @Test public void modifyStaticImports() throws Exception {
    method alwaysQualifySimple (line 727) | @Test public void alwaysQualifySimple() {
    method alwaysQualifySupersedesJavaLangImports (line 743) | @Test public void alwaysQualifySupersedesJavaLangImports() {
    method avoidClashesWithNestedClasses_viaClass (line 760) | @Test public void avoidClashesWithNestedClasses_viaClass() {
    method avoidClashesWithNestedClasses_viaTypeElement (line 791) | @Test public void avoidClashesWithNestedClasses_viaTypeElement() {
    method avoidClashesWithNestedClasses_viaSuperinterfaceType (line 822) | @Test public void avoidClashesWithNestedClasses_viaSuperinterfaceType() {
    class Foo (line 861) | static class Foo {
      class NestedTypeA (line 862) | static class NestedTypeA {
      class NestedTypeB (line 865) | static class NestedTypeB {
    type FooInterface (line 870) | interface FooInterface {
      class NestedTypeA (line 871) | class NestedTypeA {
      class NestedTypeB (line 874) | class NestedTypeB {
    method childTypeBuilder (line 879) | private TypeSpec.Builder childTypeBuilder() {
    method avoidClashes_parentChild_superclass_type (line 891) | @Test
    method avoidClashes_parentChild_superclass_typeMirror (line 912) | @Test
    method avoidClashes_parentChild_superinterface_type (line 933) | @Test
    method avoidClashes_parentChild_superinterface_typeMirror (line 955) | @Test
    class Parent (line 979) | static class Parent implements ParentInterface {
      class Pattern (line 980) | static class Pattern {
    type ParentInterface (line 985) | interface ParentInterface {
      class Optional (line 986) | class Optional {
    method avoidClashes_mapEntry (line 992) | @Test

FILE: src/test/java/com/squareup/javapoet/LineWrapperTest.java
  class LineWrapperTest (line 24) | @RunWith(JUnit4.class)
    method wrap (line 26) | @Test public void wrap() throws Exception {
    method noWrap (line 36) | @Test public void noWrap() throws Exception {
    method zeroWidthNoWrap (line 46) | @Test public void zeroWidthNoWrap() throws Exception {
    method nospaceWrapMax (line 56) | @Test public void nospaceWrapMax() throws Exception {
    method multipleWrite (line 66) | @Test public void multipleWrite() throws Exception {
    method fencepost (line 90) | @Test public void fencepost() throws Exception {
    method fencepostZeroWidth (line 102) | @Test public void fencepostZeroWidth() throws Exception {
    method overlyLongLinesWithoutLeadingSpace (line 114) | @Test public void overlyLongLinesWithoutLeadingSpace() throws Exception {
    method overlyLongLinesWithLeadingSpace (line 122) | @Test public void overlyLongLinesWithLeadingSpace() throws Exception {
    method overlyLongLinesWithLeadingZeroWidth (line 131) | @Test public void overlyLongLinesWithLeadingZeroWidth() throws Excepti...
    method noWrapEmbeddedNewlines (line 140) | @Test public void noWrapEmbeddedNewlines() throws Exception {
    method wrapEmbeddedNewlines (line 151) | @Test public void wrapEmbeddedNewlines() throws Exception {
    method noWrapEmbeddedNewlines_ZeroWidth (line 162) | @Test public void noWrapEmbeddedNewlines_ZeroWidth() throws Exception {
    method wrapEmbeddedNewlines_ZeroWidth (line 173) | @Test public void wrapEmbeddedNewlines_ZeroWidth() throws Exception {
    method noWrapMultipleNewlines (line 184) | @Test public void noWrapMultipleNewlines() throws Exception {
    method wrapMultipleNewlines (line 196) | @Test public void wrapMultipleNewlines() throws Exception {

FILE: src/test/java/com/squareup/javapoet/MethodSpecTest.java
  class MethodSpecTest (line 51) | public final class MethodSpecTest {
    method setUp (line 57) | @Before public void setUp() {
    method getElement (line 62) | private TypeElement getElement(Class<?> clazz) {
    method nullAnnotationsAddition (line 66) | @Test public void nullAnnotationsAddition() {
    method nullTypeVariablesAddition (line 75) | @Test public void nullTypeVariablesAddition() {
    method nullParametersAddition (line 84) | @Test public void nullParametersAddition() {
    method nullExceptionsAddition (line 93) | @Test public void nullExceptionsAddition() {
    class Everything (line 106) | abstract static class Everything {
      method everything (line 107) | @Deprecated protected abstract <T extends Runnable & Closeable> Runn...
    class Generics (line 111) | abstract static class Generics {
      method run (line 112) | <T, R, V extends Throwable> T run(R param) throws V {
    class HasAnnotation (line 117) | abstract static class HasAnnotation {
      method toString (line 118) | @Override public abstract String toString();
    type Throws (line 121) | interface Throws<R extends RuntimeException> {
      method fail (line 122) | void fail() throws R;
    type ExtendsOthers (line 125) | interface ExtendsOthers extends Callable<Integer>, Comparable<ExtendsO...
    type ExtendsIterableWithDefaultMethods (line 129) | interface ExtendsIterableWithDefaultMethods extends Iterable<Object> {
    class FinalClass (line 132) | final class FinalClass {
      method method (line 133) | void method() {
    class InvalidOverrideMethods (line 137) | abstract static class InvalidOverrideMethods {
      method finalMethod (line 138) | final void finalMethod() {
      method privateMethod (line 141) | private void privateMethod() {
      method staticMethod (line 144) | static void staticMethod() {
    method overrideEverything (line 148) | @Test public void overrideEverything() {
    method overrideGenerics (line 161) | @Test public void overrideGenerics() {
    method overrideDoesNotCopyOverrideAnnotation (line 174) | @Test public void overrideDoesNotCopyOverrideAnnotation() {
    method overrideDoesNotCopyDefaultModifier (line 184) | @Test public void overrideDoesNotCopyDefaultModifier() {
    method overrideExtendsOthersWorksWithActualTypeParameters (line 196) | @Test public void overrideExtendsOthersWorksWithActualTypeParameters() {
    method overrideFinalClassMethod (line 220) | @Test public void overrideFinalClassMethod() {
    method overrideInvalidModifiers (line 232) | @Test public void overrideInvalidModifiers() {
    class AbstractClassWithPrivateAnnotation (line 255) | abstract static class AbstractClassWithPrivateAnnotation {
      method foo (line 259) | abstract void foo(@PrivateAnnotation final String bar);
    method overrideDoesNotCopyParameterAnnotations (line 262) | @Test public void overrideDoesNotCopyParameterAnnotations() {
    method equalsAndHashCode (line 275) | @Test public void equalsAndHashCode() {
    method withoutParameterJavaDoc (line 292) | @Test public void withoutParameterJavaDoc() {
    method withParameterJavaDoc (line 306) | @Test public void withParameterJavaDoc() {
    method withParameterJavaDocAndWithoutMethodJavadoc (line 327) | @Test public void withParameterJavaDocAndWithoutMethodJavadoc() {
    method duplicateExceptionsIgnored (line 345) | @Test public void duplicateExceptionsIgnored() {
    method nullIsNotAValidMethodName (line 359) | @Test public void nullIsNotAValidMethodName() {
    method addModifiersVarargsShouldNotBeNull (line 368) | @Test public void addModifiersVarargsShouldNotBeNull() {
    method modifyMethodName (line 378) | @Test public void modifyMethodName() {
    method modifyAnnotations (line 388) | @Test public void modifyAnnotations() {
    method modifyModifiers (line 397) | @Test public void modifyModifiers() {
    method modifyParameters (line 405) | @Test public void modifyParameters() {
    method modifyTypeVariables (line 413) | @Test public void modifyTypeVariables() {
    method ensureTrailingNewline (line 423) | @Test public void ensureTrailingNewline() {
    method ensureTrailingNewlineWithExistingNewline (line 435) | @Test public void ensureTrailingNewlineWithExistingNewline() {
    method controlFlowWithNamedCodeBlocks (line 446) | @Test public void controlFlowWithNamedCodeBlocks() {
    method doWhileWithNamedCodeBlocks (line 465) | @Test public void doWhileWithNamedCodeBlocks() {
    method named (line 484) | private static CodeBlock named(String format, Map<String, ?> args){

FILE: src/test/java/com/squareup/javapoet/NameAllocatorTest.java
  class NameAllocatorTest (line 24) | public final class NameAllocatorTest {
    method usage (line 26) | @Test public void usage() throws Exception {
    method nameCollision (line 34) | @Test public void nameCollision() throws Exception {
    method nameCollisionWithTag (line 41) | @Test public void nameCollisionWithTag() throws Exception {
    method characterMappingSubstitute (line 51) | @Test public void characterMappingSubstitute() throws Exception {
    method characterMappingSurrogate (line 56) | @Test public void characterMappingSurrogate() throws Exception {
    method characterMappingInvalidStartButValidPart (line 61) | @Test public void characterMappingInvalidStartButValidPart() throws Ex...
    method characterMappingInvalidStartIsInvalidPart (line 67) | @Test public void characterMappingInvalidStartIsInvalidPart() throws E...
    method javaKeyword (line 72) | @Test public void javaKeyword() throws Exception {
    method tagReuseForbidden (line 78) | @Test public void tagReuseForbidden() throws Exception {
    method useBeforeAllocateForbidden (line 89) | @Test public void useBeforeAllocateForbidden() throws Exception {
    method cloneUsage (line 99) | @Test public void cloneUsage() throws Exception {

FILE: src/test/java/com/squareup/javapoet/ParameterSpecTest.java
  class ParameterSpecTest (line 37) | public class ParameterSpecTest {
    method setUp (line 42) | @Before public void setUp() {
    method getElement (line 46) | private TypeElement getElement(Class<?> clazz) {
    method equalsAndHashCode (line 50) | @Test public void equalsAndHashCode() {
    method receiverParameterInstanceMethod (line 63) | @Test public void receiverParameterInstanceMethod() {
    method receiverParameterNestedClass (line 68) | @Test public void receiverParameterNestedClass() {
    method keywordName (line 73) | @Test public void keywordName() {
    method nullAnnotationsAddition (line 82) | @Test public void nullAnnotationsAddition() {
    class VariableElementFieldClass (line 92) | final class VariableElementFieldClass {
    method fieldVariableElement (line 96) | @Test public void fieldVariableElement() {
    class VariableElementParameterClass (line 109) | final class VariableElementParameterClass {
      method foo (line 110) | public void foo(@Nullable final String bar) {
    method parameterVariableElement (line 114) | @Test public void parameterVariableElement() {
    method addNonFinalModifier (line 124) | @Test public void addNonFinalModifier() {
    method modifyAnnotations (line 138) | @Test public void modifyAnnotations() {
    method modifyModifiers (line 147) | @Test public void modifyModifiers() {

FILE: src/test/java/com/squareup/javapoet/TestFiler.java
  class TestFiler (line 35) | final class TestFiler implements Filer {
    class Source (line 36) | class Source extends SimpleJavaFileObject {
      method Source (line 38) | protected Source(Path path) {
      method openOutputStream (line 42) | @Override public OutputStream openOutputStream() throws IOException {
    method TestFiler (line 54) | public TestFiler(FileSystem fileSystem, Path fsRoot) {
    method getOriginatingElements (line 61) | public Set<Element> getOriginatingElements(Path path) {
    method createSourceFile (line 65) | @Override public JavaFileObject createSourceFile(
    method createClassFile (line 73) | @Override public JavaFileObject createClassFile(CharSequence name, Ele...
    method createResource (line 78) | @Override public FileObject createResource(JavaFileManager.Location lo...
    method getResource (line 83) | @Override public FileObject getResource(JavaFileManager.Location locat...

FILE: src/test/java/com/squareup/javapoet/TestUtil.java
  class TestUtil (line 8) | final class TestUtil {
    method findFirst (line 9) | static <E extends Element> E findFirst(Collection<E> elements, String ...

FILE: src/test/java/com/squareup/javapoet/TypeNameTest.java
  class TypeNameTest (line 32) | public class TypeNameTest {
    method generic (line 36) | protected <E extends Enum<E>> E generic(E[] values) {
    class TestGeneric (line 40) | protected static class TestGeneric<T> {
      class Inner (line 41) | class Inner {}
      class InnerGeneric (line 43) | class InnerGeneric<T2> {}
      class NestedNonGeneric (line 45) | static class NestedNonGeneric {}
    method testGenericStringInner (line 48) | protected static TestGeneric<String>.Inner testGenericStringInner() {
    method testGenericIntInner (line 52) | protected static TestGeneric<Integer>.Inner testGenericIntInner() {
    method testGenericInnerLong (line 56) | protected static TestGeneric<Short>.InnerGeneric<Long> testGenericInne...
    method testGenericInnerInt (line 60) | protected static TestGeneric<Short>.InnerGeneric<Integer> testGenericI...
    method testNestedNonGeneric (line 64) | protected static TestGeneric.NestedNonGeneric testNestedNonGeneric() {
    method genericType (line 68) | @Test public void genericType() throws Exception {
    method innerClassInGenericType (line 79) | @Test public void innerClassInGenericType() throws Exception {
    method innerGenericInGenericType (line 91) | @Test public void innerGenericInGenericType() throws Exception {
    method innerStaticInGenericType (line 103) | @Test public void innerStaticInGenericType() throws Exception {
    method equalsAndHashCodePrimitive (line 113) | @Test public void equalsAndHashCodePrimitive() {
    method equalsAndHashCodeArrayTypeName (line 125) | @Test public void equalsAndHashCodeArrayTypeName() {
    method equalsAndHashCodeClassName (line 132) | @Test public void equalsAndHashCodeClassName() {
    method equalsAndHashCodeParameterizedTypeName (line 139) | @Test public void equalsAndHashCodeParameterizedTypeName() {
    method equalsAndHashCodeTypeVariableName (line 148) | @Test public void equalsAndHashCodeTypeVariableName() {
    method equalsAndHashCodeWildcardTypeName (line 156) | @Test public void equalsAndHashCodeWildcardTypeName() {
    method isPrimitive (line 165) | @Test public void isPrimitive() throws Exception {
    method isBoxedPrimitive (line 173) | @Test public void isBoxedPrimitive() throws Exception {
    method canBoxAnnotatedPrimitive (line 183) | @Test public void canBoxAnnotatedPrimitive() throws Exception {
    method canUnboxAnnotatedPrimitive (line 188) | @Test public void canUnboxAnnotatedPrimitive() throws Exception {
    method assertEqualsHashCodeAndToString (line 193) | private void assertEqualsHashCodeAndToString(TypeName a, TypeName b) {

FILE: src/test/java/com/squareup/javapoet/TypeSpecTest.java
  class TypeSpecTest (line 49) | @RunWith(JUnit4.class)
    method getElement (line 56) | private TypeElement getElement(Class<?> clazz) {
    method basic (line 60) | @Test public void basic() throws Exception {
    method interestingTypes (line 84) | @Test public void interestingTypes() throws Exception {
    method anonymousInnerClass (line 112) | @Test public void anonymousInnerClass() throws Exception {
    method annotatedParameters (line 172) | @Test public void annotatedParameters() throws Exception {
    method annotationsAndJavaLangTypes (line 212) | @Test public void annotationsAndJavaLangTypes() throws Exception {
    method retrofitStyleInterface (line 230) | @Test public void retrofitStyleInterface() throws Exception {
    method annotatedField (line 288) | @Test public void annotatedField() throws Exception {
    method annotatedClass (line 307) | @Test public void annotatedClass() throws Exception {
    method addAnnotationDisallowsNull (line 329) | @Test public void addAnnotationDisallowsNull() {
    method enumWithSubclassing (line 350) | @Test public void enumWithSubclassing() throws Exception {
    method enumsMayDefineAbstractMethods (line 409) | @Test public void enumsMayDefineAbstractMethods() throws Exception {
    method noEnumConstants (line 438) | @Test public void noEnumConstants() throws Exception {
    method onlyEnumsMayHaveEnumConstants (line 453) | @Test public void onlyEnumsMayHaveEnumConstants() throws Exception {
    method enumWithMembersButNoConstructorCall (line 463) | @Test public void enumWithMembersButNoConstructorCall() throws Excepti...
    method enumWithAnnotatedValues (line 491) | @Test public void enumWithAnnotatedValues() throws Exception {
    method methodThrows (line 515) | @Test public void methodThrows() throws Exception {
    method typeVariables (line 552) | @Test public void typeVariables() throws Exception {
    method typeVariableWithBounds (line 607) | @Test public void typeVariableWithBounds() {
    method classImplementsExtends (line 630) | @Test public void classImplementsExtends() throws Exception {
    method classImplementsNestedClass (line 651) | @Test public void classImplementsNestedClass() throws Exception {
    method enumImplements (line 674) | @Test public void enumImplements() throws Exception {
    method interfaceExtends (line 694) | @Test public void interfaceExtends() throws Exception {
    method nestedClasses (line 710) | @Test public void nestedClasses() throws Exception {
    method annotation (line 783) | @Test public void annotation() throws Exception {
    method innerAnnotationInAnnotationDeclaration (line 802) | @Test public void innerAnnotationInAnnotationDeclaration() throws Exce...
    method annotationWithFields (line 822) | @Test public void annotationWithFields() {
    method classCannotHaveDefaultValueForMethod (line 841) | @Test
    method classCannotHaveDefaultMethods (line 856) | @Test
    method interfaceStaticMethods (line 871) | @Test
    method interfaceDefaultMethods (line 892) | @Test
    method invalidInterfacePrivateMethods (line 913) | @Test
    method interfacePrivateMethods (line 951) | @Test
    method referencedAndDeclaredSimpleNamesConflict (line 990) | @Test public void referencedAndDeclaredSimpleNamesConflict() throws Ex...
    method simpleNamesConflictInThisAndOtherPackage (line 1053) | @Test public void simpleNamesConflictInThisAndOtherPackage() throws Ex...
    method simpleNameConflictsWithTypeVariable (line 1072) | @Test public void simpleNameConflictsWithTypeVariable() {
    method originatingElementsIncludesThoseOfNestedTypes (line 1140) | @Test public void originatingElementsIncludesThoseOfNestedTypes() {
    method intersectionType (line 1152) | @Test public void intersectionType() {
    method arrayType (line 1174) | @Test public void arrayType() {
    method javadoc (line 1186) | @Test public void javadoc() {
    method annotationsInAnnotations (line 1229) | @Test public void annotationsInAnnotations() throws Exception {
    method varargs (line 1261) | @Test public void varargs() throws Exception {
    method codeBlocks (line 1280) | @Test public void codeBlocks() throws Exception {
    method indexedElseIf (line 1351) | @Test public void indexedElseIf() throws Exception {
    method elseIf (line 1377) | @Test public void elseIf() throws Exception {
    method doWhile (line 1403) | @Test public void doWhile() throws Exception {
    method inlineIndent (line 1425) | @Test public void inlineIndent() throws Exception {
    method defaultModifiersForInterfaceMembers (line 1445) | @Test public void defaultModifiersForInterfaceMembers() throws Excepti...
    method defaultModifiersForMemberInterfacesAndEnums (line 1473) | @Test public void defaultModifiersForMemberInterfacesAndEnums() throws...
    method membersOrdering (line 1502) | @Test public void membersOrdering() throws Exception {
    method nativeMethods (line 1559) | @Test public void nativeMethods() throws Exception {
    method nullStringLiteral (line 1592) | @Test public void nullStringLiteral() throws Exception {
    method annotationToString (line 1608) | @Test public void annotationToString() throws Exception {
    method codeBlockToString (line 1615) | @Test public void codeBlockToString() throws Exception {
    method codeBlockAddStatementOfCodeBlockToString (line 1622) | @Test public void codeBlockAddStatementOfCodeBlockToString() throws Ex...
    method fieldToString (line 1628) | @Test public void fieldToString() throws Exception {
    method methodToString (line 1636) | @Test public void methodToString() throws Exception {
    method constructorToString (line 1650) | @Test public void constructorToString() throws Exception {
    method parameterToString (line 1662) | @Test public void parameterToString() throws Exception {
    method classToString (line 1671) | @Test public void classToString() throws Exception {
    method anonymousClassToString (line 1679) | @Test public void anonymousClassToString() throws Exception {
    method interfaceClassToString (line 1695) | @Test public void interfaceClassToString() throws Exception {
    method annotationDeclarationToString (line 1703) | @Test public void annotationDeclarationToString() throws Exception {
    method toString (line 1711) | private String toString(TypeSpec typeSpec) {
    method multilineStatement (line 1715) | @Test public void multilineStatement() throws Exception {
    method multilineStatementWithAnonymousClass (line 1743) | @Test public void multilineStatementWithAnonymousClass() throws Except...
    method multilineStrings (line 1804) | @Test public void multilineStrings() throws Exception {
    method doubleFieldInitialization (line 1823) | @Test public void doubleFieldInitialization() {
    method nullAnnotationsAddition (line 1843) | @Test public void nullAnnotationsAddition() {
    method multipleAnnotationAddition (line 1853) | @Test public void multipleAnnotationAddition() {
    method nullFieldsAddition (line 1873) | @Test public void nullFieldsAddition() {
    method multipleFieldAddition (line 1883) | @Test public void multipleFieldAddition() {
    method nullMethodsAddition (line 1901) | @Test public void nullMethodsAddition() {
    method multipleMethodAddition (line 1911) | @Test public void multipleMethodAddition() {
    method nullSuperinterfacesAddition (line 1943) | @Test public void nullSuperinterfacesAddition() {
    method nullSingleSuperinterfaceAddition (line 1953) | @Test public void nullSingleSuperinterfaceAddition() {
    method nullInSuperinterfaceIterableAddition (line 1963) | @Test public void nullInSuperinterfaceIterableAddition() {
    method multipleSuperinterfaceAddition (line 1977) | @Test public void multipleSuperinterfaceAddition() {
    method nullModifiersAddition (line 1993) | @Test public void nullModifiersAddition() {
    method nullTypeVariablesAddition (line 2003) | @Test public void nullTypeVariablesAddition() {
    method multipleTypeVariableAddition (line 2013) | @Test public void multipleTypeVariableAddition() {
    method nullTypesAddition (line 2028) | @Test public void nullTypesAddition() {
    method multipleTypeAddition (line 2038) | @Test public void multipleTypeAddition() {
    method tryCatch (line 2056) | @Test public void tryCatch() {
    method ifElse (line 2080) | @Test public void ifElse() {
    method literalFromAnything (line 2108) | @Test public void literalFromAnything() {
    method nameFromCharSequence (line 2117) | @Test public void nameFromCharSequence() {
    method nameFromField (line 2121) | @Test public void nameFromField() {
    method nameFromParameter (line 2126) | @Test public void nameFromParameter() {
    method nameFromMethod (line 2131) | @Test public void nameFromMethod() {
    method nameFromType (line 2139) | @Test public void nameFromType() {
    method nameFromUnsupportedType (line 2144) | @Test public void nameFromUnsupportedType() {
    method stringFromAnything (line 2153) | @Test public void stringFromAnything() {
    method stringFromNull (line 2162) | @Test public void stringFromNull() {
    method typeFromTypeName (line 2166) | @Test public void typeFromTypeName() {
    method typeFromTypeMirror (line 2171) | @Test public void typeFromTypeMirror() {
    method typeFromTypeElement (line 2176) | @Test public void typeFromTypeElement() {
    method typeFromReflectType (line 2181) | @Test public void typeFromReflectType() {
    method typeFromUnsupportedType (line 2185) | @Test public void typeFromUnsupportedType() {
    method tooFewArguments (line 2194) | @Test public void tooFewArguments() {
    method unusedArgumentsRelative (line 2203) | @Test public void unusedArgumentsRelative() {
    method unusedArgumentsIndexed (line 2212) | @Test public void unusedArgumentsIndexed() {
    method superClassOnlyValidForClasses (line 2233) | @Test public void superClassOnlyValidForClasses() {
    method invalidSuperClass (line 2251) | @Test public void invalidSuperClass() {
    method staticCodeBlock (line 2267) | @Test public void staticCodeBlock() {
    method initializerBlockInRightPlace (line 2303) | @Test public void initializerBlockInRightPlace() {
    method initializersToBuilder (line 2350) | @Test public void initializersToBuilder() {
    method initializerBlockUnsupportedExceptionOnInterface (line 2424) | @Test public void initializerBlockUnsupportedExceptionOnInterface() {
    method initializerBlockUnsupportedExceptionOnAnnotation (line 2433) | @Test public void initializerBlockUnsupportedExceptionOnAnnotation() {
    method lineWrapping (line 2442) | @Test public void lineWrapping() {
    method lineWrappingWithZeroWidthSpace (line 2471) | @Test public void lineWrappingWithZeroWidthSpace() {
    method equalsAndHashCode (line 2493) | @Test public void equalsAndHashCode() {
    method classNameFactories (line 2512) | @Test public void classNameFactories() {
    method modifyAnnotations (line 2520) | @Test
    method modifyModifiers (line 2531) | @Test
    method modifyFields (line 2540) | @Test
    method modifyTypeVariables (line 2549) | @Test
    method modifySuperinterfaces (line 2561) | @Test
    method modifyMethods (line 2570) | @Test
    method modifyTypes (line 2579) | @Test
    method modifyEnumConstants (line 2588) | @Test
    method modifyOriginatingElements (line 2599) | @Test
    method javadocWithTrailingLineDoesNotAddAnother (line 2608) | @Test public void javadocWithTrailingLineDoesNotAddAnother() {
    method javadocEnsuresTrailingLine (line 2623) | @Test public void javadocEnsuresTrailingLine() {

FILE: src/test/java/com/squareup/javapoet/TypesEclipseTest.java
  class TypesEclipseTest (line 49) | @RunWith(JUnit4.class)
    class CompilationRule (line 60) | public static final class CompilationRule implements TestRule {
      method apply (line 64) | @Override
      method getElements (line 115) | public Elements getElements() {
      method getTypes (line 125) | public Types getTypes() {
      method compile (line 130) | static private boolean compile(Iterable<? extends Processor> process...
    method getElements (line 149) | @Override
    method getTypes (line 154) | @Override

FILE: src/test/java/com/squareup/javapoet/TypesTest.java
  class TypesTest (line 27) | @RunWith(JUnit4.class)
    method getElements (line 31) | @Override
    method getTypes (line 36) | @Override

FILE: src/test/java/com/squareup/javapoet/UtilTest.java
  class UtilTest (line 22) | public class UtilTest {
    method characterLiteral (line 23) | @Test public void characterLiteral() {
    method stringLiteral (line 59) | @Test public void stringLiteral() {
    method stringLiteral (line 68) | void stringLiteral(String string) {
    method stringLiteral (line 72) | void stringLiteral(String expected, String value, String indent) {
Condensed preview — 50 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (537K chars).
[
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 722,
    "preview": "Contributing\n============\n\nIf you would like to contribute code you can do so through GitHub by forking\nthe repository a"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 515,
    "preview": "name: build\n\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checko"
  },
  {
    "path": ".github/workflows/settings.xml",
    "chars": 233,
    "preview": "<settings>\n  <servers>\n    <server>\n      <id>sonatype-nexus-snapshots</id>\n      <username>${env.SONATYPE_DEPLOY_USERNA"
  },
  {
    "path": ".gitignore",
    "chars": 150,
    "preview": ".classpath\n.project\n.settings\n.checkstyle\neclipsebin\n\nbin\ngen\nbuild\nout\nlib\n\ntarget\npom.xml.*\nrelease.properties\n\n.idea\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 12550,
    "preview": "Change Log\n==========\n\nJavaPoet 1.13.0 *(2020-06-18)*\n-----------------------------\n\n * New: Add support for explicit re"
  },
  {
    "path": "LICENSE.txt",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README.md",
    "chars": 28886,
    "preview": "JavaPoet\n========\n\n`JavaPoet` is a Java API for generating `.java` source files.\n\nSource file generation can be useful w"
  },
  {
    "path": "RELEASING.md",
    "chars": 1493,
    "preview": "Releasing\n=========\n\n1. Update the CHANGELOG.md for the impending release.\n2. Update the README.md with the new version."
  },
  {
    "path": "checkstyle.xml",
    "chars": 5490,
    "preview": "<?xml version=\"1.0\"?>\n<!DOCTYPE module PUBLIC\n    \"-//Puppy Crawl//DTD Check Configuration 1.3//EN\"\n    \"http://www.pupp"
  },
  {
    "path": "pom.xml",
    "chars": 4867,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/"
  },
  {
    "path": "renovate.json",
    "chars": 107,
    "preview": "{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\n    \"config:base\"\n  ]\n}\n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/AnnotationSpec.java",
    "chars": 9860,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/ArrayTypeName.java",
    "chars": 3575,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/ClassName.java",
    "chars": 11188,
    "preview": "/*\n * Copyright (C) 2014 Google, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/CodeBlock.java",
    "chars": 16305,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/CodeWriter.java",
    "chars": 18315,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/FieldSpec.java",
    "chars": 5530,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/JavaFile.java",
    "chars": 11407,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/LineWrapper.java",
    "chars": 5456,
    "preview": "/*\n * Copyright (C) 2016 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/MethodSpec.java",
    "chars": 18301,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/NameAllocator.java",
    "chars": 6071,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/ParameterSpec.java",
    "chars": 6535,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/ParameterizedTypeName.java",
    "chars": 5336,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/TypeName.java",
    "chars": 15225,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/TypeSpec.java",
    "chars": 31297,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/TypeVariableName.java",
    "chars": 6456,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/Util.java",
    "chars": 4697,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/main/java/com/squareup/javapoet/WildcardTypeName.java",
    "chars": 4714,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/ClassNameNoPackageTest.java",
    "chars": 1240,
    "preview": "/*\n * Copyright (C) 2019 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/AbstractTypesTest.java",
    "chars": 11681,
    "preview": "/*\n * Copyright (C) 2014 Google, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/AnnotatedTypeNameTest.java",
    "chars": 9077,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/AnnotationSpecTest.java",
    "chars": 14002,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/ClassNameTest.java",
    "chars": 8665,
    "preview": "/*\n * Copyright (C) 2014 Google, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/CodeBlockTest.java",
    "chars": 12069,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/CodeWriterTest.java",
    "chars": 644,
    "preview": "package com.squareup.javapoet;\n\nimport org.junit.Test;\n\nimport java.io.IOException;\n\nimport static com.google.common.tru"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/FieldSpecTest.java",
    "chars": 2328,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/FileReadingTest.java",
    "chars": 5025,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/FileWritingTest.java",
    "chars": 8918,
    "preview": "/*\n * Copyright (C) 2014 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/JavaFileTest.java",
    "chars": 35493,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/LineWrapperTest.java",
    "chars": 7494,
    "preview": "/*\n * Copyright (C) 2016 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/MethodSpecTest.java",
    "chars": 17901,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/NameAllocatorTest.java",
    "chars": 4345,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/ParameterSpecTest.java",
    "chars": 5294,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/TestFiler.java",
    "chars": 3230,
    "preview": "/*\n * Copyright (C) 2014 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/TestUtil.java",
    "chars": 520,
    "preview": "package com.squareup.javapoet;\n\nimport javax.lang.model.element.Element;\nimport javax.lang.model.element.ExecutableEleme"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/TypeNameTest.java",
    "chars": 8477,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/TypeSpecTest.java",
    "chars": 94473,
    "preview": "/*\n * Copyright (C) 2015 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/TypesEclipseTest.java",
    "chars": 5447,
    "preview": "/*\n * Copyright (C) 2014 Google, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/TypesTest.java",
    "chars": 1177,
    "preview": "/*\n * Copyright (C) 2014 Google, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "src/test/java/com/squareup/javapoet/UtilTest.java",
    "chars": 3666,
    "preview": "/*\n * Copyright (C) 2016 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  }
]

About this extraction

This page contains the full source code of the square/javapoet GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 50 files (495.9 KB), approximately 121.2k tokens, and a symbol index with 920 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!