diff --git a/CHANGELOG.md b/CHANGELOG.md index 648117df..59db253e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added +- Add support for `.tsx` ([#87](https://github.com/cucumber/language-service/issues/87) [#90](https://github.com/cucumber/language-service/pull/90)) + ## [0.32.0] - 2022-08-27 ### Fixed - Recognize parameter types using array for `regexp` ([#67](https://github.com/cucumber/language-service/issues/67), [#86](https://github.com/cucumber/language-service/pull/86)) diff --git a/README.md b/README.md index 3494aef8..318613e3 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ and [Cucumber Monaco](https://github.com/cucumber/monaco#readme). - Languages - [x] Java - [x] TypeScript + - [x] TypeScript JSX (TSX) - [x] C# - [x] PHP - [x] Ruby diff --git a/package-lock.json b/package-lock.json index 945a257d..6ac95bd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "js-search": "2.0.0", "mustache": "4.2.0", "vscode-languageserver-types": "3.17.2", - "web-tree-sitter": "0.20.7" + "web-tree-sitter": "^0.20.5" }, "devDependencies": { "@cucumber/cucumber": "^8.5.2", @@ -27,6 +27,7 @@ "@types/glob": "8.0.0", "@types/mocha": "9.1.1", "@types/node": "18.7.14", + "@types/react": "18.0.18", "@typescript-eslint/eslint-plugin": "5.36.2", "@typescript-eslint/parser": "5.36.2", "eslint": "8.23.0", @@ -41,6 +42,7 @@ "npm-check-updates": "16.1.0", "prettier": "2.7.1", "pretty-quick": "3.1.3", + "react": "18.2.0", "ts-node": "10.9.1", "txtgen": "3.0.2", "typescript": "4.8.2" @@ -680,6 +682,23 @@ "integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA==", "dev": true }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.0.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz", + "integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, "node_modules/@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -689,6 +708,12 @@ "@types/node": "*" } }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -1822,6 +1847,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/csstype": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", + "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==", + "dev": true + }, "node_modules/d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -3933,6 +3964,12 @@ "resolved": "https://registry.npmjs.org/js-search/-/js-search-2.0.0.tgz", "integrity": "sha512-lJ8KzjlwcelIWuAdKyzsXv45W6OIwRpayzc7XmU8mzgWadg5UVOKVmnq/tXudddEB9Ceic3tVaGu6QOK/eebhg==" }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -4116,6 +4153,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -5721,6 +5770,18 @@ "node": ">=0.10.0" } }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/read-package-json": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.2.tgz", @@ -8047,6 +8108,23 @@ "integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA==", "dev": true }, + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "dev": true + }, + "@types/react": { + "version": "18.0.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz", + "integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -8056,6 +8134,12 @@ "@types/node": "*" } }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -8862,6 +8946,12 @@ } } }, + "csstype": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", + "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==", + "dev": true + }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -10409,6 +10499,12 @@ "resolved": "https://registry.npmjs.org/js-search/-/js-search-2.0.0.tgz", "integrity": "sha512-lJ8KzjlwcelIWuAdKyzsXv45W6OIwRpayzc7XmU8mzgWadg5UVOKVmnq/tXudddEB9Ceic3tVaGu6QOK/eebhg==" }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -10556,6 +10652,15 @@ "is-unicode-supported": "^0.1.0" } }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -11791,6 +11896,15 @@ "require-from-string": "^2.0.2" } }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0" + } + }, "read-package-json": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.2.tgz", diff --git a/package.json b/package.json index 7ba6f786..3c602ed7 100644 --- a/package.json +++ b/package.json @@ -67,17 +67,17 @@ "js-search": "2.0.0", "mustache": "4.2.0", "vscode-languageserver-types": "3.17.2", - "web-tree-sitter": "0.20.7" + "web-tree-sitter": "^0.20.5" }, "optionalDependencies": { "tree-sitter": "0.20.0", - "tree-sitter-cli": "0.20.7", "tree-sitter-c-sharp": "0.19.1", + "tree-sitter-cli": "0.20.7", "tree-sitter-java": "0.19.1", "tree-sitter-php": "0.19.0", + "tree-sitter-python": "0.20.1", "tree-sitter-ruby": "0.19.0", - "tree-sitter-typescript": "0.20.1", - "tree-sitter-python": "0.20.1" + "tree-sitter-typescript": "0.20.1" }, "devDependencies": { "@cucumber/cucumber": "^8.5.2", @@ -85,6 +85,7 @@ "@types/glob": "8.0.0", "@types/mocha": "9.1.1", "@types/node": "18.7.14", + "@types/react": "18.0.18", "@typescript-eslint/eslint-plugin": "5.36.2", "@typescript-eslint/parser": "5.36.2", "eslint": "8.23.0", @@ -99,6 +100,7 @@ "npm-check-updates": "16.1.0", "prettier": "2.7.1", "pretty-quick": "3.1.3", + "react": "18.2.0", "ts-node": "10.9.1", "txtgen": "3.0.2", "typescript": "4.8.2" diff --git a/scripts/build.js b/scripts/build.js index 2acb8f20..321d7770 100755 --- a/scripts/build.js +++ b/scripts/build.js @@ -12,8 +12,8 @@ const languages = [ }, { npm: 'tree-sitter-typescript', - dir: 'typescript', - wasm: 'typescript', + dir: 'tsx', + wasm: 'tsx', }, { npm: 'tree-sitter-c-sharp', diff --git a/src/language/SourceAnalyzer.ts b/src/language/SourceAnalyzer.ts index db6e8f69..f6848e2f 100644 --- a/src/language/SourceAnalyzer.ts +++ b/src/language/SourceAnalyzer.ts @@ -31,7 +31,10 @@ export class SourceAnalyzer { try { tree = this.parse(source) } catch (err) { - err.message += `\nuri: ${source.uri}` + err.message += ` +uri: ${source.uri} +language: ${source.languageName} +` this.errors.push(err) continue } diff --git a/src/language/languages.ts b/src/language/languages.ts index 74ea1a46..8b0df25b 100644 --- a/src/language/languages.ts +++ b/src/language/languages.ts @@ -3,12 +3,12 @@ import { javaLanguage } from './javaLanguage.js' import { phpLanguage } from './phpLanguage.js' import { pythonLanguage } from './pythonLanguage.js' import { rubyLanguage } from './rubyLanguage.js' +import { tsxLanguage } from './tsxLanguage.js' import { Language, LanguageName } from './types.js' -import { typescriptLanguage } from './typescriptLanguage.js' const languageByName: Record = { java: javaLanguage, - typescript: typescriptLanguage, + tsx: tsxLanguage, c_sharp: csharpLanguage, php: phpLanguage, ruby: rubyLanguage, diff --git a/src/language/typescriptLanguage.ts b/src/language/tsxLanguage.ts similarity index 98% rename from src/language/typescriptLanguage.ts rename to src/language/tsxLanguage.ts index a883d9ee..4581297b 100644 --- a/src/language/typescriptLanguage.ts +++ b/src/language/tsxLanguage.ts @@ -4,7 +4,7 @@ import { RegExps } from '@cucumber/cucumber-expressions/dist/cjs/src/ParameterTy import { childrenToString, filter, NO_QUOTES, NO_SLASHES } from './helpers.js' import { Language, TreeSitterSyntaxNode } from './types.js' -export const typescriptLanguage: Language = { +export const tsxLanguage: Language = { toParameterTypeName(node) { return childrenToString(node, NO_QUOTES) }, diff --git a/src/language/types.ts b/src/language/types.ts index dc06446a..35b7b92f 100644 --- a/src/language/types.ts +++ b/src/language/types.ts @@ -35,7 +35,7 @@ export type SnippetParameters = Readonly -export const LanguageNames = ['java', 'typescript', 'c_sharp', 'php', 'python', 'ruby'] as const +export const LanguageNames = ['java', 'tsx', 'c_sharp', 'php', 'python', 'ruby'] as const export type LanguageName = typeof LanguageNames[number] export type Source = Readonly<{ diff --git a/src/tree-sitter-node/NodeParserAdapter.ts b/src/tree-sitter-node/NodeParserAdapter.ts index dcd2896e..57198deb 100644 --- a/src/tree-sitter-node/NodeParserAdapter.ts +++ b/src/tree-sitter-node/NodeParserAdapter.ts @@ -27,7 +27,7 @@ export class NodeParserAdapter implements ParserAdapter { case 'java': this.parser.setLanguage(Java) break - case 'typescript': + case 'tsx': this.parser.setLanguage(TypeScript.typescript) break case 'c_sharp': diff --git a/test/language/ExpressionBuilder.test.ts b/test/language/ExpressionBuilder.test.ts index 43bd61f5..263e3af1 100644 --- a/test/language/ExpressionBuilder.test.ts +++ b/test/language/ExpressionBuilder.test.ts @@ -10,12 +10,7 @@ import { NodeParserAdapter } from '../../src/tree-sitter-node/NodeParserAdapter. import { WasmParserAdapter } from '../../src/tree-sitter-wasm/WasmParserAdapter.js' // List languages that support Cucumber Expressions here -const cucumberExpressionsSupport: Set = new Set([ - 'c_sharp', - 'java', - 'ruby', - 'typescript', -]) +const cucumberExpressionsSupport: Set = new Set(['c_sharp', 'java', 'ruby', 'tsx']) function defineContract(makeParserAdapter: () => ParserAdapter) { let expressionBuilder: ExpressionBuilder diff --git a/test/language/testdata/typescript/ParameterTypes.ts b/test/language/testdata/tsx/ParameterTypes.ts similarity index 100% rename from test/language/testdata/typescript/ParameterTypes.ts rename to test/language/testdata/tsx/ParameterTypes.ts diff --git a/test/language/testdata/typescript/StepDefinitions.ts b/test/language/testdata/tsx/StepDefinitions.tsx similarity index 88% rename from test/language/testdata/typescript/StepDefinitions.ts rename to test/language/testdata/tsx/StepDefinitions.tsx index 67e61dab..7ec63f18 100644 --- a/test/language/testdata/typescript/StepDefinitions.ts +++ b/test/language/testdata/tsx/StepDefinitions.tsx @@ -1,5 +1,8 @@ import { Given } from '@cucumber/cucumber' import assert from 'assert' +import React from 'react' + +const dummyTsx = Hello Given('a {uuid}', async function (uuid: string) { assert(uuid) diff --git a/test/service/getGenerateSnippetCodeAction.test.ts b/test/service/getGenerateSnippetCodeAction.test.ts index bd3ed362..98c14af7 100644 --- a/test/service/getGenerateSnippetCodeAction.test.ts +++ b/test/service/getGenerateSnippetCodeAction.test.ts @@ -21,7 +21,7 @@ describe('getGenerateSnippetCodeAction', () => { 'step_definitions/steps.ts', true, undefined, - 'typescript', + 'tsx', new ParameterTypeRegistry() ) const expectedAction: CodeAction = { @@ -111,7 +111,7 @@ Given('I have {int} cukes', (int: number) => { 'step_definitions/steps.ts', false, undefined, - 'typescript', + 'tsx', new ParameterTypeRegistry() ) const expectedAction: CodeAction = { diff --git a/tsconfig.json b/tsconfig.json index 005c7efa..7bd90883 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,6 +16,7 @@ "target": "ES6", "moduleResolution": "node", "allowSyntheticDefaultImports": true, - "noEmit": true + "noEmit": true, + "jsx": "react" } }