Skip to content

Commit

Permalink
Patcher uses 'Tree' and 'Pattern' classes as input
Browse files Browse the repository at this point in the history
  • Loading branch information
kniazkov committed Jun 27, 2024
1 parent a1bf88c commit bba0a74
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import org.cqfn.astranaut.core.base.ActionList;
import org.cqfn.astranaut.core.base.DiffTree;
import org.cqfn.astranaut.core.base.Node;
import org.cqfn.astranaut.core.base.PatternNode;
import org.cqfn.astranaut.core.base.Pattern;
import org.cqfn.astranaut.core.base.Tree;

/**
Expand All @@ -38,8 +38,8 @@
*/
public final class DefaultPatcher implements Patcher {
@Override
public Tree patch(final Tree source, final PatternNode pattern) {
final PatternMatcher matcher = new PatternMatcher(source.getRoot());
public Tree patch(final Tree source, final Pattern pattern) {
final PatternMatcher matcher = new PatternMatcher(source);
final Set<Node> nodes = matcher.match(pattern);
final Tree result;
if (nodes.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
package org.cqfn.astranaut.core.algorithms.patching;

import org.cqfn.astranaut.core.base.PatternNode;
import org.cqfn.astranaut.core.base.Pattern;
import org.cqfn.astranaut.core.base.Tree;

/**
Expand All @@ -39,5 +39,5 @@ public interface Patcher {
* @param pattern Root node af a pattern
* @return Root node of updated syntax tree
*/
Tree patch(Tree source, PatternNode pattern);
Tree patch(Tree source, Pattern pattern);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
import org.cqfn.astranaut.core.base.Hole;
import org.cqfn.astranaut.core.base.Insert;
import org.cqfn.astranaut.core.base.Node;
import org.cqfn.astranaut.core.base.Pattern;
import org.cqfn.astranaut.core.base.PatternNode;
import org.cqfn.astranaut.core.base.Replace;
import org.cqfn.astranaut.core.base.Tree;

/**
* The matcher matches syntax tree and patterns.
Expand All @@ -55,10 +57,10 @@ class PatternMatcher {

/**
* Constructor.
* @param root Root node of the tree in which patterns are searched
* @param tree The syntax tree in which patterns will be searched
*/
PatternMatcher(final Node root) {
this.root = root;
PatternMatcher(final Tree tree) {
this.root = tree.getRoot();
this.actions = new ActionList();
}

Expand All @@ -75,15 +77,16 @@ public ActionList getActionList() {
* @param pattern Root node of the pattern
* @return Nodes that match the root node of the pattern
*/
Set<Node> match(final PatternNode pattern) {
Set<Node> match(final Pattern pattern) {
final DeepTraversal deep = new DeepTraversal(this.root);
final PatternNode head = pattern.getRoot();
final List<Node> preset = deep.findAll(
node -> node.getTypeName().equals(pattern.getTypeName())
&& node.getData().equals(pattern.getData())
node -> node.getTypeName().equals(head.getTypeName())
&& node.getData().equals(head.getData())
);
final Set<Node> set = new HashSet<>();
for (final Node node : preset) {
final boolean matches = this.checkNode(node, null, pattern);
final boolean matches = this.checkNode(node, null, head);
if (matches) {
set.add(node);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;

import org.cqfn.astranaut.core.base.*;
import org.cqfn.astranaut.core.base.Builder;
import org.cqfn.astranaut.core.base.DiffNode;
import org.cqfn.astranaut.core.base.DraftNode;
import org.cqfn.astranaut.core.base.Hole;
import org.cqfn.astranaut.core.base.Node;
import org.cqfn.astranaut.core.base.Pattern;
import org.cqfn.astranaut.core.example.green.Addition;
import org.cqfn.astranaut.core.example.green.ExpressionStatement;
import org.cqfn.astranaut.core.example.green.IntegerLiteral;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@
import java.util.TreeMap;
import org.cqfn.astranaut.core.algorithms.DiffTreeBuilder;
import org.cqfn.astranaut.core.algorithms.PatternBuilder;
import org.cqfn.astranaut.core.base.*;
import org.cqfn.astranaut.core.base.Builder;
import org.cqfn.astranaut.core.base.DiffNode;
import org.cqfn.astranaut.core.base.DraftNode;
import org.cqfn.astranaut.core.base.Insertion;
import org.cqfn.astranaut.core.base.Node;
import org.cqfn.astranaut.core.base.Pattern;
import org.cqfn.astranaut.core.base.PatternNode;
import org.cqfn.astranaut.core.base.Tree;
import org.cqfn.astranaut.core.example.green.Addition;
import org.cqfn.astranaut.core.example.green.ExpressionStatement;
import org.cqfn.astranaut.core.example.green.IntegerLiteral;
Expand All @@ -48,9 +55,12 @@ class PatcherTest {
@Test
void patchingByPatternThatDoesNotMatch() {
final Tree source = Tree.createDraft("A(B,C,D)");
final PatternNode pattern = new PatternNode(
new DiffNode(
DraftNode.create("D")
final Pattern pattern =
new Pattern(
new PatternNode(
new DiffNode(
DraftNode.create("E")
)
)
);
final Patcher patcher = new DefaultPatcher();
Expand All @@ -70,7 +80,7 @@ void patchPatternWithInsertion() {
nodes.get("B").iterator().next()
)
);
final PatternNode pattern = new PatternNode(builder.getDiffTree().getRoot());
final Pattern pattern = new Pattern(new PatternNode(builder.getDiffTree().getRoot()));
final Tree tree = Tree.createDraft("X(Y,A(B),Z)");
final Patcher patcher = new DefaultPatcher();
final Tree result = patcher.patch(tree, pattern);
Expand All @@ -84,7 +94,7 @@ void patchPatternWithReplacement() {
final Node prepattern = DraftNode.create("A(B, D)", nodes);
final DiffTreeBuilder builder = new DiffTreeBuilder(prepattern);
builder.replaceNode(nodes.get("B").iterator().next(), DraftNode.create("C"));
final PatternNode pattern = new PatternNode(builder.getDiffTree().getRoot());
final Pattern pattern = new Pattern(new PatternNode(builder.getDiffTree().getRoot()));
final Tree tree = Tree.createDraft("X(Y,A(B,D),Z)");
final Patcher patcher = new DefaultPatcher();
final Tree result = patcher.patch(tree, pattern);
Expand All @@ -98,7 +108,7 @@ void patchPatternWithDeletion() {
final Node prepattern = DraftNode.create("A(B, D)", nodes);
final DiffTreeBuilder builder = new DiffTreeBuilder(prepattern);
builder.deleteNode(nodes.get("B").iterator().next());
final PatternNode pattern = new PatternNode(builder.getDiffTree().getRoot());
final Pattern pattern = new Pattern(new PatternNode(builder.getDiffTree().getRoot()));
final Tree tree = Tree.createDraft("X(Y,A(B,D),Z)");
final Patcher patcher = new DefaultPatcher();
final Tree result = patcher.patch(tree, pattern);
Expand Down Expand Up @@ -128,7 +138,7 @@ void patchPatternWithHole() {
final Node stmt = ctor.createNode();
final Patcher patcher = new DefaultPatcher();
final Pattern pattern = PatcherTest.createPatternWithHole();
final Tree patched = patcher.patch(new Tree(stmt), pattern.getRoot());
final Tree patched = patcher.patch(new Tree(stmt), pattern);
ctor = new Variable.Constructor();
ctor.setData("a");
first = ctor.createNode();
Expand Down Expand Up @@ -156,7 +166,7 @@ void patchWithPatternThatDoesNotMatch() {
final Node prepattern = DraftNode.create("E(B,D)", nodes);
final DiffTreeBuilder builder = new DiffTreeBuilder(prepattern);
builder.replaceNode(nodes.get("B").iterator().next(), DraftNode.create("C"));
final PatternNode pattern = new PatternNode(builder.getDiffTree().getRoot());
final Pattern pattern = new Pattern(new PatternNode(builder.getDiffTree().getRoot()));
final Tree tree = Tree.createDraft("X(Y,K(B,D),Z)");
final Patcher patcher = new DefaultPatcher();
final Tree result = patcher.patch(tree, pattern);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@
import java.util.TreeMap;
import org.cqfn.astranaut.core.algorithms.DiffTreeBuilder;
import org.cqfn.astranaut.core.algorithms.PatternBuilder;
import org.cqfn.astranaut.core.base.*;
import org.cqfn.astranaut.core.base.DiffNode;
import org.cqfn.astranaut.core.base.DraftNode;
import org.cqfn.astranaut.core.base.Insertion;
import org.cqfn.astranaut.core.base.Node;
import org.cqfn.astranaut.core.base.Pattern;
import org.cqfn.astranaut.core.base.PatternNode;
import org.cqfn.astranaut.core.base.Tree;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

Expand All @@ -40,9 +46,9 @@
class PatternMatcherTest {
@Test
void findSubtreeInATree() {
final Node tree = DraftNode.create("X(Y(A(B,C)),A(B,C),A(B,D))");
final Tree tree = Tree.createDraft("X(Y(A(B,C)),A(B,C),A(B,D))");
final DiffNode subtree = new DiffNode(DraftNode.create("A(B,C)"));
final PatternNode pattern = new PatternNode(subtree);
final Pattern pattern = new Pattern(new PatternNode(subtree));
final PatternMatcher matcher = new PatternMatcher(tree);
final Set<Node> found = matcher.match(pattern);
Assertions.assertEquals(2, found.size());
Expand All @@ -53,12 +59,12 @@ void findSubtreeInATree() {

@Test
void findReducedSubtreeInATree() {
final Node tree = DraftNode.create("X(A(B,C(F),D,E),A(B,D,E),A(B))");
final Tree tree = Tree.createDraft("X(A(B,C(F),D,E),A(B,D,E),A(B))");
final DiffNode subtree = new DiffNode(
DraftNode.create("A(C(F),D)")
);
final PatternMatcher matcher = new PatternMatcher(tree);
final PatternNode pattern = new PatternNode(subtree);
final Pattern pattern = new Pattern(new PatternNode(subtree));
final Set<Node> found = matcher.match(pattern);
Assertions.assertEquals(1, found.size());
final Node node = found.iterator().next();
Expand All @@ -78,8 +84,8 @@ void findPatternWithInsertionInATree() {
nodes.get("B").iterator().next()
)
);
final PatternNode pattern = new PatternNode(builder.getDiffTree().getRoot());
final Node tree = DraftNode.create("X(Y,A(B),Z)");
final Pattern pattern = new Pattern(new PatternNode(builder.getDiffTree().getRoot()));
final Tree tree = Tree.createDraft("X(Y,A(B),Z)");
final PatternMatcher matcher = new PatternMatcher(tree);
final Set<Node> found = matcher.match(pattern);
Assertions.assertEquals(1, found.size());
Expand All @@ -93,8 +99,8 @@ void findPatternWithReplacementInATree() {
final Node prepattern = DraftNode.create("A(B, D)", nodes);
final DiffTreeBuilder builder = new DiffTreeBuilder(prepattern);
builder.replaceNode(nodes.get("B").iterator().next(), DraftNode.create("C"));
final PatternNode pattern = new PatternNode(builder.getDiffTree().getRoot());
final Node tree = DraftNode.create("X(Y,A(B,D),Z)");
final Pattern pattern = new Pattern(new PatternNode(builder.getDiffTree().getRoot()));
final Tree tree = Tree.createDraft("X(Y,A(B,D),Z)");
final PatternMatcher matcher = new PatternMatcher(tree);
final Set<Node> found = matcher.match(pattern);
Assertions.assertEquals(1, found.size());
Expand All @@ -108,8 +114,8 @@ void findPatternWithDeletionInATree() {
final Node prepattern = DraftNode.create("A(B, D)", nodes);
final DiffTreeBuilder builder = new DiffTreeBuilder(prepattern);
builder.deleteNode(nodes.get("B").iterator().next());
final PatternNode pattern = new PatternNode(builder.getDiffTree().getRoot());
final Node tree = DraftNode.create("X(Y,A(B,D),Z)");
final Pattern pattern = new Pattern(new PatternNode(builder.getDiffTree().getRoot()));
final Tree tree = Tree.createDraft("X(Y,A(B,D),Z)");
final PatternMatcher matcher = new PatternMatcher(tree);
final Set<Node> found = matcher.match(pattern);
Assertions.assertEquals(1, found.size());
Expand All @@ -127,35 +133,39 @@ void findPatternWithHoleInATree() {
final boolean flag = pbuilder.makeHole(nodes.get("D").iterator().next(), 0);
Assertions.assertTrue(flag);
final Pattern pattern = pbuilder.getPattern();
final Node tree = DraftNode.create("X(Y,A(B,D<\"11\">),Z)");
final Tree tree = Tree.createDraft("X(Y,A(B,D<\"11\">),Z)");
final PatternMatcher matcher = new PatternMatcher(tree);
final Set<Node> found = matcher.match(pattern.getRoot());
final Set<Node> found = matcher.match(pattern);
Assertions.assertEquals(1, found.size());
final Node node = found.iterator().next();
Assertions.assertEquals("A", node.getTypeName());
}

@Test
void matchPatternWithData() {
final PatternNode pattern = new PatternNode(
new DiffNode(
DraftNode.create("A(B<\"test\">)")
final Pattern pattern = new Pattern(
new PatternNode(
new DiffNode(
DraftNode.create("A(B<\"test\">)")
)
)
);
final Node tree = DraftNode.create("X(Y, A(B<\"test\">), Z)");
final Tree tree = Tree.createDraft("X(Y, A(B<\"test\">), Z)");
final PatternMatcher matcher = new PatternMatcher(tree);
final Set<Node> found = matcher.match(pattern);
Assertions.assertEquals(1, found.size());
}

@Test
void matchPatternThatIsTooBig() {
final PatternNode pattern = new PatternNode(
new DiffNode(
DraftNode.create("A(B,C,D,E,F)")
final Pattern pattern = new Pattern(
new PatternNode(
new DiffNode(
DraftNode.create("A(B,C,D,E,F)")
)
)
);
final Node tree = DraftNode.create("X(Y,A(B,C),Z)");
final Tree tree = Tree.createDraft("X(Y,A(B,C),Z)");
final PatternMatcher matcher = new PatternMatcher(tree);
final Set<Node> found = matcher.match(pattern);
Assertions.assertEquals(0, found.size());
Expand Down

0 comments on commit bba0a74

Please sign in to comment.