diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cf03445..659120a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Fixed - (Rust) Support for r# raw strings with step definition patterns ([#176](https://github.com/cucumber/language-service/pull/176)) - -### Fixed +- (Rust) Line continuation characters in rust step definition patterns ([#179](https://github.com/cucumber/language-service/pull/179)) - (Python) Unexpected spaces and commas in generated step definitions [#160](https://github.com/cucumber/language-service/issues/160) ## [1.4.1] - 2023-07-16 diff --git a/src/language/rustLanguage.ts b/src/language/rustLanguage.ts index 5d15f40c..5050fb15 100644 --- a/src/language/rustLanguage.ts +++ b/src/language/rustLanguage.ts @@ -111,9 +111,17 @@ fn {{ #lowercase }}{{ #underscore }}{{ expression }}{{ /underscore }}{{ /lowerca export function stringLiteral(node: TreeSitterSyntaxNode | null): string { if (node === null) throw new Error('node cannot be null') - if (node.text.startsWith('r#')) return unescapeString(node.text.slice(3, -2)) - if (node.text.startsWith('r')) return unescapeString(node.text.slice(2, -1)) - return unescapeString(node.text.slice(1, -1)) + + let result + if (node.text.startsWith('r#')) result = unescapeString(node.text.slice(3, -2)) + else if (node.text.startsWith('r')) result = unescapeString(node.text.slice(2, -1)) + else result = unescapeString(node.text.slice(1, -1)) + + return stripLineContinuation(result) +} + +export function stripLineContinuation(s: string): string { + return s.replace(/\\\n\s*/g, '') } function unescapeString(s: string): string { diff --git a/test/language/rustLanguage.test.ts b/test/language/rustLanguage.test.ts index 31155f39..f4f4fc2c 100644 --- a/test/language/rustLanguage.test.ts +++ b/test/language/rustLanguage.test.ts @@ -1,6 +1,6 @@ import assert from 'assert' -import { stringLiteral } from '../../src/language/rustLanguage.js' +import { stringLiteral, stripLineContinuation } from '../../src/language/rustLanguage.js' import { TreeSitterSyntaxNode } from '../../src/language/types.js' describe('rustLanguage', () => { @@ -41,4 +41,71 @@ describe('rustLanguage', () => { assert.strictEqual(stringLiteral(node), expected) }) }) + + it('should strip line continuations from expressions', () => { + const cases = [ + { + // Single line continuation + input: '"Line \\\n continuation"', + expected: '"Line continuation"', + }, + { + input: '"Multiple \\\n line \\\n continuations"', + expected: '"Multiple line continuations"', + }, + { + // Continuation with consecutive new lines + input: '"Continuation with \\\n\n consecutive new lines"', + expected: '"Continuation with consecutive new lines"', + }, + { + // No space before continuation + input: '"No space\\\n before continuation"', + expected: '"No spacebefore continuation"', + }, + { + // Multiple spaces before continuation + input: '"Two spaces \\\n before continuation"', + expected: '"Two spaces before continuation"', + }, + { + // Line continuation with extra space + input: '"this \\ line \\\nshould too"', + expected: '"this \\ line should too"', + }, + { + // Ends with line continuation + input: '"Ends with continuation\\\n"', + expected: '"Ends with continuation"', + }, + { + // Ends with line continuation and whitespace + input: '"Ends with continuation and whitespace\\\n "', + expected: '"Ends with continuation and whitespace"', + }, + ] + + cases.forEach(({ input, expected }) => { + assert.strictEqual(stripLineContinuation(input), expected) + }) + }) + + it('should not strip invalid line continuations from expressions', () => { + const cases = [ + { + // Space after continuation but before new line + input: '"Space after continuation \\ \n but before new line"', + expected: '"Space after continuation \\ \n but before new line"', + }, + { + // Ends with escape character + input: '"Escaped backslash \\"', + expected: '"Escaped backslash \\"', + }, + ] + + cases.forEach(({ input, expected }) => { + assert.strictEqual(stripLineContinuation(input), expected) + }) + }) })