diff --git a/src/main/java/org/cqfn/astranaut/core/algorithms/SubtreeBuilder.java b/src/main/java/org/cqfn/astranaut/core/algorithms/SubtreeBuilder.java index 46cefe9..cbb2445 100644 --- a/src/main/java/org/cqfn/astranaut/core/algorithms/SubtreeBuilder.java +++ b/src/main/java/org/cqfn/astranaut/core/algorithms/SubtreeBuilder.java @@ -43,13 +43,14 @@ public class SubtreeBuilder { /** * Algorithm that composes a subtree only from the nodes that are specified in the set. */ - public static final Algorithm INCLUDE = (node, set) -> set.contains(node); + public static final Algorithm INCLUDE = SubtreeBuilder::isPresentInSet; /** * Algorithm that composes a subtree from all nodes in the original tree, * but excludes nodes specified in the set. */ - public static final Algorithm EXCLUDE = (node, set) -> !set.contains(node); + public static final Algorithm EXCLUDE = + (node, set) -> !SubtreeBuilder.isPresentInSet(node, set); /** * The root node of the original tree. @@ -118,6 +119,20 @@ private void build(final Node node, final Map> indexes, } } + /** + * Checks whether a node or its prototype is present in the node set. + * @param node Node to be checked + * @param set Set of nodes + * @return Checking result. + */ + private static boolean isPresentInSet(final Node node, final Set set) { + boolean result = set.contains(node); + if (!result && node instanceof PrototypeBasedNode) { + result = SubtreeBuilder.isPresentInSet(((PrototypeBasedNode) node).getPrototype(), set); + } + return result; + } + /** * An algorithm that selects nodes based on some criteria. * @since 1.1.4 diff --git a/src/main/java/org/cqfn/astranaut/core/base/PatternNode.java b/src/main/java/org/cqfn/astranaut/core/base/PatternNode.java index 95718d1..d17701f 100644 --- a/src/main/java/org/cqfn/astranaut/core/base/PatternNode.java +++ b/src/main/java/org/cqfn/astranaut/core/base/PatternNode.java @@ -125,14 +125,11 @@ private static List initChildrenList(final Node original) { final List result = new ArrayList<>(count); for (int index = 0; index < count; index = index + 1) { final Node child = original.getChild(index); - if (child instanceof DiffNode) { - result.add( - new PatternNode(((DiffNode) child).getPrototype()) - ); - } else if (child instanceof Action) { - result.add((PatternItem) child); - } else { + final Action action = Action.toAction(child); + if (action == null) { result.add(new PatternNode(child)); + } else { + result.add(action); } } return result; diff --git a/src/test/java/org/cqfn/astranaut/core/algorithms/PatternBuilderTest.java b/src/test/java/org/cqfn/astranaut/core/algorithms/PatternBuilderTest.java index 51ab716..457a71e 100644 --- a/src/test/java/org/cqfn/astranaut/core/algorithms/PatternBuilderTest.java +++ b/src/test/java/org/cqfn/astranaut/core/algorithms/PatternBuilderTest.java @@ -35,6 +35,7 @@ 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.base.Replace; import org.cqfn.astranaut.core.base.Tree; import org.cqfn.astranaut.core.example.green.Addition; import org.cqfn.astranaut.core.example.green.ExpressionStatement; @@ -89,9 +90,9 @@ void creatingPatternFromSubtree() { final Node var = ctor.createNode(); ctor = new IntegerLiteral.Constructor(); ctor.setData("1"); - final Node second = ctor.createNode(); + final Node before = ctor.createNode(); ctor = new Addition.Constructor(); - ctor.setChildrenList(Arrays.asList(var, second)); + ctor.setChildrenList(Arrays.asList(var, before)); final Node addition = ctor.createNode(); ctor = new Variable.Constructor(); ctor.setData("x"); @@ -108,19 +109,23 @@ void creatingPatternFromSubtree() { ctor.setChildrenList(Arrays.asList(stmt, ret)); final Node block = ctor.createNode(); final Tree tree = new Tree(block); + ctor = new IntegerLiteral.Constructor(); + ctor.setData("2"); + final Node after = ctor.createNode(); + final DiffTreeBuilder diffbuilder = new DiffTreeBuilder(tree); + diffbuilder.replaceNode(before, after); + final DiffTree diff = diffbuilder.getDiffTree(); final Set exclude = new HashSet<>(); exclude.add(ret); final Tree subtree = new Tree( - new SubtreeBuilder(tree, SubtreeBuilder.EXCLUDE).create(exclude) + new SubtreeBuilder(diff, SubtreeBuilder.EXCLUDE).create(exclude) ); - final PatternBuilder builder = new PatternBuilder(subtree); - builder.makeHole(var, 1); - final Pattern pattern = builder.getPattern(); - Assertions.assertNotNull(pattern); + final PatternBuilder ptbuilder = new PatternBuilder(subtree); + ptbuilder.makeHole(var, 1); + final Pattern pattern = ptbuilder.getPattern(); final DepthFirstWalker traversal = new DepthFirstWalker(pattern.getRoot()); - final Optional hole = traversal.findFirst(node -> node instanceof Hole); - Assertions.assertTrue(hole.isPresent()); - Assertions.assertEquals("#1", hole.get().getData()); + Assertions.assertTrue(traversal.findFirst(node -> node instanceof Replace).isPresent()); + Assertions.assertTrue(traversal.findFirst(node -> node instanceof Hole).isPresent()); } @Test