/* * Copyright 2016 DiffPlug * * 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.diffplug.spotless; import java.io.File; import java.io.Serializable; import java.util.Objects; import javax.annotation.Nullable; /** * An implementation of this class specifies a single step in a formatting process. * * The input is guaranteed to have unix-style newlines, and the output is required * to not introduce any windows-style newlines as well. */ public interface FormatterStep extends Serializable { /** The name of the step, for debugging purposes. */ public String getName(); /** * Returns a formatted version of the given content. * * @param rawUnix * the content to format, guaranteed to have unix-style newlines ('\n'); never null * @param file * the file which `rawUnix` was obtained from; never null. Pass an empty file using * `new File("")` if and only if no file is actually associated with `rawUnix` * @return the formatted content, guaranteed to only have unix-style newlines; may return null * if the formatter step doesn't have any changes to make * @throws Exception if the formatter step experiences a problem */ public @Nullable String format(String rawUnix, File file) throws Exception; /** * Returns a new FormatterStep which will only apply its changes * to files which pass the given filter. * * The provided filter must be serializable. */ public default FormatterStep filterByFile(SerializableFileFilter filter) { return new FilterByFileFormatterStep(this, filter); } /** * Implements a FormatterStep in a strict way which guarantees correct and lazy implementation * of up-to-date checks. This maximizes performance for cases where the FormatterStep is not * actually needed (e.g. don't load eclipse setting file unless this step is actually running) * while also ensuring that gradle can detect changes in a step's settings to determine that * it needs to rerun a format. */ abstract class Strict<State extends Serializable> extends LazyForwardingEquality<State> implements FormatterStep { private static final long serialVersionUID = 1L; /** * Implements the formatting function strictly in terms * of the input data and the result of {@link #calculateState()}. */ protected abstract String format(State state, String rawUnix, File file) throws Exception; @Override public final String format(String rawUnix, File file) throws Exception { return format(state(), rawUnix, file); } } /** * @param name * The name of the formatter step * @param stateSupplier * If the rule has any state, this supplier will calculate it lazily, and the result * will be passed to stateToFormatter * @param stateToFormatter * A pure function which generates a formatting function using * only the state supplied by state and nowhere else. * @return A FormatterStep */ public static <State extends Serializable> FormatterStep createLazy( String name, ThrowingEx.Supplier<State> stateSupplier, ThrowingEx.Function<State, FormatterFunc> stateToFormatter) { return new FormatterStepImpl.Standard<>(name, stateSupplier, stateToFormatter); } /** * @param name * The name of the formatter step * @param state * If the rule has any state, this state must contain all of it * @param stateToFormatter * A pure function which generates a formatting function using * only the state supplied by state and nowhere else. * @return A FormatterStep */ public static <State extends Serializable> FormatterStep create( String name, State state, ThrowingEx.Function<State, FormatterFunc> stateToFormatter) { Objects.requireNonNull(state, "state"); return createLazy(name, () -> state, stateToFormatter); } /** * @param name * The name of the formatter step * @param functionSupplier * A supplier which will lazily generate the function * used by the formatter step * @return A FormatterStep which will never report that it is up-to-date, because * it is not equal to the serialized representation of itself. */ public static FormatterStep createNeverUpToDateLazy( String name, ThrowingEx.Supplier<FormatterFunc> functionSupplier) { return new FormatterStepImpl.NeverUpToDate(name, functionSupplier); } /** * @param name * The name of the formatter step * @param function * The function used by the formatter step * @return A FormatterStep which will never report that it is up-to-date, because * it is not equal to the serialized representation of itself. */ public static FormatterStep createNeverUpToDate( String name, FormatterFunc function) { Objects.requireNonNull(function, "function"); return createNeverUpToDateLazy(name, () -> function); } }