Skip to content

Commit

Permalink
The new FormatterStep.create() and createLazy() utilized anonymous cl…
Browse files Browse the repository at this point in the history
…asses which captured their parameters in non-transient fields. Thanks to FindBugs for spotting the error! New implementation ensures that the *only state* is the serializable key.
  • Loading branch information
nedtwigg committed Nov 1, 2016
1 parent 452fbd9 commit c1357f5
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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.gradle.spotless;

import java.io.File;
import java.io.Serializable;
import java.util.Objects;
import java.util.function.BiFunction;

import com.diffplug.common.base.Throwing;
import com.diffplug.gradle.spotless.FormatterStep.Strict;

/**
* Standard implementation of FormatExtension which cleanly enforces
* separation of serializable configuration and a pure format function.
*/
abstract class FormatExtensionStandardImpl<Key extends Serializable> extends Strict<Key> {
private static final long serialVersionUID = 1L;

/** Transient because only the state matters. */
final transient String name;
/** Transient because only the state matters. */
final transient BiFunction<Key, String, String> formatter;

public FormatExtensionStandardImpl(String name, BiFunction<Key, String, String> formatter) {
this.name = Objects.requireNonNull(name);
this.formatter = Objects.requireNonNull(formatter);
}

@Override
public String getName() {
return name;
}

@Override
protected String format(Key key, String rawUnix, File file) {
return formatter.apply(key, rawUnix);
}

static class Eager<Key extends Serializable> extends FormatExtensionStandardImpl<Key> {
private static final long serialVersionUID = 1L;

/** Transient because the key is persisted by the superclass. */
final transient Key key;

public Eager(String name, Key key, BiFunction<Key, String, String> formatter) {
super(name, formatter);
this.key = Objects.requireNonNull(key);
}

@Override
protected Key calculateKey() throws Exception {
return key;
}
}

static class Lazy<Key extends Serializable> extends FormatExtensionStandardImpl<Key> {
private static final long serialVersionUID = 1L;

/** Transient because the key is persisted by the superclass. */
final transient Throwing.Specific.Supplier<Key, Exception> keySupplier;

public Lazy(String name, Throwing.Specific.Supplier<Key, Exception> keySupplier, BiFunction<Key, String, String> formatter) {
super(name, formatter);
this.keySupplier = Objects.requireNonNull(keySupplier);
}

@Override
protected Key calculateKey() throws Exception {
return keySupplier.get();
}
}
}
40 changes: 3 additions & 37 deletions src/main/java/com/diffplug/gradle/spotless/FormatterStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public interface FormatterStep extends Serializable {
/**
* Returns a formatted version of the given content.
*
* @param raw
* @param rawUnix
* File's content, guaranteed to have unix-style newlines ('\n')
* @param file
* the File which is being formatted
Expand Down Expand Up @@ -92,24 +92,7 @@ public static <Key extends Serializable> FormatterStep createLazy(
String name,
Throwing.Specific.Supplier<Key, Exception> keySupplier,
BiFunction<Key, String, String> formatter) {
return new Strict<Key>() {
private static final long serialVersionUID = 1L;

@Override
public String getName() {
return name;
}

@Override
protected Key calculateKey() throws Exception {
return keySupplier.get();
}

@Override
protected String format(Key key, String rawUnix, File file) {
return formatter.apply(key, rawUnix);
}
};
return new FormatExtensionStandardImpl.Lazy<>(name, keySupplier, formatter);
}

/**
Expand All @@ -126,24 +109,7 @@ public static <Key extends Serializable> FormatterStep create(
String name,
Key key,
BiFunction<Key, String, String> formatter) {
return new Strict<Key>() {
private static final long serialVersionUID = 1L;

@Override
public String getName() {
return name;
}

@Override
protected Key calculateKey() throws Exception {
return key;
}

@Override
protected String format(Key key, String rawUnix, File file) {
return formatter.apply(key, rawUnix);
}
};
return new FormatExtensionStandardImpl.Eager<>(name, key, formatter);
}

/** A FormatterStep which doesn't depend on the input file. */
Expand Down

0 comments on commit c1357f5

Please sign in to comment.