Skip to content

Commit

Permalink
Merge branch 'main' into strip-java-case-insensitive-flags
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy authored Oct 10, 2022
2 parents 5d0bf4e + ef820df commit a5df7a2
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 5 deletions.
3 changes: 1 addition & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Add support for [document symbols](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentSymbol) ([#98](https://github.com/cucumber/language-service/issues/98), [#106](https://github.com/cucumber/language-service/pull/106))
- (Java) Recognise regexps with `(?i)`, with the caveat that the resulting JavaScript `RegExp` is *not* case insensitive ([#100](https://github.com/cucumber/language-service/issues/100), [#108](https://github.com/cucumber/language-service/pull/108))
- (TypeScript) Add support for template literals without subsitutions. ([#101](https://github.com/cucumber/language-service/issues/101), [#107](https://github.com/cucumber/language-service/pull/107))

## [1.0.1] - 2022-10-10

Expand Down Expand Up @@ -326,5 +327,3 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
[0.2.0]: https://github.com/cucumber/language-service/compare/v0.1.1...v0.2.0
[0.1.1]: https://github.com/cucumber/language-service/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/cucumber/language-service/tree/v0.1.0
0...v0.1.1
[0.1.0]: https://github.com/cucumber/language-service/tree/v0.1.0
6 changes: 5 additions & 1 deletion src/language/SourceAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export type SourceMatch = {
match: TreeSitterQueryMatch
}

export const NO_EXPRESSION = ''

export class SourceAnalyzer {
private readonly errors: Error[] = []
private readonly treeByContent = new Map<Source<LanguageName>, TreeSitterTree>()
Expand Down Expand Up @@ -86,7 +88,9 @@ export class SourceAnalyzer {
if (expressionNode && rootNode) {
const language = getLanguage(source.languageName)
const stepDefinitionExpression = language.toStepDefinitionExpression(expressionNode)
callback(stepDefinitionExpression, rootNode, expressionNode, source)
if (stepDefinitionExpression !== NO_EXPRESSION) {
callback(stepDefinitionExpression, rootNode, expressionNode, source)
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/language/tsxLanguage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { StringOrRegExp } from '@cucumber/cucumber-expressions'
import { RegExps } from '@cucumber/cucumber-expressions/dist/cjs/src/ParameterType'

import { childrenToString, filter, NO_QUOTES } from './helpers.js'
import { NO_EXPRESSION } from './SourceAnalyzer.js'
import { Language, TreeSitterSyntaxNode } from './types.js'

export const tsxLanguage: Language = {
Expand Down Expand Up @@ -76,6 +77,7 @@ export const tsxLanguage: Language = {
[
(string) @expression
(regex) @expression
(template_string) @expression
]
)
(#match? @function-name "Given|When|Then")
Expand Down Expand Up @@ -135,6 +137,12 @@ export function toStringOrRegExp(node: TreeSitterSyntaxNode): StringOrRegExp {
}
case 'string':
return unescapeString(childrenToString(node, NO_QUOTES))
case 'template_string':
if (node.children.length > 0) {
// template literal with substitutions. Can't handle those.
return NO_EXPRESSION
}
return node.text.slice(1, node.text.length - 1)
default:
throw new Error(`Unexpected type: ${node.type}`)
}
Expand Down
45 changes: 43 additions & 2 deletions test/language/tsxLanguage.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import assert from 'assert'

import { NO_EXPRESSION } from '../../src/language/SourceAnalyzer.js'
import { toStringOrRegExp } from '../../src/language/tsxLanguage.js'
import { TreeSitterSyntaxNode } from '../../src/language/types.js'

describe('tsxLanguage', () => {
it('should preserve regexp flags in step definitions', () => {
const regex: TreeSitterSyntaxNode = {
const node: TreeSitterSyntaxNode = {
type: 'regex',
text: '/^a regexp$/imu',
startPosition: { row: 0, column: 6 },
Expand All @@ -27,7 +28,47 @@ describe('tsxLanguage', () => {
},
],
}
const result = toStringOrRegExp(regex)
const result = toStringOrRegExp(node)
assert.deepStrictEqual(result, /^a regexp$/imu)
})

it('should generate cucumber expression strings from template literals without substitution', () => {
const node: TreeSitterSyntaxNode = {
type: 'template_string',
text: '`hello there`',
startPosition: { row: 0, column: 5 },
endPosition: { row: 0, column: 18 },
children: [],
}
const result = toStringOrRegExp(node)
assert.deepStrictEqual(result, 'hello there')
})

it('should generate a regexp that matches nothing from template literals with substitution', () => {
const node: TreeSitterSyntaxNode = {
type: 'template_string',
text: '`hello there`',
startPosition: { row: 0, column: 5 },
endPosition: { row: 0, column: 21 },
children: [
{
type: 'template_subsitution',
text: '${there}',
startPosition: { row: 0, column: 12 },
endPosition: { row: 0, column: 20 },
children: [
{
type: 'identifier',
text: 'there',
startPosition: { row: 0, column: 14 },
endPosition: { row: 0, column: 19 },
children: [],
},
],
},
],
}
const result = toStringOrRegExp(node)
assert.deepStrictEqual(result, NO_EXPRESSION)
})
})

0 comments on commit a5df7a2

Please sign in to comment.