Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Refaster matching algorithm #104

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions error-prone-contrib/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@
<artifactId>auto-service-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,11 @@
<artifactId>error_prone_core</artifactId>
<version>${version.error-prone}</version>
</path>
<path>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<version>${version.auto-value}</version>
</path>
<path>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
Expand Down Expand Up @@ -1521,6 +1526,11 @@
Prone bug pattern checkers, so we enable
all and then selectively deactivate some. -->
-XepAllDisabledChecksAsWarnings
<!-- Some generated classes violate Error
Prone bug patterns. We cannot in all cases
avoid that, so we simply tell Error Prone
not to warn about generated code. -->
-XepDisableWarningsInGeneratedCode
Stephan202 marked this conversation as resolved.
Show resolved Hide resolved
<!-- We don't target Android. -->
-Xep:AndroidJdkLibsChecker:OFF
<!-- XXX: Enable this once we open-source
Expand All @@ -1543,6 +1553,9 @@
-XepOpt:NullAway:AssertsEnabled=true
-XepOpt:NullAway:CheckOptionalEmptiness=true
-XepOpt:Nullness:Conservative=false
<!-- XXX: Fix this -->
-Xep:VoidMissingNullable:OFF
-Xep:ReturnMissingNullable:OFF
<!-- Append additional custom arguments. -->
${error-prone.patch-args}
${error-prone.self-check-args}
Expand Down
10 changes: 10 additions & 0 deletions refaster-runner/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
<artifactId>error_prone_check_api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${groupId.error-prone}</groupId>
<artifactId>error_prone_core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>refaster-compiler</artifactId>
Expand All @@ -42,6 +47,11 @@
<artifactId>auto-service-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package tech.picnic.errorprone.refaster.runner;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

/**
* A node in an immutable tree.
*
* <p>The tree's edges are string-labeled, while its leaves store values of type {@code T}.
*/
// XXX: Introduce JUnit tests for this class.
@AutoValue
abstract class Node<T> {
static <T> Node<T> create(Map<String, Node<T>> children, ImmutableList<T> values) {
return new AutoValue_Node<>(ImmutableSortedMap.copyOf(children), values);
}

static <T> Node<T> create(
List<T> values, Function<T, ImmutableSet<ImmutableSortedSet<String>>> pathExtractor) {
BuildNode<T> tree = BuildNode.create();
tree.register(values, pathExtractor);
return tree.immutable();
}

abstract ImmutableMap<String, Node<T>> children();

abstract ImmutableList<T> values();

void collectCandidateTemplates(ImmutableList<String> candidateEdges, Consumer<T> sink) {
values().forEach(sink);

if (candidateEdges.isEmpty() || children().isEmpty()) {
return;
}

if (children().size() < candidateEdges.size()) {
for (Map.Entry<String, Node<T>> e : children().entrySet()) {
if (candidateEdges.contains(e.getKey())) {
e.getValue().collectCandidateTemplates(candidateEdges, sink);
}
}
} else {
ImmutableList<String> remainingCandidateEdges =
candidateEdges.subList(1, candidateEdges.size());
Node<T> child = children().get(candidateEdges.get(0));
if (child != null) {
child.collectCandidateTemplates(remainingCandidateEdges, sink);
}
collectCandidateTemplates(remainingCandidateEdges, sink);
}
}

@AutoValue
@SuppressWarnings("AutoValueImmutableFields" /* Type is used only during `Node` construction. */)
abstract static class BuildNode<T> {
static <T> BuildNode<T> create() {
return new AutoValue_Node_BuildNode<>(new HashMap<>(), new ArrayList<>());
}

abstract Map<String, BuildNode<T>> children();

abstract List<T> values();

private void register(
List<T> values, Function<T, ImmutableSet<ImmutableSortedSet<String>>> pathsExtractor) {
for (T value : values) {
for (ImmutableSet<String> path : pathsExtractor.apply(value)) {
registerPath(value, path.asList());
}
}
}

private void registerPath(T value, ImmutableList<String> path) {
path.stream()
.findFirst()
.ifPresentOrElse(
edge ->
children()
.computeIfAbsent(edge, k -> BuildNode.create())
.registerPath(value, path.subList(1, path.size())),
() -> values().add(value));
}

private Node<T> immutable() {
return Node.create(
Maps.transformValues(children(), BuildNode::immutable), ImmutableList.copyOf(values()));
}
}
}
Loading