All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.errorprone.refaster.annotation.Placeholder Maven / Gradle / Ivy

There is a newer version: 2.27.1
Show newest version
/*
 * Copyright 2014 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.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Annotation to indicate a placeholder method.
 *
 * 

A placeholder method is an abstract method in a Refaster template class which can represent an * arbitrary expression (if the return type is nonvoid), or zero or more statements (if the return * type is void), in terms of its arguments. For example, * *


 * abstract class ComputeIfAbsent<K, V> {
 *  {@literal @}Placeholder abstract V computeValue(K key);
 *
 *  {@literal @}BeforeTemplate void getOrCompute(Map<K, V> map, K key) {
 *     V value = map.get(key);
 *     if (value == null) {
 *       map.put(key, value = computeValue(key));
 *     }
 *   }
 *
 *  {@literal @}AfterTemplate void computeIfAbsent(Map<K, V> map, K key) {
 *     V value = map.computeIfAbsent(key, (K k) -> computeValue(k));
 *   }
 * }
 * 
* *

Here, {@code computeValue} represents an arbitrary expression in terms of {@code key}, and the * {@code @AfterTemplate} rewrites that same expression in terms of the parameter of a lambda * expression. * *

For a multi-line example, consider * *


 * abstract class TryWithResources<T extends AutoCloseable> {
 *  {@literal @}Placeholder abstract T open();
 *  {@literal @}Placeholder void process(T resource);
 *
 *  {@literal @}BeforeTemplate void tryFinallyClose() {
 *     T resource = open();
 *     try {
 *       process(resource);
 *     } finally {
 *       resource.close();
 *     }
 *   }
 *
 *  {@literal @}AfterTemplate void tryWithResource() {
 *     try (T resource = open()) {
 *       process(resource);
 *     }
 *   }
 * }
 * 
* *

Here, {@code process} is any block, though it must refer to {@code resource} in some way; it * is not permitted to reassign the contents of {@code resource}. * *

Placeholder methods are not permitted to refer to any local variables or parameters of the * {@code @BeforeTemplate} that are not passed to them as arguments. Additionally, they * must contain references to all arguments that are passed to them -- except * those corresponding to parameters annotated with {@link MayOptionallyUse}. * * @author [email protected] (Louis Wasserman) */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Placeholder { // TODO(lowasser): consider putting forbiddenKinds here as an annotation parameter /** * Identifies whether the placeholder is allowed to match an expression which simply returns one * of the placeholder arguments unchanged. */ boolean allowsIdentity() default false; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy