round-core 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/index.d.ts +18 -3
  2. package/extension/.vscodeignore +5 -0
  3. package/extension/LICENSE +21 -0
  4. package/extension/cgmanifest.json +45 -0
  5. package/extension/extension.js +163 -0
  6. package/extension/images/round-config-dark.svg +10 -0
  7. package/extension/images/round-config-light.svg +10 -0
  8. package/extension/images/round-dark.svg +10 -0
  9. package/extension/images/round-light.svg +10 -0
  10. package/extension/javascript-language-configuration.json +241 -0
  11. package/extension/package-lock.json +97 -0
  12. package/extension/package.json +119 -0
  13. package/extension/package.nls.json +4 -0
  14. package/extension/round-0.1.0.vsix +0 -0
  15. package/extension/round-lsp/package-lock.json +185 -0
  16. package/extension/round-lsp/package.json +21 -0
  17. package/extension/round-lsp/src/round-transformer-lsp.js +248 -0
  18. package/extension/round-lsp/src/server.js +396 -0
  19. package/extension/snippets/javascript.code-snippets +266 -0
  20. package/extension/snippets/round.code-snippets +109 -0
  21. package/extension/syntaxes/JavaScript.tmLanguage.json +6001 -0
  22. package/extension/syntaxes/JavaScriptReact.tmLanguage.json +6066 -0
  23. package/extension/syntaxes/Readme.md +12 -0
  24. package/extension/syntaxes/Regular Expressions (JavaScript).tmLanguage +237 -0
  25. package/extension/syntaxes/Round.tmLanguage.json +290 -0
  26. package/extension/syntaxes/RoundInject.tmLanguage.json +20 -0
  27. package/extension/tags-language-configuration.json +152 -0
  28. package/extension/temp_astro/package-lock.json +912 -0
  29. package/extension/temp_astro/package.json +16 -0
  30. package/extension/types/round-core.d.ts +326 -0
  31. package/package.json +1 -1
  32. package/src/index.d.ts +18 -3
