Skip to content

Commit

Permalink
Merge branch '__rultor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rultor committed Oct 13, 2022
2 parents 540bc22 + 9d22880 commit 2d99ec0
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,13 @@ private void createMatchMethod() {
final String condition = this.createCondition();
if (this.descriptor.hasTypedHole()) {
final String extractor = this.createExtractorWithTypedHoles();
String modifier = "";
if (this.descriptor.hasOnlyEllipsisOrTypedHole()) {
modifier = "final ";
}
final String code = String.format(
"boolean result = %s;\n%s\nreturn result;",
"%sboolean result = %s;\n%s\nreturn result;",
modifier,
condition,
extractor
);
Expand Down Expand Up @@ -491,14 +496,16 @@ private String formatHoleExtractor(final Hole hole, final int index) {
destination,
hole.getValue()
);
if (hole.getAttribute() == HoleAttribute.ELLIPSIS && index == 0) {
final HoleAttribute attribute = hole.getAttribute();
assert attribute != HoleAttribute.TYPED;
if (attribute == HoleAttribute.ELLIPSIS && index == 0) {
result =
String.format(
"children.put(%s.%s, node.getChildrenList());\n",
this.klass.getName(),
destination
);
} else if (hole.getAttribute() == HoleAttribute.ELLIPSIS) {
} else if (attribute == HoleAttribute.ELLIPSIS) {
this.alist = true;
final List<String> code = Arrays.asList(
"final int count = node.getChildCount();",
Expand All @@ -516,33 +523,6 @@ private String formatHoleExtractor(final Hole hole, final int index) {
)
);
result = String.join("\n", code);
} else if (hole.getAttribute() == HoleAttribute.TYPED) {
this.alist = true;
final String capacity;
if (index == 0) {
capacity = "count";
} else {
capacity = String.format("count - %d", index);
}
final List<String> code = Arrays.asList(
"final int count = node.getChildCount();",
String.format("final List<Node> list = new ArrayList<>(%s);", capacity),
String.format(
"for (int index = %d; index < count; index = index + 1) {",
index
),
"final Node child = node.getChild(index);",
String.format("if (\"%s\".equals(child.getTypeName())) {", hole.getType()),
"list.add(child);",
"}",
"}",
String.format(
"children.put(%s.%s, list);\n",
this.klass.getName(),
destination
)
);
result = String.join("\n", code);
} else {
this.collections = true;
final String srclbl = this.children.getLabel();
Expand Down
49 changes: 40 additions & 9 deletions src/main/java/org/cqfn/astranaut/rules/Descriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public boolean hasHole() {
result = true;
}
if (!result) {
result = this.hasHoleWithAttribute(attribute -> true);
result = this.hasHoleWithAttribute(attribute -> true, false);
}
return result;
}
Expand All @@ -140,7 +140,10 @@ public boolean hasHole() {
* @return Checking result, {@code true} if the descriptor has a typed hole
*/
public boolean hasTypedHole() {
return this.hasHoleWithAttribute(attribute -> attribute == HoleAttribute.TYPED);
return this.hasHoleWithAttribute(
attribute -> attribute == HoleAttribute.TYPED,
false
);
}

/**
Expand All @@ -149,7 +152,19 @@ public boolean hasTypedHole() {
*/
public boolean hasEllipsisOrTypedHole() {
return this.hasHoleWithAttribute(
attribute -> attribute == HoleAttribute.ELLIPSIS || attribute == HoleAttribute.TYPED
attribute -> attribute == HoleAttribute.ELLIPSIS || attribute == HoleAttribute.TYPED,
false
);
}

/**
* Checks whether the descriptor has only holes with ellipsis or a node type.
* @return Checking result, {@code true} if the descriptor has a hole with ellipsis
*/
public boolean hasOnlyEllipsisOrTypedHole() {
return this.hasHoleWithAttribute(
attribute -> attribute == HoleAttribute.ELLIPSIS || attribute == HoleAttribute.TYPED,
true
);
}

Expand Down Expand Up @@ -209,17 +224,33 @@ private void parametersToString(final StringBuilder builder) {
/**
* Checks whether the descriptor has a hole with specified attribute.
* @param checker Checker that checks the attribute matches some criteria
* @param exceptional The checker returns {@code true} only if the parameter list contains
* exclusively holes with these attributes
* @return Checking result, {@code true} if the descriptor has a hole with specified attribute
*/
private boolean hasHoleWithAttribute(final AttributeChecker checker) {
private boolean hasHoleWithAttribute(
final AttributeChecker checker,
final boolean exceptional) {
boolean result = false;
final List<Parameter> parameters = this.getParameters();
final ListIterator<Parameter> iterator = parameters.listIterator(parameters.size());
while (iterator.hasPrevious()) {
final Parameter parameter = iterator.previous();
if (parameter instanceof Hole && checker.check(((Hole) parameter).getAttribute())) {
result = true;
break;
if (exceptional) {
while (iterator.hasPrevious()) {
final Parameter parameter = iterator.previous();
if (parameter instanceof Hole && checker.check(((Hole) parameter).getAttribute())) {
result = true;
} else {
result = false;
break;
}
}
} else {
while (iterator.hasPrevious()) {
final Parameter parameter = iterator.previous();
if (parameter instanceof Hole && checker.check(((Hole) parameter).getAttribute())) {
result = true;
break;
}
}
}
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ void testUnknownNumberOfChildNodesWithSameType() {
Assertions.assertTrue(result > 0);
}

/**
* Test case: node contains only typed holes.
*/
@Test
void testNodeContainsOnlyEllipsisAndTypedHoles() {
final int result = this.testing(
"AAA(BBB#1, #2...)",
"matcher_generator_only_holes_with_type.txt"
);
Assertions.assertTrue(result > 0);
}

/**
* Performs a test.
* @param code Source code of descriptor
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2022 Ivan Kniazkov
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package org.uast;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.cqfn.astranaut.core.Matcher;
import org.cqfn.astranaut.core.Node;

/**
* Checks if the node matches some structure, and extracts the data and children.
*
* @since 1.0
*/
public final class Matcher0 implements Matcher {
/**
* The instance.
*/
public static final Matcher INSTANCE = new Matcher0();

/**
* Expected node type.
*/
private static final String EXPECTED_TYPE = "AAA";

/**
* The number of the first hole.
*/
private static final int FIRST_HOLE_ID = 1;

/**
* The type of the first hole.
*/
private static final String FIRST_HOLE_TYPE = "BBB";

/**
* The number of the second hole.
*/
private static final int SECOND_HOLE_ID = 2;

/**
* Constructor.
*/
private Matcher0() {
}

@Override
public boolean match(final Node node,
final Map<Integer, List<Node>> children,
final Map<Integer, String> data) {
final boolean result = node.belongsToGroup(Matcher0.EXPECTED_TYPE);
final LinkedList<Node> batch = new LinkedList<>(node.getChildrenList());
if (result) {
final List<Node> list = new LinkedList<>();
while (!batch.isEmpty()) {
final Node child = batch.pollFirst();
if (Matcher0.FIRST_HOLE_TYPE.equals(child.getTypeName())) {
list.add(child);
} else {
batch.addFirst(child);
break;
}
}
children.put(Matcher0.FIRST_HOLE_ID, list);
}
if (result) {
final List<Node> list = new LinkedList<>();
while (!batch.isEmpty()) {
list.add(batch.pollFirst());
}
children.put(Matcher0.SECOND_HOLE_ID, list);
}
return result;
}
}

0 comments on commit 2d99ec0

Please sign in to comment.