Skip to content

Commit

Permalink
Expose the AST in the JavaScript implementation (#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy authored Apr 21, 2022
1 parent 3802248 commit 0c9b826
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added

- [JavaScript] Add `CucumberExpression.ast` and expose the AST types.

## [15.0.2] - 2022-03-15
### Fixed
- Add missing `name` field in CommonJS package file ([#87](https://github.com/cucumber/cucumber-expressions/pull/87))
Expand Down
4 changes: 2 additions & 2 deletions javascript/src/Ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export interface Located {
readonly end: number
}

export class Node {
export class Node implements Located {
constructor(
public readonly type: NodeType,
public readonly nodes: readonly Node[] | undefined,
Expand Down Expand Up @@ -70,7 +70,7 @@ export enum NodeType {
expression = 'EXPRESSION_NODE',
}

export class Token {
export class Token implements Located {
readonly type: TokenType
readonly text: string
readonly start: number
Expand Down
9 changes: 5 additions & 4 deletions javascript/src/CucumberExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const ESCAPE_PATTERN = () => /([\\^[({$.|?*+})\]])/g
export default class CucumberExpression implements Expression {
private readonly parameterTypes: Array<ParameterType<unknown>> = []
private readonly treeRegexp: TreeRegexp
private readonly ast: Node

/**
* @param expression
Expand All @@ -30,8 +31,8 @@ export default class CucumberExpression implements Expression {
private readonly parameterTypeRegistry: ParameterTypeRegistry
) {
const parser = new CucumberExpressionParser()
const ast = parser.parse(expression)
const pattern = this.rewriteToRegex(ast)
this.ast = parser.parse(expression)
const pattern = this.rewriteToRegex(this.ast)
this.treeRegexp = new TreeRegexp(pattern)
}

Expand Down Expand Up @@ -73,14 +74,14 @@ export default class CucumberExpression implements Expression {

private rewriteAlternation(node: Node) {
// Make sure the alternative parts aren't empty and don't contain parameter types
;(node.nodes || []).forEach((alternative) => {
for (const alternative of node.nodes || []) {
if (!alternative.nodes || alternative.nodes.length == 0) {
throw createAlternativeMayNotBeEmpty(alternative, this.expression)
}
this.assertNotEmpty(alternative, (astNode) =>
createAlternativeMayNotExclusivelyContainOptionals(astNode, this.expression)
)
})
}
const regex = (node.nodes || []).map((node) => this.rewriteToRegex(node)).join('|')
return `(?:${regex})`
}
Expand Down
6 changes: 6 additions & 0 deletions javascript/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Argument from './Argument.js'
import { Located, Node, NodeType, Token, TokenType } from './Ast.js'
import CucumberExpression from './CucumberExpression.js'
import CucumberExpressionGenerator from './CucumberExpressionGenerator.js'
import ExpressionFactory from './ExpressionFactory.js'
Expand All @@ -17,7 +18,12 @@ export {
ExpressionFactory,
GeneratedExpression,
Group,
Located,
Node,
NodeType,
ParameterType,
ParameterTypeRegistry,
RegularExpression,
Token,
TokenType,
}

0 comments on commit 0c9b826

Please sign in to comment.