@@ -0,0 +1,119 @@
1
+ {
2
+ "name": "round",
3
+ "displayName": "Round",
4
+ "description": "Language support for .round (Round framework)",
5
+ "version": "0.1.0",
6
+ "main": "./extension.js",
7
+ "publisher": "round-framework",
8
+ "license": "MIT",
9
+ "engines": {
10
+ "vscode": "^1.90.0"
11
+ },
12
+ "activationEvents": [
13
+ "onLanguage:round",
14
+ "workspaceContains:**/*.round"
15
+ ],
16
+ "categories": [
17
+ "Programming Languages"
18
+ ],
19
+ "contributes": {
20
+ "configurationDefaults": {
21
+ "[round]": {
22
+ "editor.maxTokenizationLineLength": 2500
23
+ }
24
+ },
25
+ "languages": [
26
+ {
27
+ "id": "round",
28
+ "aliases": [
29
+ "Round"
30
+ ],
31
+ "icon": {
32
+ "light": "./images/round-light.svg",
33
+ "dark": "./images/round-dark.svg"
34
+ },
35
+ "extensions": [
36
+ ".round"
37
+ ],
38
+ "configuration": "./javascript-language-configuration.json"
39
+ },
40
+ {
41
+ "id": "jsx-tags",
42
+ "aliases": [],
43
+ "configuration": "./tags-language-configuration.json"
44
+ }
45
+ ],
46
+ "grammars": [
47
+ {
48
+ "language": "round",
49
+ "scopeName": "source.round",
50
+ "path": "./syntaxes/Round.tmLanguage.json",
51
+ "embeddedLanguages": {
52
+ "meta.tag.js": "jsx-tags",
53
+ "meta.tag.without-attributes.js": "jsx-tags",
54
+ "meta.tag.attributes.js.jsx": "round",
55
+ "meta.embedded.expression.js": "round"
56
+ },
57
+ "tokenTypes": {
58
+ "punctuation.definition.template-expression": "other",
59
+ "entity.name.type.instance.jsdoc": "other",
60
+ "entity.name.function.tagged-template": "other",
61
+ "meta.import string.quoted": "other",
62
+ "variable.other.jsdoc": "other"
63
+ }
64
+ },
65
+ {
66
+ "scopeName": "source.js.jsx",
67
+ "path": "./syntaxes/JavaScriptReact.tmLanguage.json"
68
+ },
69
+ {
70
+ "scopeName": "source.js.regexp",
71
+ "path": "./syntaxes/Regular Expressions (JavaScript).tmLanguage"
72
+ }
73
+ ],
74
+ "semanticTokenScopes": [
75
+ {
76
+ "language": "round",
77
+ "scopes": {
78
+ "property": [
79
+ "variable.other.property.jsx"
80
+ ],
81
+ "property.readonly": [
82
+ "variable.other.constant.property.jsx"
83
+ ],
84
+ "variable": [
85
+ "variable.other.readwrite.jsx"
86
+ ],
87
+ "variable.readonly": [
88
+ "variable.other.constant.object.jsx"
89
+ ],
90
+ "function": [
91
+ "entity.name.function.jsx"
92
+ ],
93
+ "namespace": [
94
+ "entity.name.type.module.jsx"
95
+ ],
96
+ "variable.defaultLibrary": [
97
+ "support.variable.js"
98
+ ],
99
+ "function.defaultLibrary": [
100
+ "support.function.js"
101
+ ]
102
+ }
103
+ }
104
+ ],
105
+ "snippets": [
106
+ {
107
+ "language": "round",
108
+ "path": "./snippets/javascript.code-snippets"
109
+ }
110
+ ]
111
+ },
112
+ "repository": {
113
+ "type": "git",
114
+ "url": "https://github.com/ZtaMDev/RoundJS.git"
115
+ },
116
+ "dependencies": {
117
+ "vscode-languageclient": "^9.0.1"
118
+ }
119
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "displayName": "Round Framework",
3
+ "description": "Provides snippets, syntax highlighting, bracket matching and folding in Round files."
4
+ }
Binary file
@@ -0,0 +1,185 @@
1
+ {
2
+ "name": "round-lsp",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "round-lsp",
9
+ "version": "1.0.0",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "glob": "^13.0.0",
13
+ "magic-string": "^0.30.21",
14
+ "typescript": "^5.9.3",
15
+ "vscode-languageserver": "^9.0.1",
16
+ "vscode-languageserver-textdocument": "^1.0.12",
17
+ "vscode-uri": "^3.1.0"
18
+ }
19
+ },
20
+ "node_modules/@isaacs/balanced-match": {
21
+ "version": "4.0.1",
22
+ "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
23
+ "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
24
+ "license": "MIT",
25
+ "engines": {
26
+ "node": "20 || >=22"
27
+ }
28
+ },
29
+ "node_modules/@isaacs/brace-expansion": {
30
+ "version": "5.0.0",
31
+ "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
32
+ "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "@isaacs/balanced-match": "^4.0.1"
36
+ },
37
+ "engines": {
38
+ "node": "20 || >=22"
39
+ }
40
+ },
41
+ "node_modules/@jridgewell/sourcemap-codec": {
42
+ "version": "1.5.5",
43
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
44
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
45
+ "license": "MIT"
46
+ },
47
+ "node_modules/glob": {
48
+ "version": "13.0.0",
49
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz",
50
+ "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==",
51
+ "license": "BlueOak-1.0.0",
52
+ "dependencies": {
53
+ "minimatch": "^10.1.1",
54
+ "minipass": "^7.1.2",
55
+ "path-scurry": "^2.0.0"
56
+ },
57
+ "engines": {
58
+ "node": "20 || >=22"
59
+ },
60
+ "funding": {
61
+ "url": "https://github.com/sponsors/isaacs"
62
+ }
63
+ },
64
+ "node_modules/lru-cache": {
65
+ "version": "11.2.4",
66
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz",
67
+ "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==",
68
+ "license": "BlueOak-1.0.0",
69
+ "engines": {
70
+ "node": "20 || >=22"
71
+ }
72
+ },
73
+ "node_modules/magic-string": {
74
+ "version": "0.30.21",
75
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
76
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
77
+ "license": "MIT",
78
+ "dependencies": {
79
+ "@jridgewell/sourcemap-codec": "^1.5.5"
80
+ }
81
+ },
82
+ "node_modules/minimatch": {
83
+ "version": "10.1.1",
84
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
85
+ "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
86
+ "license": "BlueOak-1.0.0",
87
+ "dependencies": {
88
+ "@isaacs/brace-expansion": "^5.0.0"
89
+ },
90
+ "engines": {
91
+ "node": "20 || >=22"
92
+ },
93
+ "funding": {
94
+ "url": "https://github.com/sponsors/isaacs"
95
+ }
96
+ },
97
+ "node_modules/minipass": {
98
+ "version": "7.1.2",
99
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
100
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
101
+ "license": "ISC",
102
+ "engines": {
103
+ "node": ">=16 || 14 >=14.17"
104
+ }
105
+ },
106
+ "node_modules/path-scurry": {
107
+ "version": "2.0.1",
108
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz",
109
+ "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==",
110
+ "license": "BlueOak-1.0.0",
111
+ "dependencies": {
112
+ "lru-cache": "^11.0.0",
113
+ "minipass": "^7.1.2"
114
+ },
115
+ "engines": {
116
+ "node": "20 || >=22"
117
+ },
118
+ "funding": {
119
+ "url": "https://github.com/sponsors/isaacs"
120
+ }
121
+ },
122
+ "node_modules/typescript": {
123
+ "version": "5.9.3",
124
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
125
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
126
+ "license": "Apache-2.0",
127
+ "bin": {
128
+ "tsc": "bin/tsc",
129
+ "tsserver": "bin/tsserver"
130
+ },
131
+ "engines": {
132
+ "node": ">=14.17"
133
+ }
134
+ },
135
+ "node_modules/vscode-jsonrpc": {
136
+ "version": "8.2.0",
137
+ "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
138
+ "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
139
+ "license": "MIT",
140
+ "engines": {
141
+ "node": ">=14.0.0"
142
+ }
143
+ },
144
+ "node_modules/vscode-languageserver": {
145
+ "version": "9.0.1",
146
+ "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz",
147
+ "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==",
148
+ "license": "MIT",
149
+ "dependencies": {
150
+ "vscode-languageserver-protocol": "3.17.5"
151
+ },
152
+ "bin": {
153
+ "installServerIntoExtension": "bin/installServerIntoExtension"
154
+ }
155
+ },
156
+ "node_modules/vscode-languageserver-protocol": {
157
+ "version": "3.17.5",
158
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
159
+ "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
160
+ "license": "MIT",
161
+ "dependencies": {
162
+ "vscode-jsonrpc": "8.2.0",
163
+ "vscode-languageserver-types": "3.17.5"
164
+ }
165
+ },
166
+ "node_modules/vscode-languageserver-textdocument": {
167
+ "version": "1.0.12",
168
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
169
+ "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==",
170
+ "license": "MIT"
171
+ },
172
+ "node_modules/vscode-languageserver-types": {
173
+ "version": "3.17.5",
174
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
175
+ "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==",
176
+ "license": "MIT"
177
+ },
178
+ "node_modules/vscode-uri": {
179
+ "version": "3.1.0",
180
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
181
+ "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
182
+ "license": "MIT"
183
+ }
184
+ }
185
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "round-lsp",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "ZtaMDev",
11
+ "license": "ISC",
12
+ "type": "commonjs",
13
+ "dependencies": {
14
+ "glob": "^13.0.0",
15
+ "magic-string": "^0.30.21",
16
+ "typescript": "^5.9.3",
17
+ "vscode-languageserver": "^9.0.1",
18
+ "vscode-languageserver-textdocument": "^1.0.12",
19
+ "vscode-uri": "^3.1.0"
20
+ }
21
+ }
@@ -0,0 +1,248 @@
1
+ const MagicString = require('magic-string');
2
+
3
+ function transformLSP(code, filename = 'file.round') {
4
+ const s = new MagicString(code);
5
+
6
+ const edits = [];
7
+ const VIRTUAL_IMPORT = `// @ts-nocheck
8
+ import { Fragment, createElement } from 'round-core';
9
+ const React = { createElement, Fragment };
10
+
11
+ declare global {
12
+ namespace JSX {
13
+ interface IntrinsicElements {
14
+ [elemName: string]: any;
15
+ }
16
+ interface ElementAttributesProperty { props: {}; }
17
+ type Element = any;
18
+ }
19
+ }
20
+ `;
21
+ s.prepend(VIRTUAL_IMPORT);
22
+ edits.push({ offset: 0, length: 0, newLength: VIRTUAL_IMPORT.length });
23
+
24
+ function applyOverlapOverwrite(start, end, content) {
25
+ s.overwrite(start, end, content);
26
+ edits.push({ offset: start, length: end - start, newLength: content.length });
27
+ }
28
+
29
+ // Helper to find balanced block starting at index
30
+ // ... (rest of helper functions same as before)
31
+ function parseBlock(str, startIndex) {
32
+ let open = 0;
33
+ let startBlockIndex = -1;
34
+ let endBlockIndex = -1;
35
+
36
+ let inSingle = false;
37
+ let inDouble = false;
38
+ let inTemplate = false;
39
+ let inCommentLine = false;
40
+ let inCommentMulti = false;
41
+
42
+ for (let i = startIndex; i < str.length; i++) {
43
+ const ch = str[i];
44
+ const prev = i > 0 ? str[i - 1] : '';
45
+ const next = i < str.length - 1 ? str[i + 1] : '';
46
+
47
+ if (inCommentLine) {
48
+ if (ch === '\n' || ch === '\r') inCommentLine = false;
49
+ continue;
50
+ }
51
+ if (inCommentMulti) {
52
+ if (ch === '*' && next === '/') {
53
+ inCommentMulti = false;
54
+ i++;
55
+ }
56
+ continue;
57
+ }
58
+ if (inTemplate) {
59
+ if (ch === '`' && prev !== '\\') inTemplate = false;
60
+ continue;
61
+ }
62
+ if (inSingle) {
63
+ if (ch === '\'' && prev !== '\\') inSingle = false;
64
+ continue;
65
+ }
66
+ if (inDouble) {
67
+ if (ch === '"' && prev !== '\\') inDouble = false;
68
+ continue;
69
+ }
70
+
71
+ if (ch === '/' && next === '/') {
72
+ inCommentLine = true;
73
+ i++;
74
+ continue;
75
+ }
76
+ if (ch === '/' && next === '*') {
77
+ inCommentMulti = true;
78
+ i++;
79
+ continue;
80
+ }
81
+ if (ch === '`') {
82
+ inTemplate = true;
83
+ continue;
84
+ }
85
+ if (ch === '\'') {
86
+ inSingle = true;
87
+ continue;
88
+ }
89
+ if (ch === '"') {
90
+ inDouble = true;
91
+ continue;
92
+ }
93
+
94
+ if (ch === '{') {
95
+ if (open === 0) startBlockIndex = i;
96
+ open++;
97
+ } else if (ch === '}') {
98
+ open--;
99
+ if (open === 0) {
100
+ endBlockIndex = i;
101
+ return { start: startBlockIndex, end: endBlockIndex };
102
+ }
103
+ }
104
+ }
105
+ return null;
106
+ }
107
+
108
+ function consumeWhitespace(str, i) {
109
+ while (i < str.length && /\s/.test(str[i])) i++;
110
+ return i;
111
+ }
112
+
113
+ function parseIfChain(str, ifIndex) {
114
+ const head = str.slice(ifIndex);
115
+ const m = head.match(/^if\s*\((.*?)\)\s*\{/);
116
+ if (!m) return null;
117
+
118
+ let i = ifIndex;
119
+ const chainEdits = [];
120
+ let hasElse = false;
121
+ let isFirst = true;
122
+
123
+ while (true) {
124
+ const cur = str.slice(i);
125
+ const mm = cur.match(/^if\s*\((.*?)\)\s*\{/);
126
+ if (!mm) break;
127
+
128
+ const cond = mm[1];
129
+ const condStartInMatch = mm[0].indexOf('(') + 1;
130
+ const condEndInMatch = mm[0].lastIndexOf(')');
131
+
132
+ // 1. "if (" or "else if (" -> "(" or ") : ("
133
+ const prefixReplacement = isFirst ? '(' : ') : (';
134
+ applyOverlapOverwrite(i, i + condStartInMatch, prefixReplacement);
135
+
136
+ // 2. Condition preserved as-is for mapping/hover accuracy
137
+ // Since we have // @ts-nocheck, we don't need complex ternary wrapping here.
138
+
139
+ // 3. ") {" -> ") ? (<Fragment>"
140
+ applyOverlapOverwrite(i + condEndInMatch, i + mm[0].length, ') ? (<Fragment>');
141
+
142
+ const blockStart = i + mm[0].length - 1;
143
+ const block = parseBlock(str, blockStart);
144
+ if (!block) break;
145
+
146
+ i = block.end;
147
+ const endOfBlock = i;
148
+
149
+ i++; // skip }
150
+ i = consumeWhitespace(str, i);
151
+
152
+ isFirst = false;
153
+
154
+ if (str.startsWith('else', i)) {
155
+ const nextI = consumeWhitespace(str, i + 4);
156
+ if (str.startsWith('if', nextI)) {
157
+ // Handled by next loop iteration
158
+ i = nextI;
159
+ continue;
160
+ }
161
+
162
+ if (str[nextI] === '{') {
163
+ const elseBlock = parseBlock(str, nextI);
164
+ if (elseBlock) {
165
+ applyOverlapOverwrite(endOfBlock, nextI + 1, '</Fragment>) : (<Fragment>');
166
+ applyOverlapOverwrite(elseBlock.end, elseBlock.end + 1, '</Fragment>)');
167
+ hasElse = true;
168
+ i = elseBlock.end + 1;
169
+ break;
170
+ }
171
+ }
172
+ }
173
+
174
+ applyOverlapOverwrite(endOfBlock, endOfBlock + 1, '</Fragment>) : null');
175
+ break;
176
+ }
177
+
178
+ return { hasElse }; // chainEdits are applied immediately via applyOverlapOverwrite
179
+ }
180
+
181
+ // Process "if" expressions {if(cond){...}}
182
+ let currentCode = s.original;
183
+ let match;
184
+ const ifExprRegex = /\{\s*if\s*\(/g;
185
+ while ((match = ifExprRegex.exec(currentCode)) !== null) {
186
+ const start = match.index;
187
+ const outer = parseBlock(currentCode, start);
188
+ if (!outer) continue;
189
+
190
+ const innerIfStart = consumeWhitespace(currentCode, start + 1);
191
+ applyOverlapOverwrite(start, start + 1, '{(() => ');
192
+ parseIfChain(currentCode, innerIfStart);
193
+ applyOverlapOverwrite(outer.end, outer.end + 1, ')}');
194
+ }
195
+
196
+ // Process "for" expressions {for(item in list){...}}
197
+ const forExprRegex = /\{\s*for\s*\((.*?)\s+in\s+(.*?)\)\s*\{/g;
198
+ currentCode = s.original;
199
+ while ((match = forExprRegex.exec(currentCode)) !== null) {
200
+ const start = match.index;
201
+ const outer = parseBlock(currentCode, start);
202
+ if (!outer) continue;
203
+
204
+ const blockStart = start + match[0].lastIndexOf('{');
205
+ const block = parseBlock(currentCode, blockStart);
206
+ if (!block) continue;
207
+
208
+ const item = match[1];
209
+ const list = match[2];
210
+ const parenStart = start + match[0].indexOf('(');
211
+ const parenEnd = start + match[0].indexOf(')');
212
+
213
+ applyOverlapOverwrite(start, parenStart + 1, '{(() => ');
214
+ applyOverlapOverwrite(parenStart + 1, block.start + 1, `${list}.map(${item} => (<Fragment>`);
215
+ applyOverlapOverwrite(block.end, block.end + 1, '</Fragment>)))}');
216
+ }
217
+
218
+ // signal() replacements
219
+ const signalRegex = /\{\s*([A-Za-z_$][\w$]*)\s*\(\s*\)\s*\}/g;
220
+ currentCode = s.original;
221
+ while ((match = signalRegex.exec(currentCode)) !== null) {
222
+ const braceEnd = match[0].indexOf(match[1]);
223
+ applyOverlapOverwrite(match.index, match.index + braceEnd, '{() => ');
224
+ }
225
+
226
+ const signalAttrRegex = /=\{\s*([A-Za-z_$][\w$]*)\s*\(\s*\)\s*\}/g;
227
+ while ((match = signalAttrRegex.exec(currentCode)) !== null) {
228
+ const braceEnd = match[0].indexOf(match[1]);
229
+ applyOverlapOverwrite(match.index, match.index + braceEnd, '={() => ');
230
+ }
231
+
232
+ // Sort edits by original offset for easy lookup
233
+ edits.sort((a, b) => a.offset - b.offset);
234
+
235
+ return {
236
+ code: s.toString(),
237
+ edits,
238
+ map: s.generateMap({
239
+ source: filename,
240
+ file: filename + '.tsx',
241
+ includeContent: true,
242
+ hires: true
243
+ })
244
+ };
245
+ }
246
+
247
+
248
+ module.exports = { transformLSP };