com.google.errorprone.refaster.Refaster Maven / Gradle / Ivy
/*
* Copyright 2013 The Error Prone Authors.
*
* 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.google.errorprone.refaster;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
/**
* Static utilities to indicate special handling in Refaster templates.
*
* @author [email protected] (Louis Wasserman)
*/
public class Refaster {
private Refaster() {}
/**
* Indicates that Refaster should treat this {@code @Repeated} argument specifically as a varargs
* argument.
*
* For example, you might write
*
*
{@code
* @BeforeTemplate void something(@Repeated T arg) {
* Stream.of(asVarargs(arg)); // doesn't use the Stream.of(T) overload, but Stream.of(T...)
* }
* }
*/
public static T[] asVarargs(T arg) {
throw new UnsupportedOperationException();
}
/**
* Indicates that Refaster should attempt to match a target expression against each of the
* specified template expressions, in order, and succeed at the first match.
*
* This method should only be used in Refaster templates, but should never actually be run.
*
*
For example, instead of writing
*
*
{@code
* @BeforeTemplate List copyOfSingleton(E element) {
* return ImmutableList.copyOf(Collections.singletonList(element));
* }
* @BeforeTemplate List copyOfArrayList(E element) {
* return ImmutableList.copyOf(Lists.newArrayList(element));
* }
* }
*
* one could alternately write
*
*
{@code
* @BeforeTemplate List singleton(E element) {
* return ImmutableList.copyOf(Refaster.anyOf(
* Collections.singletonList(element),
* Lists.newArrayList(element)));
* }
* }
*/
@SafeVarargs
@CanIgnoreReturnValue
public static T anyOf(T... expressions) {
throw new UnsupportedOperationException();
}
/**
* This is a placeholder for the Java instanceof operator that can be used with Refaster type
* variables. The type argument must always be specified explicitly, e.g. {@code
* Refaster.isInstance(o)}.
*
* For example, instead of writing the broken
*
*
{@code
* @AfterTemplate boolean instanceOf(Object o) {
* return o instanceof T; // you want to match this, but it won't compile
* }
* }
*
* you would instead write
*
*
{@code
* @AfterTemplate boolean instanceOf(Object o) {
* return Refaster.isInstance(o); // generates the replacement "o instanceof T"
* }
* }
*
* @throws IllegalArgumentException if T is not specified explicitly.
*/
public static boolean isInstance(Object o) {
// real code wouldn't have an unused type parameter (T) or an unused argument (o)
throw new UnsupportedOperationException(o.toString());
}
/**
* This is a placeholder for {@code new T[size]}. The type argument must always be specified
* explicitly, e.g. {@code Refaster.newArray(10)}.
*
* For example, instead of writing the broken
*
*
{@code
* @AfterTemplate T[] newTArray(int size) {
* return new T[size]; // you want to generate this code, but it won't compile
* }
* }
*
* you would instead write
*
*
{@code
* @AfterTemplate T[] newTArray(int size) {
* return Refaster.newArray(size);
* }
* }
*
* @throws IllegalArgumentException if T is not specified explicitly.
*/
public static T[] newArray(int size) {
throw new UnsupportedOperationException(Integer.toString(size));
}
/**
* This is a placeholder for the expression T.class. The type argument must always be specified
* explicitly, e.g. {@code Refaster.clazz()}.
*
* For example, instead of writing the broken
*
*
{@code
* @AfterTemplate T[] getEnumConstants() {
* return T.class.getEnumConstants(); // you want to inline this, but it won't compile
* }
* }
*
* you would instead write
*
* {@code
* @AfterTemplate T[] getEnumConstants() {
* return Refaster.clazz().getEnumConstants();
* }
* }
*
* @throws IllegalArgumentException if T is not specified explicitly.
*/
public static Class clazz() {
throw new UnsupportedOperationException();
}
/**
* This is a placeholder for the expression E.valueOf(string). The type argument must always be
* specified explicitly, e.g. {@code Refaster.valueOf(string)}.
*
* For example, instead of writing the broken
*
*
{@code
* @BeforeTemplate > E valueOf(String str) {
* return E.valueOf(str);
* }
* }
*
* you would instead write
*
*
{@code
* @BeforeTemplate > E valueOf(String str) {
* return Refaster.enumValueOf(str);
* }
* }
*
* @throws IllegalArgumentException if E is not specified explicitly.
*/
public static > E enumValueOf(String string) {
throw new UnsupportedOperationException();
}
/**
* This is a special method to emit a comment before an expression. The comment argument must
* always be a string literal. This method cannot be static imported.
*
* For example, instead of writing
*
*
{@code
* @AfterTemplate int lengthWithComment(String str) {
* return /* comment \*\/ str.length();
* }
* }
*
* you would instead write
*
*
{@code
* @AfterTemplate int lengthWithComment(String str) {
* return Refaster.emitCommentBefore("comment", str.length());
* }
* }
*/
public static T emitCommentBefore(String literal, T expression) {
throw new UnsupportedOperationException();
}
/**
* This is a special method to emit a one-line comment. The comment argument must always be a
* string literal. This method cannot be static imported.
*
* For example, instead of writing
*
*
{@code
* @AfterTemplate void printWithComment(String str) {
* // comment
* System.out.println(str);
* }
* }
*
* you would instead write
*
*
{@code
* @AfterTemplate void printWithComment(String str) {
* Refaster.emitComment("comment");
* System.out.println(str);
* }
* }
*/
public static void emitComment(String literal) {
throw new UnsupportedOperationException();
}
}