Skip to content

Commit ca3c8bd

Browse files
committed
Extract API to package
1 parent 58f974a commit ca3c8bd

File tree

9 files changed

+210
-211
lines changed

9 files changed

+210
-211
lines changed

java/src/main/java/io/cucumber/cucumberexpressions/Ast.java

Lines changed: 21 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,11 @@
11
package io.cucumber.cucumberexpressions;
22

3-
import org.apiguardian.api.API;
4-
5-
import java.util.List;
63
import java.util.Objects;
74
import java.util.StringJoiner;
85

96
import static java.util.Objects.requireNonNull;
10-
import static java.util.stream.Collectors.joining;
11-
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
12-
13-
@API(since = "18.1", status = EXPERIMENTAL)
14-
public final class Ast {
157

16-
public static final char escapeCharacter = '\\';
17-
public static final char alternationCharacter = '/';
18-
public static final char beginParameterCharacter = '{';
19-
public static final char endParameterCharacter = '}';
20-
public static final char beginOptionalCharacter = '(';
21-
public static final char endOptionalCharacter = ')';
8+
final class Ast {
229

2310
interface Located {
2411
int start();
@@ -27,143 +14,21 @@ interface Located {
2714

2815
}
2916

30-
public static final class Node implements Located {
31-
32-
private final NodeType type;
33-
private final List<Node> nodes;
34-
private final String token;
35-
private final int start;
36-
private final int end;
37-
38-
Node(NodeType type, int start, int end, String token) {
39-
this(type, start, end, null, requireNonNull(token));
40-
}
41-
42-
Node(NodeType type, int start, int end, List<Node> nodes) {
43-
this(type, start, end, requireNonNull(nodes), null);
44-
}
45-
46-
private Node(NodeType type, int start, int end, List<Node> nodes, String token) {
47-
this.type = requireNonNull(type);
48-
this.nodes = nodes;
49-
this.token = token;
50-
this.start = start;
51-
this.end = end;
52-
}
53-
54-
public enum NodeType {
55-
TEXT_NODE,
56-
OPTIONAL_NODE,
57-
ALTERNATION_NODE,
58-
ALTERNATIVE_NODE,
59-
PARAMETER_NODE,
60-
EXPRESSION_NODE
61-
}
62-
63-
public int start() {
64-
return start;
65-
}
66-
67-
public int end() {
68-
return end;
69-
}
70-
71-
/**
72-
* @return child nodes, {@code null} if a leaf-node
73-
*/
74-
public List<Node> nodes() {
75-
return nodes;
76-
}
77-
78-
public NodeType type() {
79-
return type;
80-
}
81-
82-
/**
83-
* @return the text contained with in this node, {@code null} if not a leaf-node
84-
*/
85-
public String token() {
86-
return token;
87-
}
88-
89-
String text() {
90-
if (nodes == null)
91-
return token;
92-
93-
return nodes().stream()
94-
.map(Node::text)
95-
.collect(joining());
96-
}
97-
98-
@Override
99-
public String toString() {
100-
return toString(0).toString();
101-
}
102-
103-
private StringBuilder toString(int depth) {
104-
StringBuilder sb = new StringBuilder();
105-
for (int i = 0; i < depth; i++) {
106-
sb.append(" ");
107-
}
108-
sb.append("{")
109-
.append("\"type\": \"").append(type)
110-
.append("\", \"start\": ")
111-
.append(start)
112-
.append(", \"end\": ")
113-
.append(end);
114-
115-
if (token != null) {
116-
sb.append(", \"token\": \"").append(token.replaceAll("\\\\", "\\\\\\\\")).append("\"");
117-
}
118-
119-
if (nodes != null) {
120-
sb.append(", \"nodes\": ");
121-
if (!nodes.isEmpty()) {
122-
StringBuilder padding = new StringBuilder();
123-
for (int i = 0; i < depth; i++) {
124-
padding.append(" ");
125-
}
126-
sb.append(nodes.stream()
127-
.map(node -> node.toString(depth + 1))
128-
.collect(joining(",\n", "[\n", "\n" + padding + "]")));
129-
130-
} else {
131-
sb.append("[]");
132-
}
133-
}
134-
sb.append("}");
135-
return sb;
136-
}
137-
138-
@Override
139-
public boolean equals(Object o) {
140-
if (this == o)
141-
return true;
142-
if (o == null || getClass() != o.getClass())
143-
return false;
144-
Node node = (Node) o;
145-
return start == node.start &&
146-
end == node.end &&
147-
type == node.type &&
148-
Objects.equals(nodes, node.nodes) &&
149-
Objects.equals(token, node.token);
150-
}
151-
152-
@Override
153-
public int hashCode() {
154-
return Objects.hash(type, nodes, token, start, end);
155-
}
156-
157-
}
158-
15917
static final class Token implements Located {
16018

19+
private static final char escapeCharacter = '\\';
20+
private static final char alternationCharacter = '/';
21+
private static final char beginParameterCharacter = '{';
22+
private static final char endParameterCharacter = '}';
23+
private static final char beginOptionalCharacter = '(';
24+
private static final char endOptionalCharacter = ')';
25+
16126
final String text;
162-
final TokenType type;
27+
final Type type;
16328
final int start;
16429
final int end;
16530

166-
Token(String text, TokenType type, int start, int end) {
31+
Token(String text, Type type, int start, int end) {
16732
this.text = requireNonNull(text);
16833
this.type = requireNonNull(type);
16934
this.start = start;
@@ -186,23 +51,23 @@ static boolean canEscape(Integer token) {
18651
return false;
18752
}
18853

189-
static TokenType typeOf(Integer token) {
54+
static Type typeOf(Integer token) {
19055
if (Character.isWhitespace(token)) {
191-
return TokenType.WHITE_SPACE;
56+
return Type.WHITE_SPACE;
19257
}
19358
switch (token) {
19459
case (int) alternationCharacter:
195-
return TokenType.ALTERNATION;
60+
return Type.ALTERNATION;
19661
case (int) beginParameterCharacter:
197-
return TokenType.BEGIN_PARAMETER;
62+
return Type.BEGIN_PARAMETER;
19863
case (int) endParameterCharacter:
199-
return TokenType.END_PARAMETER;
64+
return Type.END_PARAMETER;
20065
case (int) beginOptionalCharacter:
201-
return TokenType.BEGIN_OPTIONAL;
66+
return Type.BEGIN_OPTIONAL;
20267
case (int) endOptionalCharacter:
203-
return TokenType.END_OPTIONAL;
68+
return Type.END_OPTIONAL;
20469
}
205-
return TokenType.TEXT;
70+
return Type.TEXT;
20671
}
20772

20873
static boolean isEscapeCharacter(int token) {
@@ -245,7 +110,7 @@ public String toString() {
245110
.toString();
246111
}
247112

248-
enum TokenType {
113+
enum Type {
249114
START_OF_LINE,
250115
END_OF_LINE,
251116
WHITE_SPACE,
@@ -259,11 +124,11 @@ enum TokenType {
259124
private final String symbol;
260125
private final String purpose;
261126

262-
TokenType() {
127+
Type() {
263128
this(null, null);
264129
}
265130

266-
TokenType(String symbol, String purpose) {
131+
Type(String symbol, String purpose) {
267132
this.symbol = symbol;
268133
this.purpose = purpose;
269134
}

java/src/main/java/io/cucumber/cucumberexpressions/CucumberExpression.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
package io.cucumber.cucumberexpressions;
22

3-
import io.cucumber.cucumberexpressions.Ast.Node;
4-
import io.cucumber.cucumberexpressions.Ast.Node.NodeType;
3+
import io.cucumber.cucumberexpressions.Node.Type;
54
import org.apiguardian.api.API;
65

7-
import java.lang.reflect.Type;
86
import java.util.ArrayList;
97
import java.util.List;
108
import java.util.function.Function;
119
import java.util.regex.Pattern;
1210

13-
import static io.cucumber.cucumberexpressions.Ast.Node.NodeType.OPTIONAL_NODE;
14-
import static io.cucumber.cucumberexpressions.Ast.Node.NodeType.PARAMETER_NODE;
15-
import static io.cucumber.cucumberexpressions.Ast.Node.NodeType.TEXT_NODE;
11+
import static io.cucumber.cucumberexpressions.Node.Type.OPTIONAL_NODE;
12+
import static io.cucumber.cucumberexpressions.Node.Type.PARAMETER_NODE;
13+
import static io.cucumber.cucumberexpressions.Node.Type.TEXT_NODE;
1614
import static io.cucumber.cucumberexpressions.CucumberExpressionException.createAlternativeMayNotBeEmpty;
1715
import static io.cucumber.cucumberexpressions.CucumberExpressionException.createAlternativeMayNotExclusivelyContainOptionals;
1816
import static io.cucumber.cucumberexpressions.CucumberExpressionException.createOptionalIsNotAllowedInOptional;
@@ -129,7 +127,7 @@ private void assertNoOptionals(Node node,
129127
assertNoNodeOfType(OPTIONAL_NODE, node, createNodeContainedAnOptionalException);
130128
}
131129

132-
private void assertNoNodeOfType(NodeType nodeType, Node node,
130+
private void assertNoNodeOfType(Type nodeType, Node node,
133131
Function<Node, CucumberExpressionException> createException) {
134132
node.nodes()
135133
.stream()
@@ -143,7 +141,7 @@ private void assertNoNodeOfType(NodeType nodeType, Node node,
143141

144142

145143
@Override
146-
public List<Argument<?>> match(String text, Type... typeHints) {
144+
public List<Argument<?>> match(String text, java.lang.reflect.Type... typeHints) {
147145
final Group group = treeRegexp.match(text);
148146
if (group == null) {
149147
return null;
@@ -152,7 +150,7 @@ public List<Argument<?>> match(String text, Type... typeHints) {
152150
List<ParameterType<?>> parameterTypes = new ArrayList<>(this.parameterTypes);
153151
for (int i = 0; i < parameterTypes.size(); i++) {
154152
ParameterType<?> parameterType = parameterTypes.get(i);
155-
Type type = i < typeHints.length ? typeHints[i] : String.class;
153+
java.lang.reflect.Type type = i < typeHints.length ? typeHints[i] : String.class;
156154
if (parameterType.isAnonymous()) {
157155
ParameterByTypeTransformer defaultTransformer = parameterTypeRegistry.getDefaultParameterTransformer();
158156
parameterTypes.set(i, parameterType.deAnonymize(type, arg -> defaultTransformer.transform(arg, type)));

java/src/main/java/io/cucumber/cucumberexpressions/CucumberExpressionException.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package io.cucumber.cucumberexpressions;
22

33
import io.cucumber.cucumberexpressions.Ast.Located;
4-
import io.cucumber.cucumberexpressions.Ast.Node;
54
import io.cucumber.cucumberexpressions.Ast.Token;
6-
import io.cucumber.cucumberexpressions.Ast.Token.TokenType;
5+
import io.cucumber.cucumberexpressions.Ast.Token.Type;
76
import org.apiguardian.api.API;
87

98
@API(status = API.Status.STABLE)
@@ -17,7 +16,7 @@ public class CucumberExpressionException extends RuntimeException {
1716
super(message, cause);
1817
}
1918

20-
static CucumberExpressionException createMissingEndToken(String expression, TokenType beginToken, TokenType endToken,
19+
static CucumberExpressionException createMissingEndToken(String expression, Type beginToken, Type endToken,
2120
Token current) {
2221
return new CucumberExpressionException(message(
2322
current.start(),

java/src/main/java/io/cucumber/cucumberexpressions/CucumberExpressionParser.java

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
package io.cucumber.cucumberexpressions;
22

3-
import io.cucumber.cucumberexpressions.Ast.Node;
43
import io.cucumber.cucumberexpressions.Ast.Token;
5-
import io.cucumber.cucumberexpressions.Ast.Token.TokenType;
4+
import io.cucumber.cucumberexpressions.Ast.Token.Type;
65
import org.apiguardian.api.API;
76

87
import java.util.ArrayList;
98
import java.util.Arrays;
109
import java.util.List;
1110

12-
import static io.cucumber.cucumberexpressions.Ast.Node.NodeType.ALTERNATION_NODE;
13-
import static io.cucumber.cucumberexpressions.Ast.Node.NodeType.ALTERNATIVE_NODE;
14-
import static io.cucumber.cucumberexpressions.Ast.Node.NodeType.EXPRESSION_NODE;
15-
import static io.cucumber.cucumberexpressions.Ast.Node.NodeType.OPTIONAL_NODE;
16-
import static io.cucumber.cucumberexpressions.Ast.Node.NodeType.PARAMETER_NODE;
17-
import static io.cucumber.cucumberexpressions.Ast.Node.NodeType.TEXT_NODE;
18-
import static io.cucumber.cucumberexpressions.Ast.Token.TokenType.ALTERNATION;
19-
import static io.cucumber.cucumberexpressions.Ast.Token.TokenType.BEGIN_OPTIONAL;
20-
import static io.cucumber.cucumberexpressions.Ast.Token.TokenType.BEGIN_PARAMETER;
21-
import static io.cucumber.cucumberexpressions.Ast.Token.TokenType.END_OF_LINE;
22-
import static io.cucumber.cucumberexpressions.Ast.Token.TokenType.END_OPTIONAL;
23-
import static io.cucumber.cucumberexpressions.Ast.Token.TokenType.END_PARAMETER;
24-
import static io.cucumber.cucumberexpressions.Ast.Token.TokenType.START_OF_LINE;
25-
import static io.cucumber.cucumberexpressions.Ast.Token.TokenType.WHITE_SPACE;
11+
import static io.cucumber.cucumberexpressions.Node.Type.ALTERNATION_NODE;
12+
import static io.cucumber.cucumberexpressions.Node.Type.ALTERNATIVE_NODE;
13+
import static io.cucumber.cucumberexpressions.Node.Type.EXPRESSION_NODE;
14+
import static io.cucumber.cucumberexpressions.Node.Type.OPTIONAL_NODE;
15+
import static io.cucumber.cucumberexpressions.Node.Type.PARAMETER_NODE;
16+
import static io.cucumber.cucumberexpressions.Node.Type.TEXT_NODE;
17+
import static io.cucumber.cucumberexpressions.Ast.Token.Type.ALTERNATION;
18+
import static io.cucumber.cucumberexpressions.Ast.Token.Type.BEGIN_OPTIONAL;
19+
import static io.cucumber.cucumberexpressions.Ast.Token.Type.BEGIN_PARAMETER;
20+
import static io.cucumber.cucumberexpressions.Ast.Token.Type.END_OF_LINE;
21+
import static io.cucumber.cucumberexpressions.Ast.Token.Type.END_OPTIONAL;
22+
import static io.cucumber.cucumberexpressions.Ast.Token.Type.END_PARAMETER;
23+
import static io.cucumber.cucumberexpressions.Ast.Token.Type.START_OF_LINE;
24+
import static io.cucumber.cucumberexpressions.Ast.Token.Type.WHITE_SPACE;
2625
import static io.cucumber.cucumberexpressions.CucumberExpressionException.createAlternationNotAllowedInOptional;
2726
import static io.cucumber.cucumberexpressions.CucumberExpressionException.createInvalidParameterTypeName;
2827
import static io.cucumber.cucumberexpressions.CucumberExpressionException.createMissingEndToken;
@@ -200,9 +199,9 @@ private Result(int consumed, List<Node> ast) {
200199
}
201200

202201
private static Parser parseBetween(
203-
Node.NodeType type,
204-
TokenType beginToken,
205-
TokenType endToken,
202+
Node.Type type,
203+
Type beginToken,
204+
Type endToken,
206205
List<Parser> parsers) {
207206
return (expression, tokens, current) -> {
208207
if (!lookingAt(tokens, current, beginToken)) {
@@ -228,7 +227,7 @@ private static Result parseTokensUntil(
228227
List<Parser> parsers,
229228
List<Token> tokens,
230229
int startAt,
231-
TokenType... endTokens) {
230+
Type... endTokens) {
232231
int current = startAt;
233232
int size = tokens.size();
234233
List<Node> ast = new ArrayList<>();
@@ -262,16 +261,16 @@ private static Result parseToken(String expression, List<Parser> parsers,
262261
throw new IllegalStateException("No eligible parsers for " + tokens);
263262
}
264263

265-
private static boolean lookingAtAny(List<Token> tokens, int at, TokenType... tokenTypes) {
266-
for (TokenType tokeType : tokenTypes) {
264+
private static boolean lookingAtAny(List<Token> tokens, int at, Type... tokenTypes) {
265+
for (Type tokeType : tokenTypes) {
267266
if (lookingAt(tokens, at, tokeType)) {
268267
return true;
269268
}
270269
}
271270
return false;
272271
}
273272

274-
private static boolean lookingAt(List<Token> tokens, int at, TokenType token) {
273+
private static boolean lookingAt(List<Token> tokens, int at, Type token) {
275274
if (at < 0) {
276275
// If configured correctly this will never happen
277276
// Keep for completeness

0 commit comments

Comments
 (0)