Skip to content

Commit

Permalink
Release 0.19.0
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy committed May 11, 2022
1 parent bde0345 commit 53ec830
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 22 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [0.19.0] - 2022-05-11

## [0.18.1] - 2022-05-10
### Fixed
- Remove logging
Expand Down Expand Up @@ -150,7 +152,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
([#1732](https://github.com/cucumber/common/pull/1732)
[aslakhellesoy](https://github.com/aslakhellesoy))

[Unreleased]: https://github.com/cucumber/language-service/compare/v0.18.1...HEAD
[Unreleased]: https://github.com/cucumber/language-service/compare/v0.19.0...HEAD
[0.19.0]: https://github.com/cucumber/language-service/compare/v0.18.1...v0.19.0
[0.18.1]: https://github.com/cucumber/language-service/compare/v0.18.0...v0.18.1
[0.18.0]: https://github.com/cucumber/language-service/compare/v0.17.0...v0.18.0
[0.17.0]: https://github.com/cucumber/language-service/compare/v0.16.0...v0.17.0
Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cucumber/language-service",
"version": "0.18.1",
"version": "0.19.0",
"description": "Cucumber Language Service",
"type": "module",
"main": "dist/cjs/src/index.js",
Expand Down Expand Up @@ -61,7 +61,7 @@
"@cucumber/message-streams": "^4.0.1",
"@types/glob": "7.2.0",
"@types/mocha": "9.1.1",
"@types/node": "17.0.31",
"@types/node": "17.0.32",
"@typescript-eslint/eslint-plugin": "5.23.0",
"@typescript-eslint/parser": "5.23.0",
"eslint": "8.15.0",
Expand Down
32 changes: 28 additions & 4 deletions src/tree-sitter/ExpressionBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { javaLanguage } from './javaLanguage.js'
import { phpLanguage } from './phpLanguage.js'
import { rubyLanguage } from './rubyLanguage.js'
import {
ExpressionBuilderResult,
LanguageName,
ParameterTypeMeta,
ParserAdapter,
Expand All @@ -36,11 +37,21 @@ export class ExpressionBuilder {
build(
sources: readonly Source[],
parameterTypes: readonly ParameterTypeMeta[]
): readonly Expression[] {
): ExpressionBuilderResult {
const expressions: Expression[] = []
const errors: Error[] = []
const parameterTypeRegistry = new ParameterTypeRegistry()
const expressionFactory = new ExpressionFactory(parameterTypeRegistry)

const treeByContent = new Map<Source, Parser.Tree>()
const parse = (source: Source): Parser.Tree => {
let tree: Parser.Tree | undefined = treeByContent.get(source)
if (!tree) {
treeByContent.set(source, (tree = this.parserAdapter.parser.parse(source.content)))
}
return tree
}

for (const parameterType of parameterTypes) {
parameterTypeRegistry.defineParameterType(
makeParameterType(parameterType.name, new RegExp(parameterType.regexp))
Expand All @@ -49,7 +60,14 @@ export class ExpressionBuilder {

for (const source of sources) {
this.parserAdapter.setLanguage(source.language)
const tree = this.parserAdapter.parser.parse(source.content)
let tree: Parser.Tree
try {
tree = parse(source)
} catch (err) {
err.message += `\npath: ${source.path}`
errors.push(err)
continue
}

const treeSitterLanguage = treeSitterLanguageByName[source.language]
for (const defineParameterTypeQuery of treeSitterLanguage.defineParameterTypeQueries) {
Expand All @@ -70,7 +88,10 @@ export class ExpressionBuilder {

for (const source of sources) {
this.parserAdapter.setLanguage(source.language)
const tree = this.parserAdapter.parser.parse(source.content)
const tree = treeByContent.get(source)
if (!tree) {
continue
}

const treeSitterLanguage = treeSitterLanguageByName[source.language]
for (const defineStepDefinitionQuery of treeSitterLanguage.defineStepDefinitionQueries) {
Expand All @@ -89,7 +110,10 @@ export class ExpressionBuilder {
}
}

return expressions
return {
expressions,
errors,
}
}
}

Expand Down
11 changes: 9 additions & 2 deletions src/tree-sitter/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Expression } from '@cucumber/cucumber-expressions'
import Parser from 'tree-sitter'

export type ParameterTypeMeta = { name: string; regexp: string }
Expand All @@ -6,8 +7,9 @@ export const LanguageNames = ['java', 'typescript', 'c_sharp', 'php', 'ruby'] as
export type LanguageName = typeof LanguageNames[number]

export type Source = {
language: LanguageName
content: string
readonly language: LanguageName
readonly path: string
readonly content: string
}

export type TreeSitterLanguage = {
Expand All @@ -16,6 +18,11 @@ export type TreeSitterLanguage = {
toStringOrRegExp(expression: string): string | RegExp
}

export type ExpressionBuilderResult = {
readonly expressions: readonly Expression[]
readonly errors: readonly Error[]
}

/**
* The Node.js and Web bindings have slightly different APIs. We hide this difference behind this interface.
* https://github.com/tree-sitter/node-tree-sitter/issues/68
Expand Down
9 changes: 5 additions & 4 deletions test/tree-sitter/ExpressionBuilder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import glob from 'glob'
import path from 'path'

import { ExpressionBuilder, LanguageName } from '../../src/index.js'
import { ParserAdapter } from '../../src/tree-sitter/types.js'
import { ParserAdapter, Source } from '../../src/tree-sitter/types.js'
import { NodeParserAdapter } from '../../src/tree-sitter-node/NodeParserAdapter.js'
import { WasmParserAdapter } from '../../src/tree-sitter-wasm/WasmParserAdapter.js'

Expand All @@ -26,13 +26,14 @@ function defineContract(makeParserAdapter: () => ParserAdapter) {
// }
it(`builds parameter types and expressions from ${language} source`, async () => {
const contents = await Promise.all(glob.sync(`${dir}/**/*`).map((f) => readFile(f, 'utf-8')))
const sources = contents.map((content) => ({
const sources: Source[] = contents.map((content, i) => ({
language,
content,
path: `dummy-${i}`,
}))
const expressions = expressionBuilder.build(sources, [])
const result = expressionBuilder.build(sources, [])
assert.deepStrictEqual(
expressions.map((e) =>
result.expressions.map((e) =>
e instanceof CucumberExpression ? e.source : (e as RegularExpression).regexp
),
parameterTypeSupport.has(language) ? ['a {uuid}', 'a {date}', /^a regexp$/] : [/^a regexp$/]
Expand Down

0 comments on commit 53ec830

Please sign in to comment.