tech.deplant.javapoet.NameAllocator Maven / Gradle / Ivy
Show all versions of javapoet-core Show documentation
/*
* 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 tech.deplant.javapoet;
import javax.lang.model.SourceVersion;
import java.util.*;
/**
* 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: {@code
*
* NameAllocator nameAllocator = new NameAllocator();
* for (MyProperty property : properties) {
* nameAllocator.newName(property.parameterName(), property);
* }
* nameAllocator.newName("sb", "string builder");
* }
*
* Pass a unique tag object to each allocation. The tag scopes the parameterName, and can be used to look up
* the allocated parameterName 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.
*
*
Once we've allocated names we can use them when generating code:
{@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();
* }
*
* 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:
{@code
*
* @Override
* public String toString() {
* StringBuilder sb_ = new StringBuilder();
* sb_.append(ab);
* sb_.append(sb);
* return sb_.toString();
* }
* }
*
* 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
* parameterName-unsafe characters like space or dash.
*
*
When dealing with multiple independent inner scopes, use a {@link #clone()} of the
* NameAllocator used for the outer scope to further refine parameterName allocation for a specific inner
* scope.
*/
public final class NameAllocator implements Cloneable {
private final Set allocatedNames;
private final Map