mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 08:11:25 +00:00
Compare commits
18 Commits
v0.19.1
...
sschroever
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f84e17b396 | ||
|
|
11022cd958 | ||
|
|
f0145f74ab | ||
|
|
86e50aaa7b | ||
|
|
8bf1bd4105 | ||
|
|
db876b2257 | ||
|
|
3427b947cf | ||
|
|
f3571f13dd | ||
|
|
c9612f22af | ||
|
|
03a4466878 | ||
|
|
7146ff1ceb | ||
|
|
e116854d3d | ||
|
|
379b453e82 | ||
|
|
ecafaa6801 | ||
|
|
1ef7f5b04b | ||
|
|
3d5a75333b | ||
|
|
9ee59a6030 | ||
|
|
4bcba7f2a0 |
19
.github/workflows/deploy-website.yaml
vendored
19
.github/workflows/deploy-website.yaml
vendored
@@ -21,16 +21,19 @@ jobs:
|
||||
bundler-cache: true
|
||||
- name: Configure Github Pages
|
||||
uses: actions/configure-pages@v2.1.3
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v3.5.1
|
||||
with:
|
||||
java-version: 17.0.4
|
||||
distribution: temurin
|
||||
cache: maven
|
||||
- name: Compile project and extract data
|
||||
# XXX: Remove `-Dverification.skip` and update `website/README.md` once
|
||||
# module `docgen` has no errors.
|
||||
run: mvn -T1C clean install -DskipTests -Dverification.skip -Pdocgen
|
||||
- name: Generate documentation
|
||||
run: ./generate-docs.sh
|
||||
- name: Build website with Jekyll
|
||||
working-directory: ./website
|
||||
run: bundle exec jekyll build
|
||||
- name: Validate HTML output
|
||||
working-directory: ./website
|
||||
# XXX: Drop `--disable_external true` once we fully adopted the
|
||||
# "Refaster rules" terminology on our website and in the code.
|
||||
run: bundle exec htmlproofer --disable_external true --check-external-hash false ./_site
|
||||
run: bundle exec ruby generate-docs.rb
|
||||
- name: Upload website as artifact
|
||||
uses: actions/upload-pages-artifact@v1.0.5
|
||||
with:
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_check_api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${groupId.error-prone}</groupId>
|
||||
<artifactId>error_prone_test_helpers</artifactId>
|
||||
|
||||
@@ -5,17 +5,19 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.auto.common.AnnotationMirrors;
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.BugPattern;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.annotations.Immutable;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import java.util.Optional;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import tech.picnic.errorprone.documentation.BugPatternExtractor.BugPatternDocumentation;
|
||||
|
||||
@@ -23,29 +25,38 @@ import tech.picnic.errorprone.documentation.BugPatternExtractor.BugPatternDocume
|
||||
* An {@link Extractor} that describes how to extract data from a {@code @BugPattern} annotation.
|
||||
*/
|
||||
@Immutable
|
||||
final class BugPatternExtractor implements Extractor<BugPatternDocumentation> {
|
||||
@Override
|
||||
public BugPatternDocumentation extract(ClassTree tree, Context context) {
|
||||
ClassSymbol symbol = ASTHelpers.getSymbol(tree);
|
||||
BugPattern annotation = symbol.getAnnotation(BugPattern.class);
|
||||
requireNonNull(annotation, "BugPattern annotation must be present");
|
||||
@AutoService(Extractor.class)
|
||||
public final class BugPatternExtractor implements Extractor<BugPatternDocumentation> {
|
||||
/** Instantiates a new {@link BugPatternExtractor} instance. */
|
||||
public BugPatternExtractor() {}
|
||||
|
||||
return new AutoValue_BugPatternExtractor_BugPatternDocumentation(
|
||||
symbol.getQualifiedName().toString(),
|
||||
annotation.name().isEmpty() ? tree.getSimpleName().toString() : annotation.name(),
|
||||
ImmutableList.copyOf(annotation.altNames()),
|
||||
annotation.link(),
|
||||
ImmutableList.copyOf(annotation.tags()),
|
||||
annotation.summary(),
|
||||
annotation.explanation(),
|
||||
annotation.severity(),
|
||||
annotation.disableable(),
|
||||
annotation.documentSuppression() ? getSuppressionAnnotations(tree) : ImmutableList.of());
|
||||
@Override
|
||||
public String identifier() {
|
||||
return "bugpattern";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract(ClassTree tree) {
|
||||
return ASTHelpers.hasDirectAnnotationWithSimpleName(tree, BugPattern.class.getSimpleName());
|
||||
public Optional<BugPatternDocumentation> tryExtract(ClassTree tree, VisitorState state) {
|
||||
ClassSymbol symbol = ASTHelpers.getSymbol(tree);
|
||||
BugPattern annotation = symbol.getAnnotation(BugPattern.class);
|
||||
if (annotation == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(
|
||||
new AutoValue_BugPatternExtractor_BugPatternDocumentation(
|
||||
symbol.getQualifiedName().toString(),
|
||||
annotation.name().isEmpty() ? tree.getSimpleName().toString() : annotation.name(),
|
||||
ImmutableList.copyOf(annotation.altNames()),
|
||||
annotation.link(),
|
||||
ImmutableList.copyOf(annotation.tags()),
|
||||
annotation.summary(),
|
||||
annotation.explanation(),
|
||||
annotation.severity(),
|
||||
annotation.disableable(),
|
||||
annotation.documentSuppression()
|
||||
? getSuppressionAnnotations(tree)
|
||||
: ImmutableList.of()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
package tech.picnic.errorprone.documentation;
|
||||
|
||||
import static com.google.errorprone.matchers.Matchers.allOf;
|
||||
import static com.google.errorprone.matchers.Matchers.anything;
|
||||
import static com.google.errorprone.matchers.Matchers.argument;
|
||||
import static com.google.errorprone.matchers.Matchers.classLiteral;
|
||||
import static com.google.errorprone.matchers.Matchers.hasAnnotation;
|
||||
import static com.google.errorprone.matchers.Matchers.instanceMethod;
|
||||
import static com.google.errorprone.matchers.Matchers.toType;
|
||||
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.annotations.Immutable;
|
||||
import com.google.errorprone.matchers.Matcher;
|
||||
import com.google.errorprone.util.ASTHelpers;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
import com.sun.source.tree.MemberSelectTree;
|
||||
import com.sun.source.tree.MethodInvocationTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.source.util.TreeScanner;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import tech.picnic.errorprone.documentation.BugPatternTestExtractor.BugPatternTestDocumentation;
|
||||
|
||||
/**
|
||||
* An {@link Extractor} that describes how to extract data from classes that test a {@code
|
||||
* BugChecker}.
|
||||
*/
|
||||
@Immutable
|
||||
@AutoService(Extractor.class)
|
||||
public final class BugPatternTestExtractor implements Extractor<BugPatternTestDocumentation> {
|
||||
private static final Pattern TEST_CLASS_NAME_PATTERN = Pattern.compile("(.*)Test");
|
||||
private static final Matcher<Tree> JUNIT_TEST_METHOD =
|
||||
toType(MethodTree.class, hasAnnotation("org.junit.jupiter.api.Test"));
|
||||
private static final Matcher<MethodInvocationTree> BUG_PATTERN_TEST_METHOD =
|
||||
allOf(
|
||||
staticMethod()
|
||||
.onDescendantOfAny(
|
||||
"com.google.errorprone.CompilationTestHelper",
|
||||
"com.google.errorprone.BugCheckerRefactoringTestHelper")
|
||||
.named("newInstance"),
|
||||
argument(0, classLiteral(anything())));
|
||||
|
||||
/** Instantiates a new {@link BugPatternTestExtractor} instance. */
|
||||
public BugPatternTestExtractor() {}
|
||||
|
||||
@Override
|
||||
public String identifier() {
|
||||
return "bugpattern-test";
|
||||
}
|
||||
|
||||
// XXX: Improve support for correctly extracting multiple sources from a single
|
||||
// `{BugCheckerRefactoring,Compilation}TestHelper` test.
|
||||
@Override
|
||||
public Optional<BugPatternTestDocumentation> tryExtract(ClassTree tree, VisitorState state) {
|
||||
return getClassUnderTest(tree)
|
||||
.filter(bugPatternName -> testsBugPattern(bugPatternName, tree, state))
|
||||
.map(
|
||||
bugPatternName -> {
|
||||
CollectBugPatternTests scanner = new CollectBugPatternTests();
|
||||
|
||||
for (Tree m : tree.getMembers()) {
|
||||
if (JUNIT_TEST_METHOD.matches(m, state)) {
|
||||
scanner.scan(m, state);
|
||||
}
|
||||
}
|
||||
|
||||
return new AutoValue_BugPatternTestExtractor_BugPatternTestDocumentation(
|
||||
bugPatternName, scanner.getIdentificationTests(), scanner.getReplacementTests());
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean testsBugPattern(
|
||||
String bugPatternName, ClassTree tree, VisitorState state) {
|
||||
AtomicBoolean result = new AtomicBoolean(false);
|
||||
|
||||
new TreeScanner<@Nullable Void, @Nullable Void>() {
|
||||
@Override
|
||||
public @Nullable Void visitMethodInvocation(MethodInvocationTree node, @Nullable Void v) {
|
||||
if (BUG_PATTERN_TEST_METHOD.matches(node, state)) {
|
||||
MemberSelectTree firstArgumentTree = (MemberSelectTree) node.getArguments().get(0);
|
||||
result.compareAndSet(
|
||||
/* expectedValue= */ false,
|
||||
bugPatternName.equals(firstArgumentTree.getExpression().toString()));
|
||||
}
|
||||
|
||||
return super.visitMethodInvocation(node, v);
|
||||
}
|
||||
}.scan(tree, null);
|
||||
|
||||
return result.get();
|
||||
}
|
||||
|
||||
private static Optional<String> getClassUnderTest(ClassTree tree) {
|
||||
return Optional.of(TEST_CLASS_NAME_PATTERN.matcher(tree.getSimpleName().toString()))
|
||||
.filter(java.util.regex.Matcher::matches)
|
||||
.map(m -> m.group(1));
|
||||
}
|
||||
|
||||
private static final class CollectBugPatternTests
|
||||
extends TreeScanner<@Nullable Void, VisitorState> {
|
||||
private static final Matcher<ExpressionTree> IDENTIFICATION_SOURCE_LINES =
|
||||
instanceMethod()
|
||||
.onDescendantOf("com.google.errorprone.CompilationTestHelper")
|
||||
.named("addSourceLines");
|
||||
private static final Matcher<ExpressionTree> REPLACEMENT_INPUT =
|
||||
instanceMethod()
|
||||
.onDescendantOf("com.google.errorprone.BugCheckerRefactoringTestHelper")
|
||||
.named("addInputLines");
|
||||
private static final Matcher<ExpressionTree> REPLACEMENT_OUTPUT =
|
||||
instanceMethod()
|
||||
.onDescendantOf("com.google.errorprone.BugCheckerRefactoringTestHelper.ExpectOutput")
|
||||
.named("addOutputLines");
|
||||
|
||||
private final List<String> identificationTests = new ArrayList<>();
|
||||
private final List<BugPatternReplacementTestDocumentation> replacementTests = new ArrayList<>();
|
||||
|
||||
public ImmutableList<String> getIdentificationTests() {
|
||||
return ImmutableList.copyOf(identificationTests);
|
||||
}
|
||||
|
||||
public ImmutableList<BugPatternReplacementTestDocumentation> getReplacementTests() {
|
||||
return ImmutableList.copyOf(replacementTests);
|
||||
}
|
||||
|
||||
// XXX: Consider:
|
||||
// - Whether to omit or handle differently identification tests without `// BUG: Diagnostic
|
||||
// (contains|matches)` markers.
|
||||
// - Whether to omit or handle differently replacement tests with identical input and output.
|
||||
// (Though arguably we should have a separate checker which replaces such cases with
|
||||
// `.expectUnchanged()`.)
|
||||
// - Whether to track `.expectUnchanged()` test cases.
|
||||
@Override
|
||||
public @Nullable Void visitMethodInvocation(MethodInvocationTree node, VisitorState state) {
|
||||
if (IDENTIFICATION_SOURCE_LINES.matches(node, state)) {
|
||||
getSourceCode(node).ifPresent(identificationTests::add);
|
||||
} else if (REPLACEMENT_OUTPUT.matches(node, state)) {
|
||||
ExpressionTree receiver = ASTHelpers.getReceiver(node);
|
||||
// XXX: Make this code nicer.
|
||||
if (REPLACEMENT_INPUT.matches(receiver, state)) {
|
||||
getSourceCode(node)
|
||||
.ifPresent(
|
||||
output ->
|
||||
getSourceCode((MethodInvocationTree) receiver)
|
||||
.ifPresent(
|
||||
input ->
|
||||
replacementTests.add(
|
||||
new AutoValue_BugPatternTestExtractor_BugPatternReplacementTestDocumentation(
|
||||
input, output))));
|
||||
}
|
||||
}
|
||||
|
||||
return super.visitMethodInvocation(node, state);
|
||||
}
|
||||
|
||||
// XXX: Duplicated from `ErrorProneTestSourceFormat`. Can we do better?
|
||||
private static Optional<String> getSourceCode(MethodInvocationTree tree) {
|
||||
List<? extends ExpressionTree> sourceLines =
|
||||
tree.getArguments().subList(1, tree.getArguments().size());
|
||||
StringBuilder source = new StringBuilder();
|
||||
|
||||
for (ExpressionTree sourceLine : sourceLines) {
|
||||
String value = ASTHelpers.constValue(sourceLine, String.class);
|
||||
if (value == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
source.append(value).append('\n');
|
||||
}
|
||||
|
||||
return Optional.of(source.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Rename?
|
||||
@AutoValue
|
||||
abstract static class BugPatternTestDocumentation {
|
||||
abstract String name();
|
||||
|
||||
abstract ImmutableList<String> identificationTests();
|
||||
|
||||
abstract ImmutableList<BugPatternReplacementTestDocumentation> replacementTests();
|
||||
}
|
||||
|
||||
// XXX: Rename?
|
||||
@AutoValue
|
||||
abstract static class BugPatternReplacementTestDocumentation {
|
||||
abstract String inputLines();
|
||||
|
||||
abstract String outputLines();
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,14 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.util.TaskEvent;
|
||||
import com.sun.source.util.TaskEvent.Kind;
|
||||
import com.sun.source.util.TaskListener;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.tools.javac.api.JavacTrees;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import java.io.File;
|
||||
@@ -19,6 +23,7 @@ import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ServiceLoader;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
/**
|
||||
@@ -27,6 +32,13 @@ import javax.tools.JavaFileObject;
|
||||
*/
|
||||
// XXX: Find a better name for this class; it doesn't generate documentation per se.
|
||||
final class DocumentationGeneratorTaskListener implements TaskListener {
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private static final ImmutableList<Extractor<?>> EXTRACTORS =
|
||||
(ImmutableList)
|
||||
ImmutableList.copyOf(
|
||||
ServiceLoader.load(
|
||||
Extractor.class, DocumentationGeneratorTaskListener.class.getClassLoader()));
|
||||
|
||||
private static final ObjectMapper OBJECT_MAPPER =
|
||||
new ObjectMapper().setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
|
||||
|
||||
@@ -51,19 +63,25 @@ final class DocumentationGeneratorTaskListener implements TaskListener {
|
||||
return;
|
||||
}
|
||||
|
||||
ClassTree classTree = JavacTrees.instance(context).getTree(taskEvent.getTypeElement());
|
||||
JavaFileObject sourceFile = taskEvent.getSourceFile();
|
||||
if (classTree == null || sourceFile == null) {
|
||||
CompilationUnitTree compilationUnit = taskEvent.getCompilationUnit();
|
||||
ClassTree classTree = JavacTrees.instance(context).getTree(taskEvent.getTypeElement());
|
||||
if (sourceFile == null || compilationUnit == null || classTree == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ExtractorType.findMatchingType(classTree)
|
||||
.ifPresent(
|
||||
extractorType ->
|
||||
writeToFile(
|
||||
extractorType.getIdentifier(),
|
||||
getSimpleClassName(sourceFile.toUri()),
|
||||
extractorType.getExtractor().extract(classTree, context)));
|
||||
VisitorState state =
|
||||
VisitorState.createForUtilityPurposes(context)
|
||||
.withPath(new TreePath(new TreePath(compilationUnit), classTree));
|
||||
|
||||
for (Extractor<?> extractor : EXTRACTORS) {
|
||||
extractor
|
||||
.tryExtract(classTree, state)
|
||||
.ifPresent(
|
||||
data ->
|
||||
writeToFile(
|
||||
extractor.identifier(), getSimpleClassName(sourceFile.toUri()), data));
|
||||
}
|
||||
}
|
||||
|
||||
private void createDocsDirectory() {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package tech.picnic.errorprone.documentation;
|
||||
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.annotations.Immutable;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Interface implemented by classes that define how to extract data of some type {@link T} from a
|
||||
@@ -13,21 +14,20 @@ import com.sun.tools.javac.util.Context;
|
||||
@Immutable
|
||||
interface Extractor<T> {
|
||||
/**
|
||||
* Extracts and returns an instance of {@link T} using the provided arguments.
|
||||
* Returns the unique identifier of this extractor.
|
||||
*
|
||||
* @param tree The {@link ClassTree} to analyze and from which to extract instances of {@link T}.
|
||||
* @param context The {@link Context} in which the current compilation takes place.
|
||||
* @return A non-null instance of {@link T}.
|
||||
* @return A non-{@code null} string.
|
||||
*/
|
||||
// XXX: Drop `Context` parameter unless used.
|
||||
T extract(ClassTree tree, Context context);
|
||||
String identifier();
|
||||
|
||||
/**
|
||||
* Tells whether this {@link Extractor} can extract documentation content from the given {@link
|
||||
* ClassTree}.
|
||||
* Attempts to extract an instance of type {@link T} using the provided arguments.
|
||||
*
|
||||
* @param tree The {@link ClassTree} of interest.
|
||||
* @return {@code true} iff data extraction is supported.
|
||||
* @param tree The {@link ClassTree} to analyze and from which to extract an instance of type
|
||||
* {@link T}.
|
||||
* @param state A {@link VisitorState} describing the context in which the given {@link ClassTree}
|
||||
* is found.
|
||||
* @return An instance of type {@link T}, if possible.
|
||||
*/
|
||||
boolean canExtract(ClassTree tree);
|
||||
Optional<T> tryExtract(ClassTree tree, VisitorState state);
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package tech.picnic.errorprone.documentation;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Optional;
|
||||
|
||||
/** An enumeration of {@link Extractor} types. */
|
||||
enum ExtractorType {
|
||||
BUG_PATTERN("bugpattern", new BugPatternExtractor());
|
||||
|
||||
private static final ImmutableSet<ExtractorType> TYPES =
|
||||
Sets.immutableEnumSet(EnumSet.allOf(ExtractorType.class));
|
||||
|
||||
private final String identifier;
|
||||
private final Extractor<?> extractor;
|
||||
|
||||
ExtractorType(String identifier, Extractor<?> extractor) {
|
||||
this.identifier = identifier;
|
||||
this.extractor = extractor;
|
||||
}
|
||||
|
||||
String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
Extractor<?> getExtractor() {
|
||||
return extractor;
|
||||
}
|
||||
|
||||
static Optional<ExtractorType> findMatchingType(ClassTree tree) {
|
||||
return TYPES.stream().filter(type -> type.getExtractor().canExtract(tree)).findFirst();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package tech.picnic.errorprone.documentation;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.annotations.Immutable;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
import tech.picnic.errorprone.documentation.models.RefasterTemplateCollectionTestData;
|
||||
import tech.picnic.errorprone.documentation.models.RefasterTemplateTestData;
|
||||
|
||||
@Immutable
|
||||
@AutoService(Extractor.class)
|
||||
public final class RefasterTestInputExtractor
|
||||
implements Extractor<RefasterTemplateCollectionTestData> {
|
||||
private static final Pattern TEST_CLASS_NAME_PATTERN = Pattern.compile("(.*)Test");
|
||||
|
||||
@Override
|
||||
public String identifier() {
|
||||
return "refaster-test-input";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RefasterTemplateCollectionTestData> tryExtract(
|
||||
ClassTree tree, VisitorState state) {
|
||||
if (!state.getPath().getCompilationUnit().getPackageName().toString().contains("input")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Optional<String> className = getClassUnderTest(tree);
|
||||
if (className.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
ImmutableList<RefasterTemplateTestData> templateTests =
|
||||
tree.getMembers().stream()
|
||||
.filter(m -> m instanceof MethodTree)
|
||||
.map(MethodTree.class::cast)
|
||||
.filter(m -> m.getName().toString().startsWith("test"))
|
||||
.map(
|
||||
m ->
|
||||
RefasterTemplateTestData.create(
|
||||
m.getName().toString().replace("test", ""), getSourceCode(m, state)))
|
||||
.collect(toImmutableList());
|
||||
|
||||
return Optional.of(
|
||||
RefasterTemplateCollectionTestData.create(className.orElseThrow(), true, templateTests));
|
||||
}
|
||||
|
||||
private static Optional<String> getClassUnderTest(ClassTree tree) {
|
||||
return Optional.of(TEST_CLASS_NAME_PATTERN.matcher(tree.getSimpleName().toString()))
|
||||
.filter(java.util.regex.Matcher::matches)
|
||||
.map(m -> m.group(1));
|
||||
}
|
||||
|
||||
// XXX: Duplicated from `SourceCode`. Can we do better?
|
||||
private String getSourceCode(MethodTree tree, VisitorState state) {
|
||||
String src = state.getSourceForNode(tree);
|
||||
return src != null ? src : tree.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package tech.picnic.errorprone.documentation;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.annotations.Immutable;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
import tech.picnic.errorprone.documentation.models.RefasterTemplateCollectionTestData;
|
||||
import tech.picnic.errorprone.documentation.models.RefasterTemplateTestData;
|
||||
|
||||
@Immutable
|
||||
@AutoService(Extractor.class)
|
||||
public final class RefasterTestOutputExtractor
|
||||
implements Extractor<RefasterTemplateCollectionTestData> {
|
||||
private static final Pattern TEST_CLASS_NAME_PATTERN = Pattern.compile("(.*)Test");
|
||||
|
||||
@Override
|
||||
public String identifier() {
|
||||
return "refaster-test-output";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RefasterTemplateCollectionTestData> tryExtract(
|
||||
ClassTree tree, VisitorState state) {
|
||||
if (!state.getPath().getCompilationUnit().getPackageName().toString().contains("output")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Optional<String> className = getClassUnderTest(tree);
|
||||
if (className.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
ImmutableList<RefasterTemplateTestData> templateTests =
|
||||
tree.getMembers().stream()
|
||||
.filter(m -> m instanceof MethodTree)
|
||||
.map(MethodTree.class::cast)
|
||||
.filter(m -> m.getName().toString().startsWith("test"))
|
||||
.map(
|
||||
m ->
|
||||
RefasterTemplateTestData.create(
|
||||
m.getName().toString().replace("test", ""), getSourceCode(m, state)))
|
||||
.collect(toImmutableList());
|
||||
|
||||
return Optional.of(
|
||||
RefasterTemplateCollectionTestData.create(className.orElseThrow(), true, templateTests));
|
||||
}
|
||||
|
||||
private static Optional<String> getClassUnderTest(ClassTree tree) {
|
||||
return Optional.of(TEST_CLASS_NAME_PATTERN.matcher(tree.getSimpleName().toString()))
|
||||
.filter(java.util.regex.Matcher::matches)
|
||||
.map(m -> m.group(1));
|
||||
}
|
||||
|
||||
// XXX: Duplicated from `SourceCode`. Can we do better?
|
||||
private String getSourceCode(MethodTree tree, VisitorState state) {
|
||||
String src = state.getSourceForNode(tree);
|
||||
return src != null ? src : tree.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package tech.picnic.errorprone.documentation.models;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import java.util.List;
|
||||
import tech.picnic.errorprone.documentation.models.AutoValue_RefasterTemplateCollectionData;
|
||||
|
||||
/**
|
||||
* Object containing all data related to a Refaster template collection. This is solely used for
|
||||
* serialization.
|
||||
*/
|
||||
@AutoValue
|
||||
public abstract class RefasterTemplateCollectionData {
|
||||
public static RefasterTemplateCollectionData create(
|
||||
String name, String description, String link, List<RefasterTemplateData> templates) {
|
||||
return new AutoValue_RefasterTemplateCollectionData(name, description, link, templates);
|
||||
}
|
||||
|
||||
abstract String name();
|
||||
|
||||
abstract String description();
|
||||
|
||||
abstract String link();
|
||||
|
||||
abstract List<RefasterTemplateData> templates();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package tech.picnic.errorprone.documentation.models;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import java.util.List;
|
||||
import tech.picnic.errorprone.documentation.models.AutoValue_RefasterTemplateCollectionTestData;
|
||||
|
||||
@AutoValue
|
||||
public abstract class RefasterTemplateCollectionTestData {
|
||||
public static RefasterTemplateCollectionTestData create(
|
||||
String templateCollection, boolean isInput, List<RefasterTemplateTestData> templatesTests) {
|
||||
return new AutoValue_RefasterTemplateCollectionTestData(
|
||||
templateCollection, isInput, templatesTests);
|
||||
}
|
||||
|
||||
abstract String templateCollection();
|
||||
|
||||
abstract boolean isInput();
|
||||
|
||||
abstract List<RefasterTemplateTestData> templateTests();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package tech.picnic.errorprone.documentation.models;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.errorprone.BugPattern.SeverityLevel;
|
||||
import tech.picnic.errorprone.documentation.models.AutoValue_RefasterTemplateData;
|
||||
|
||||
@AutoValue
|
||||
public abstract class RefasterTemplateData {
|
||||
public static RefasterTemplateData create(
|
||||
String name, String description, String link, SeverityLevel severityLevel) {
|
||||
return new AutoValue_RefasterTemplateData(name, description, link, severityLevel);
|
||||
}
|
||||
|
||||
abstract String name();
|
||||
|
||||
abstract String description();
|
||||
|
||||
abstract String link();
|
||||
|
||||
abstract SeverityLevel severityLevel();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package tech.picnic.errorprone.documentation.models;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import tech.picnic.errorprone.documentation.models.AutoValue_RefasterTemplateTestData;
|
||||
|
||||
@AutoValue
|
||||
public abstract class RefasterTemplateTestData {
|
||||
public static RefasterTemplateTestData create(String templateName, String templateTestContent) {
|
||||
return new AutoValue_RefasterTemplateTestData(templateName, templateTestContent);
|
||||
}
|
||||
|
||||
abstract String templateName();
|
||||
|
||||
abstract String templateTestContent();
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package tech.picnic.errorprone.documentation;
|
||||
import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import com.google.errorprone.BugPattern;
|
||||
@@ -139,14 +138,10 @@ final class BugPatternExtractorTest {
|
||||
|
||||
@Override
|
||||
public Description matchClass(ClassTree tree, VisitorState state) {
|
||||
BugPatternExtractor extractor = new BugPatternExtractor();
|
||||
|
||||
assertThatThrownBy(() -> extractor.extract(tree, state.context))
|
||||
.isInstanceOf(NullPointerException.class)
|
||||
.hasMessage("BugPattern annotation must be present");
|
||||
|
||||
return buildDescription(tree)
|
||||
.setMessage(String.format("Can extract: %s", extractor.canExtract(tree)))
|
||||
.setMessage(
|
||||
String.format(
|
||||
"Can extract: %s", new BugPatternExtractor().tryExtract(tree, state).isPresent()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
package tech.picnic.errorprone.documentation;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
final class BugPatternTestExtractorTest {
|
||||
@Test
|
||||
void noBugPatternTest(@TempDir Path outputDirectory) {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerWithoutAnnotation.java",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"",
|
||||
"public final class TestCheckerWithoutAnnotation extends BugChecker {}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
|
||||
@Test
|
||||
void bugPatternTestFileWithoutTestSuffix(@TempDir Path outputDirectory) {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerWithWrongSuffix.java",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"",
|
||||
"final class TestCheckerWithoutTestSuffix {",
|
||||
" private static class TestCheckerWithout extends BugChecker {}",
|
||||
"",
|
||||
" CompilationTestHelper compilationTestHelper = CompilationTestHelper.newInstance(TestCheckerWithout.class, getClass());",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
|
||||
@Test
|
||||
void minimalBugPatternTest(@TempDir Path outputDirectory) throws IOException {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" CompilationTestHelper compilationTestHelper = CompilationTestHelper.newInstance(TestChecker.class, getClass());",
|
||||
"}");
|
||||
|
||||
verifyFileMatchesResource(
|
||||
outputDirectory,
|
||||
"bugpattern-test-TestCheckerTest.json",
|
||||
"bugpattern-test-documentation-minimal.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void differentBugPatternAsClassVariableTest(@TempDir Path outputDirectory) {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class DifferentChecker extends BugChecker {}",
|
||||
"",
|
||||
" CompilationTestHelper compilationTestHelper = CompilationTestHelper.newInstance(DifferentChecker.class, getClass());",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
|
||||
@Test
|
||||
void differentBugPatternAsLocalVariable(@TempDir Path outputDirectory) {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class DifferentChecker extends BugChecker {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void identification() {",
|
||||
" CompilationTestHelper.newInstance(DifferentChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
assertThat(outputDirectory.toAbsolutePath()).isEmptyDirectory();
|
||||
}
|
||||
|
||||
@Test
|
||||
void bugPatternTestSingleIdentification(@TempDir Path outputDirectory) throws IOException {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void identification() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyFileMatchesResource(
|
||||
outputDirectory,
|
||||
"bugpattern-test-TestCheckerTest.json",
|
||||
"bugpattern-test-documentation-identification.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void bugPatternTestIdentificationMultipleSourceLines(@TempDir Path outputDirectory)
|
||||
throws IOException {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"package pkg;",
|
||||
"",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void identification() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"class A {}\")",
|
||||
" .addSourceLines(\"B.java\", \"class B {}\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyFileMatchesResource(
|
||||
outputDirectory,
|
||||
"bugpattern-test-TestCheckerTest.json",
|
||||
"bugpattern-test-documentation-identification-two-sources.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void bugPatternTestSingleReplacement(@TempDir Path outputDirectory) throws IOException {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void replacement() {",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A {}\")",
|
||||
" .doTest(TestMode.TEXT_MATCH);",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyFileMatchesResource(
|
||||
outputDirectory,
|
||||
"bugpattern-test-TestCheckerTest.json",
|
||||
"bugpattern-test-documentation-replacement.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void bugPatternTestMultipleReplacementSources(@TempDir Path outputDirectory) throws IOException {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void replacement() {",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A {}\")",
|
||||
" .addInputLines(\"B.java\", \"class B {}\")",
|
||||
" .addOutputLines(\"B.java\", \"class B {}\")",
|
||||
" .doTest(TestMode.TEXT_MATCH);",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyFileMatchesResource(
|
||||
outputDirectory,
|
||||
"bugpattern-test-TestCheckerTest.json",
|
||||
"bugpattern-test-documentation-replacement-two-sources.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void bugPatternReplacementExpectUnchanged(@TempDir Path outputDirectory) throws IOException {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void replacement() {",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .expectUnchanged()",
|
||||
" .doTest(TestMode.TEXT_MATCH);",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyFileMatchesResource(
|
||||
outputDirectory,
|
||||
"bugpattern-test-TestCheckerTest.json",
|
||||
"bugpattern-test-documentation-replacement-expect-unchanged.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void bugPatternTestIdentificationAndReplacement(@TempDir Path outputDirectory)
|
||||
throws IOException {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void identification() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"",
|
||||
" @Test",
|
||||
" void replacement() {",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A {}\")",
|
||||
" .doTest(TestMode.TEXT_MATCH);",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyFileMatchesResource(
|
||||
outputDirectory,
|
||||
"bugpattern-test-TestCheckerTest.json",
|
||||
"bugpattern-test-documentation-identification-and-replacement.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void bugPatternTestMultipleIdentificationAndReplacement(@TempDir Path outputDirectory)
|
||||
throws IOException {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"TestCheckerTest.java",
|
||||
"package pkg;",
|
||||
"",
|
||||
"import static com.google.errorprone.BugCheckerRefactoringTestHelper.FixChoosers.SECOND;",
|
||||
"",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper;",
|
||||
"import com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode;",
|
||||
"import com.google.errorprone.bugpatterns.BugChecker;",
|
||||
"import com.google.errorprone.CompilationTestHelper;",
|
||||
"import org.junit.jupiter.api.Test;",
|
||||
"",
|
||||
"final class TestCheckerTest {",
|
||||
" private static class TestChecker extends BugChecker {}",
|
||||
"",
|
||||
" @Test",
|
||||
" void identification() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"A.java\", \"class A {}\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"",
|
||||
" @Test",
|
||||
" void identification2() {",
|
||||
" CompilationTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addSourceLines(\"B.java\", \"class B {}\")",
|
||||
" .doTest();",
|
||||
" }",
|
||||
"",
|
||||
" @Test",
|
||||
" void replacementFirstSuggestedFix() {",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .addInputLines(\"A.java\", \"class A {}\")",
|
||||
" .addOutputLines(\"A.java\", \"class A {}\")",
|
||||
" .doTest(TestMode.TEXT_MATCH);",
|
||||
" }",
|
||||
"",
|
||||
" @Test",
|
||||
" void replacementSecondSuggestedFix() {",
|
||||
" BugCheckerRefactoringTestHelper.newInstance(TestChecker.class, getClass())",
|
||||
" .setFixChooser(SECOND)",
|
||||
" .addInputLines(\"B.java\", \"class B {}\")",
|
||||
" .addOutputLines(\"B.java\", \"class B {}\")",
|
||||
" .doTest(TestMode.TEXT_MATCH);",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
verifyFileMatchesResource(
|
||||
outputDirectory,
|
||||
"bugpattern-test-TestCheckerTest.json",
|
||||
"bugpattern-test-documentation-multiple-identification-and-replacement.json");
|
||||
}
|
||||
|
||||
private static void verifyFileMatchesResource(
|
||||
Path outputDirectory, String fileName, String resourceName) throws IOException {
|
||||
assertThat(outputDirectory.resolve(fileName))
|
||||
.content(UTF_8)
|
||||
.isEqualToIgnoringWhitespace(getResource(resourceName));
|
||||
}
|
||||
|
||||
// XXX: Once we support only JDK 15+, drop this method in favour of including the resources as
|
||||
// text blocks in this class. (This also requires renaming the `verifyFileMatchesResource`
|
||||
// method.)
|
||||
private static String getResource(String resourceName) throws IOException {
|
||||
return Resources.toString(
|
||||
Resources.getResource(BugPatternTestExtractorTest.class, resourceName), UTF_8);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,29 @@
|
||||
package tech.picnic.errorprone.documentation;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.nio.file.attribute.AclEntryPermission.ADD_SUBDIRECTORY;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.junit.jupiter.api.condition.OS.WINDOWS;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.errorprone.VisitorState;
|
||||
import com.google.errorprone.annotations.Immutable;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.AclEntry;
|
||||
import java.nio.file.attribute.AclFileAttributeView;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledOnOs;
|
||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||
@@ -74,4 +84,55 @@ final class DocumentationGeneratorTaskListenerTest {
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("Precisely one path must be provided");
|
||||
}
|
||||
|
||||
@Test
|
||||
void extraction(@TempDir Path outputDirectory) {
|
||||
Compilation.compileWithDocumentationGenerator(
|
||||
outputDirectory,
|
||||
"DocumentationGeneratorTaskListenerTestClass.java",
|
||||
"class DocumentationGeneratorTaskListenerTestClass {}");
|
||||
|
||||
// XXX: Once we support only JDK 15+, use a text block for the `expected` string.
|
||||
assertThat(
|
||||
outputDirectory.resolve(
|
||||
"documentation-generator-task-listener-test-DocumentationGeneratorTaskListenerTestClass.json"))
|
||||
.content(UTF_8)
|
||||
.isEqualToIgnoringWhitespace(
|
||||
"{\"className\":\"DocumentationGeneratorTaskListenerTestClass\",\"path\":[\"CLASS: DocumentationGeneratorTaskListenerTestClass\",\"COMPILATION_UNIT\"]}");
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@AutoService(Extractor.class)
|
||||
public static final class TestExtractor implements Extractor<ExtractionParameters> {
|
||||
@Override
|
||||
public String identifier() {
|
||||
return "documentation-generator-task-listener-test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ExtractionParameters> tryExtract(ClassTree tree, VisitorState state) {
|
||||
return Optional.of(tree.getSimpleName().toString())
|
||||
.filter(n -> n.contains(DocumentationGeneratorTaskListenerTest.class.getSimpleName()))
|
||||
.map(
|
||||
className ->
|
||||
new AutoValue_DocumentationGeneratorTaskListenerTest_ExtractionParameters(
|
||||
className,
|
||||
Streams.stream(state.getPath())
|
||||
.map(TestExtractor::describeTree)
|
||||
.collect(toImmutableList())));
|
||||
}
|
||||
|
||||
private static String describeTree(Tree tree) {
|
||||
return (tree instanceof ClassTree)
|
||||
? String.join(": ", String.valueOf(tree.getKind()), ((ClassTree) tree).getSimpleName())
|
||||
: tree.getKind().toString();
|
||||
}
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
abstract static class ExtractionParameters {
|
||||
abstract String className();
|
||||
|
||||
abstract ImmutableList<String> path();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "TestChecker",
|
||||
"identificationTests": [
|
||||
"class A {}\n"
|
||||
],
|
||||
"replacementTests": [
|
||||
{
|
||||
"inputLines": "class A {}\n",
|
||||
"outputLines": "class A {}\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "TestChecker",
|
||||
"identificationTests": [
|
||||
"class B {}\n",
|
||||
"class A {}\n"
|
||||
],
|
||||
"replacementTests": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "TestChecker",
|
||||
"identificationTests": [
|
||||
"class A {}\n"
|
||||
],
|
||||
"replacementTests": []
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "TestChecker",
|
||||
"identificationTests": [],
|
||||
"replacementTests": []
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "TestChecker",
|
||||
"identificationTests": [
|
||||
"class A {}\n",
|
||||
"class B {}\n"
|
||||
],
|
||||
"replacementTests": [
|
||||
{
|
||||
"inputLines": "class A {}\n",
|
||||
"outputLines": "class A {}\n"
|
||||
},
|
||||
{
|
||||
"inputLines": "class B {}\n",
|
||||
"outputLines": "class B {}\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "TestChecker",
|
||||
"identificationTests": [],
|
||||
"replacementTests": []
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "TestChecker",
|
||||
"identificationTests": [],
|
||||
"replacementTests": [
|
||||
{
|
||||
"inputLines": "class B {}\n",
|
||||
"outputLines": "class B {}\n"
|
||||
},
|
||||
{
|
||||
"inputLines": "class A {}\n",
|
||||
"outputLines": "class A {}\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "TestChecker",
|
||||
"identificationTests": [],
|
||||
"replacementTests": [
|
||||
{
|
||||
"inputLines": "class A {}\n",
|
||||
"outputLines": "class A {}\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -257,4 +257,33 @@
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>docgen</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-test-source</id>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
<phase>generate-test-sources</phase>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src/test/resources</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
||||
@@ -152,7 +152,7 @@ public final class ErrorProneTestHelperSourceFormat extends BugChecker
|
||||
StringBuilder source = new StringBuilder();
|
||||
|
||||
for (ExpressionTree sourceLine : sourceLines) {
|
||||
Object value = ASTHelpers.constValue(sourceLine);
|
||||
String value = ASTHelpers.constValue(sourceLine, String.class);
|
||||
if (value == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIOException;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.math.BigDecimal;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.errorprone.BugCheckerRefactoringTestHelper;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
import static java.util.Comparator.reverseOrder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.BoundType;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableListMultimap.flatteningToImmutableListMultimap;
|
||||
import static com.google.common.collect.ImmutableListMultimap.toImmutableListMultimap;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||
import static java.util.function.Function.identity;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableMultiset.toImmutableMultiset;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableSetMultimap.flatteningToImmutableSetMultimap;
|
||||
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableSortedMap.toImmutableSortedMap;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableSortedMultiset.toImmutableSortedMultiset;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
|
||||
import static java.util.Comparator.naturalOrder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static java.util.Objects.requireNonNullElse;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.primitives.Ints;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.MoreCollectors.toOptional;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import io.reactivex.BackpressureStrategy;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static java.util.Comparator.comparingInt;
|
||||
import static java.util.Comparator.reverseOrder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.errorprone.fixes.SuggestedFix;
|
||||
import com.sun.source.tree.ExpressionTree;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertEqualsNoOrder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.time.Clock;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.input;
|
||||
|
||||
import static org.springframework.http.HttpMethod.GET;
|
||||
import static org.springframework.http.HttpMethod.HEAD;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.data.Offset.offset;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -1,4 +1,4 @@
|
||||
package tech.picnic.errorprone.refasterrules;
|
||||
package tech.picnic.errorprone.refasterrules.output;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIOException;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user