/* * Copyright 2013 Google Inc. All rights reserved. * * 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; /** * Static utilities to indicate special handling in Refaster templates. * * @author lowasser@google.com (Louis Wasserman) */ public class Refaster { private Refaster() {} /** * Indicates that Refaster should treat this {@code @Repeated} argument specifically as a varargs * argument. * * <p>For example, you might write * * <pre><code> * {@literal @}BeforeTemplate void something(@Repeated T arg) { * Stream.of(asVarargs(arg)); // doesn't use the Stream.of(T) overload, but Stream.of(T...) * } * </code></pre> */ public static <T> 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. * * <p>This method should only be used in Refaster templates, but should never actually be run. * * <p>For example, instead of writing * * <pre><code> *{@literal @}BeforeTemplate <E> List<E> copyOfSingleton(E element) { * return ImmutableList.copyOf(Collections.singletonList(element)); * } *{@literal @}BeforeTemplate <E> List<E> copyOfArrayList(E element) { * return ImmutableList.copyOf(Lists.newArrayList(element)); * } * </code></pre> * * <p>one could alternately write * * <pre><code> *{@literal @}BeforeTemplate <E> List<E> singleton(E element) { * return ImmutableList.copyOf(Refaster.anyOf( * Collections.singletonList(element), * Lists.newArrayList(element))); * } * </code></pre> */ @SafeVarargs public static <T> 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.<String>isInstance(o)}. * * <p>For example, instead of writing the broken * * <pre><code> *{@literal @}AfterTemplate <T> boolean instanceOf(Object o) { * return o instanceof T; // you want to match this, but it won't compile * } * </code></pre> * * <p>you would instead write * * <pre><code> *{@literal @}AfterTemplate <T> boolean instanceOf(Object o) { * return Refaster.<T>isInstance(o); // generates the replacement "o instanceof T" * } * </code></pre> * * @throws IllegalArgumentException if T is not specified explicitly. */ public static <T> 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.<String>newArray(10)}. * * <p>For example, instead of writing the broken * * <pre><code> *{@literal @}AfterTemplate <T> T[] newTArray(int size) { * return new T[size]; // you want to generate this code, but it won't compile * } * </code></pre> * * <p>you would instead write * * <pre><code> *{@literal @}AfterTemplate <T> T[] newTArray(int size) { * return Refaster.<T>newArray(size); * } * </code></pre> * * @throws IllegalArgumentException if T is not specified explicitly. */ public static <T> 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.<String>clazz()}. * * <p>For example, instead of writing the broken * * <pre><code> *{@literal @}AfterTemplate <T> T[] getEnumConstants() { * return T.class.getEnumConstants(); // you want to inline this, but it won't compile * } * </code></pre> * * you would instead write * * <pre><code> *{@literal @}AfterTemplate <T> T[] getEnumConstants() { * return Refaster.<T>clazz().getEnumConstants(); * } * </code></pre> * * @throws IllegalArgumentException if T is not specified explicitly. */ public static <T> Class<T> 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.<RoundingMode>valueOf(string)}. * * <p>For example, instead of writing the broken * * <pre><code> *{@literal @}BeforeTemplate <E extends Enum<E>> E valueOf(String str) { * return E.valueOf(str); * } * </code></pre> * * <p>you would instead write * * <pre><code> *{@literal @}BeforeTemplate <E extends Enum<E>> E valueOf(String str) { * return Refaster.<E>enumValueOf(str); * } * </code></pre> * * @throws IllegalArgumentException if E is not specified explicitly. */ public static <E extends Enum<E>> 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. * * <p>For example, instead of writing * * <pre><code> *{@literal @}AfterTemplate int lengthWithComment(String str) { * return /* comment \*\/ str.length(); * } * </code></pre> * * <p>you would instead write * * <pre><code> *{@literal @}AfterTemplate int lengthWithComment(String str) { * return Refaster.emitCommentBefore("comment", str.length()); * } * </code></pre> */ public static <T> 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. * * <p>For example, instead of writing * * <pre><code> *{@literal @}AfterTemplate void printWithComment(String str) { * // comment * System.out.println(str); * } * </code></pre> * * <p>you would instead write * * <pre><code> *{@literal @}AfterTemplate void printWithComment(String str) { * Refaster.emitComment("comment"); * System.out.println(str); * } * </code></pre> */ public static void emitComment(String literal) { throw new UnsupportedOperationException(); } }