diff --git a/bindings/node/gts.js b/bindings/node/gts.js new file mode 100644 index 00000000..8eb37e65 --- /dev/null +++ b/bindings/node/gts.js @@ -0,0 +1 @@ +module.exports = require('.').gts; diff --git a/bindings/node/index.js b/bindings/node/index.js index 45f72986..8f2b2d92 100644 --- a/bindings/node/index.js +++ b/bindings/node/index.js @@ -5,4 +5,5 @@ module.exports = require("node-gyp-build")(root); try { module.exports.typescript.nodeTypeInfo = require("../../typescript/src/node-types.json"); module.exports.tsx.nodeTypeInfo = require("../../tsx/src/node-types.json"); + module.exports.gts.nodeTypeInfo = require("../../gts/src/node-types.json"); } catch (_) { } diff --git a/common/define-grammar.js b/common/define-grammar.js index 3bd3297a..088a69df 100644 --- a/common/define-grammar.js +++ b/common/define-grammar.js @@ -114,10 +114,12 @@ module.exports = function defineGrammar(dialect) { ]).concat( dialect === 'typescript' ? [ [$.primary_type, $.type_parameter], - ] : [ + ] : dialect === 'tsx' ? [ [$.jsx_opening_element, $.type_parameter], [$.jsx_namespace_name, $.primary_type], - ], + ] : dialect === 'gts' ? [ + [$.glimmer_template, $.primary_type, $.type_parameter], + ] : [], ), inline: ($, previous) => previous @@ -215,15 +217,24 @@ module.exports = function defineGrammar(dialect) { $.satisfies_expression, $.instantiation_expression, $.internal_module, + $.glimmer_template, ]; if (dialect === 'typescript') { + choices.push($.type_assertion); + choices.push(...previous.members.filter((member) => { + return member.name !== '_jsx_element' && member.name !== 'glimmer_template'; + }, + )); + } else if (dialect === 'gts') { choices.push($.type_assertion); choices.push(...previous.members.filter((member) => member.name !== '_jsx_element', )); } else if (dialect === 'tsx') { - choices.push(...previous.members); + choices.push(...previous.members.filter(member => { + return member.name !== 'glimmer_template'; + })); } else { throw new Error(`Unknown dialect ${dialect}`); } @@ -231,6 +242,25 @@ module.exports = function defineGrammar(dialect) { return choice(...choices); }, + // This rule is only referenced by expression when the dialect is 'gts' + // glimmer_template: $ => choice( + // seq( + // field('open_tag', $.glimmer_opening_tag), + // field('content', repeat($._glimmer_template_content)), + // field('close_tag', $.glimmer_closing_tag), + // ), + // // empty template has no content + // // + // seq( + // field('open_tag', $.glimmer_opening_tag), + // field('close_tag', $.glimmer_closing_tag), + // ), + // ), + // + // _glimmer_template_content: _ => /.{1,}/, + // glimmer_opening_tag: _ => '', + _jsx_start_opening_element: $ => seq( '<', optional( @@ -419,6 +449,7 @@ module.exports = function defineGrammar(dialect) { class_body: $ => seq( '{', repeat(choice( + field('template', $.glimmer_template), seq( repeat(field('decorator', $.decorator)), $.method_definition, diff --git a/gts/Makefile b/gts/Makefile new file mode 100644 index 00000000..f411bfe2 --- /dev/null +++ b/gts/Makefile @@ -0,0 +1,3 @@ +LANGUAGE_NAME := tree-sitter-tsx + +include ../common/common.mak diff --git a/gts/grammar.js b/gts/grammar.js new file mode 100644 index 00000000..83a58a5f --- /dev/null +++ b/gts/grammar.js @@ -0,0 +1,3 @@ +const defineGrammar = require('../common/define-grammar'); + +module.exports = defineGrammar('gts'); diff --git a/gts/package.json b/gts/package.json new file mode 100644 index 00000000..e317e9ac --- /dev/null +++ b/gts/package.json @@ -0,0 +1,3 @@ +{ + "main": "../bindings/node/gts" +} diff --git a/package.json b/package.json index af312a24..e0529f42 100644 --- a/package.json +++ b/package.json @@ -45,16 +45,17 @@ "devDependencies": { "eslint": ">=8.57.0", "eslint-config-google": "^0.14.0", + "prebuildify": "^6.0.1", "tree-sitter-cli": "^0.22.6", - "tree-sitter-javascript": "^0.21.4", - "prebuildify": "^6.0.1" + "tree-sitter-javascript": "^0.21.4" }, "scripts": { "install": "node-gyp-build", "prebuildify": "prebuildify --napi --strip", - "build": "npm run build-typescript && npm run build-tsx", + "build": "npm run build-typescript && npm run build-tsx && npm run build-gts", "build-typescript": "cd typescript && npx tree-sitter generate --no-bindings", "build-tsx": "cd tsx && npx tree-sitter generate --no-bindings", + "build-gts": "cd gts && npx tree-sitter generate --no-bindings", "lint": "eslint common/define-grammar.js", "parse": "tree-sitter parse", "test": "tree-sitter test" diff --git a/test/corpus/expressions.txt b/test/corpus/expressions.txt index facc6de8..64c16b46 100644 --- a/test/corpus/expressions.txt +++ b/test/corpus/expressions.txt @@ -424,3 +424,28 @@ a ? function(){ return true } : b; (return_statement (true)))) (identifier)))) + +========================================================== +Class Component with content +:language(gts) +========================================================== + +export class Menu extends Component<{ + Args: { + /* args here */ + } +}> { + +} + +---- + +(program + (expression_statement + (glimmer_template + (glimmer_opening_tag) + (glimmer_closing_tag) + )))