@vesk/compiler 0.2.39 → 0.2.41
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.
- package/dist/ir-generator.d.ts.map +1 -1
- package/dist/ir-generator.js +12 -4
- package/dist/typecheck.d.ts.map +1 -1
- package/dist/typecheck.js +52 -6
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ir-generator.d.ts","sourceRoot":"","sources":["../src/ir-generator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,MAAM,EAsBP,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"ir-generator.d.ts","sourceRoot":"","sources":["../src/ir-generator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,MAAM,EAsBP,MAAM,uBAAuB,CAAC;AA2T/B,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,CAAC;IAAC,cAAc,CAAC,EAAE,GAAG,CAAC;IAAC,UAAU,CAAC,EAAE,GAAG,EAAE,CAAA;CAAE,CAAC,GAAG,SAAS,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkCnL;AA48BD,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CA6N9E"}
|
package/dist/ir-generator.js
CHANGED
|
@@ -15,6 +15,13 @@ let __vskAnnotations = [];
|
|
|
15
15
|
* slot handed to it by a caller that wrote `name={<div/>}`.
|
|
16
16
|
*/
|
|
17
17
|
let __slotProps = null;
|
|
18
|
+
/**
|
|
19
|
+
* The identifier a component binds its props to (`props` by convention, but
|
|
20
|
+
* any first-parameter name is legal). Slot detection used to hardcode the
|
|
21
|
+
* literal `props`, so a `Component`-typed prop read through a differently
|
|
22
|
+
* named parameter was treated as a plain value and stringified.
|
|
23
|
+
*/
|
|
24
|
+
let __propsParam = null;
|
|
18
25
|
function parseExprNode(text) {
|
|
19
26
|
try {
|
|
20
27
|
const ParserClass = createBaseParser();
|
|
@@ -463,7 +470,7 @@ function containsJSX(node) {
|
|
|
463
470
|
*/
|
|
464
471
|
function slotReadPropName(expr) {
|
|
465
472
|
if (expr.type === 'MemberExpression' && !expr.computed &&
|
|
466
|
-
expr.object.type === 'Identifier' && expr.object.name === 'props' &&
|
|
473
|
+
expr.object.type === 'Identifier' && expr.object.name === (__propsParam || 'props') &&
|
|
467
474
|
expr.property.type === 'Identifier') {
|
|
468
475
|
return expr.property.name;
|
|
469
476
|
}
|
|
@@ -719,7 +726,7 @@ function processJSXChildren(source, children) {
|
|
|
719
726
|
continue;
|
|
720
727
|
}
|
|
721
728
|
if ((expr.type === 'MemberExpression' && !expr.computed &&
|
|
722
|
-
expr.object.type === 'Identifier' && expr.object.name === 'props' &&
|
|
729
|
+
expr.object.type === 'Identifier' && expr.object.name === (__propsParam || 'props') &&
|
|
723
730
|
expr.property.type === 'Identifier' && expr.property.name === 'children')
|
|
724
731
|
|| (expr.type === 'Identifier' && expr.name === 'children')) {
|
|
725
732
|
result.push(new SlotNode());
|
|
@@ -818,7 +825,7 @@ function exprToIR(source, expr) {
|
|
|
818
825
|
// insert the slot nodes — not degrade to a text binding that stringifies
|
|
819
826
|
// the fragment (`String(props.children)` → "[object DocumentFragment]").
|
|
820
827
|
if ((expr.type === 'MemberExpression' && !expr.computed &&
|
|
821
|
-
expr.object.type === 'Identifier' && expr.object.name === 'props' &&
|
|
828
|
+
expr.object.type === 'Identifier' && expr.object.name === (__propsParam || 'props') &&
|
|
822
829
|
expr.property.type === 'Identifier' && expr.property.name === 'children')
|
|
823
830
|
|| (expr.type === 'Identifier' && expr.name === 'children')) {
|
|
824
831
|
return [new SlotNode()];
|
|
@@ -1500,6 +1507,7 @@ export function generateIR(ast, source, filename) {
|
|
|
1500
1507
|
// value bindings for THIS component only.
|
|
1501
1508
|
const prevSlotProps = __slotProps;
|
|
1502
1509
|
__slotProps = slotPropNamesFromType(propsType);
|
|
1510
|
+
__propsParam = propsAlias || null;
|
|
1503
1511
|
if (isStatementMode(bodyStmts)) {
|
|
1504
1512
|
const raw = processStatementModeBody(source, bodyStmts, file);
|
|
1505
1513
|
const { body, css } = extractStyle(raw);
|
|
@@ -1553,7 +1561,7 @@ export function generateIR(ast, source, filename) {
|
|
|
1553
1561
|
const guardBody = buildGuardChain(source, guardClauses, mainReturn);
|
|
1554
1562
|
const { body, css } = extractStyle([...preamble, ...guardBody]);
|
|
1555
1563
|
validateBlocks(name, isClientComp, body, file, source);
|
|
1556
|
-
const comp = new ComponentIR(name, paramNames, body, { exported, defaultExport, isClient: inner.client, isAsync: inner.async, ssrAwait: componentUsesFetch(body), propsType });
|
|
1564
|
+
const comp = new ComponentIR(name, paramNames, body, { exported, defaultExport, isClient: inner.client, isAsync: inner.async, ssrAwait: componentUsesFetch(body), propsType, propsAlias });
|
|
1557
1565
|
comp.style = css;
|
|
1558
1566
|
components.push(comp);
|
|
1559
1567
|
__slotProps = prevSlotProps;
|
package/dist/typecheck.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typecheck.d.ts","sourceRoot":"","sources":["../src/typecheck.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAKD,eAAO,MAAM,OAAO,6xoBAkhBnB,CAAC;AAEF,eAAO,MAAM,gBAAgB,uZAS5B,CAAC;AA6LF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;
|
|
1
|
+
{"version":3,"file":"typecheck.d.ts","sourceRoot":"","sources":["../src/typecheck.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAKD,eAAO,MAAM,OAAO,6xoBAkhBnB,CAAC;AAEF,eAAO,MAAM,gBAAgB,uZAS5B,CAAC;AA6LF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAuCD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,eAAe,CA2GlG;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAItE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAI1E"}
|
package/dist/typecheck.js
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync, readdirSync, statSync } from 'node:fs';
|
|
|
2
2
|
import { join, dirname, normalize, relative, resolve, sep } from 'node:path';
|
|
3
3
|
import * as ts from 'typescript';
|
|
4
4
|
import { parse } from '@vesk/compiler/src/parser';
|
|
5
|
-
import {
|
|
5
|
+
import { compileVskCodegen, generateVskDts } from '@vesk/compiler/src/vsk-tsx';
|
|
6
6
|
import { resolveAliasModule } from '@vesk/compiler/src/module-imports';
|
|
7
7
|
const SKIP_DIRS = new Set(['node_modules', '.vesk', '.git', 'dist', 'tarballs', '.next']);
|
|
8
8
|
const SKIP_FILES = new Set(['__vesk_ambient.d.ts', '__vesk_runtime_override.d.ts']);
|
|
@@ -642,7 +642,7 @@ function createTypecheckHost(projectRoot, appDir, vskFiles) {
|
|
|
642
642
|
content = '';
|
|
643
643
|
}
|
|
644
644
|
else if (vskFiles.has(file)) {
|
|
645
|
-
content =
|
|
645
|
+
content = compileVskCodegen(vskFiles.get(file)).code;
|
|
646
646
|
}
|
|
647
647
|
else if (ts.sys.fileExists(file)) {
|
|
648
648
|
content = ts.sys.readFile(file);
|
|
@@ -684,7 +684,7 @@ function createTypecheckHost(projectRoot, appDir, vskFiles) {
|
|
|
684
684
|
if (file.endsWith('.css.d.ts'))
|
|
685
685
|
return '';
|
|
686
686
|
if (vskFiles.has(file))
|
|
687
|
-
return
|
|
687
|
+
return compileVskCodegen(vskFiles.get(file)).code;
|
|
688
688
|
return ts.sys.readFile(file);
|
|
689
689
|
},
|
|
690
690
|
writeFile: () => { },
|
|
@@ -739,6 +739,35 @@ function createTypecheckHost(projectRoot, appDir, vskFiles) {
|
|
|
739
739
|
};
|
|
740
740
|
return host;
|
|
741
741
|
}
|
|
742
|
+
function mapGeneratedOffset(mappings, generatedOffset) {
|
|
743
|
+
let nearest = null;
|
|
744
|
+
for (const mapping of mappings) {
|
|
745
|
+
for (let i = 0; i < mapping.generatedOffsets.length; i++) {
|
|
746
|
+
const generated = mapping.generatedOffsets[i];
|
|
747
|
+
const length = mapping.lengths[i] ?? 0;
|
|
748
|
+
const source = mapping.sourceOffsets[i];
|
|
749
|
+
if (generated <= generatedOffset && generated + length >= generatedOffset) {
|
|
750
|
+
return source + (generatedOffset - generated);
|
|
751
|
+
}
|
|
752
|
+
if (generated <= generatedOffset && (!nearest || generated > nearest.generated)) {
|
|
753
|
+
nearest = { source, generated, length };
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
return nearest ? nearest.source + Math.min(nearest.length, Math.max(0, generatedOffset - nearest.generated)) : null;
|
|
758
|
+
}
|
|
759
|
+
function sourcePosition(source, offset) {
|
|
760
|
+
const bounded = Math.max(0, Math.min(offset, source.length));
|
|
761
|
+
let line = 1;
|
|
762
|
+
let lineStart = 0;
|
|
763
|
+
for (let i = 0; i < bounded; i++) {
|
|
764
|
+
if (source.charCodeAt(i) === 10) {
|
|
765
|
+
line++;
|
|
766
|
+
lineStart = i + 1;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return { line, character: bounded - lineStart + 1 };
|
|
770
|
+
}
|
|
742
771
|
export function typecheckProject(projectRoot, opts = {}) {
|
|
743
772
|
const appDir = opts.appDir ?? join(projectRoot, 'app');
|
|
744
773
|
const vskFiles = new Map();
|
|
@@ -820,12 +849,29 @@ export function typecheckProject(projectRoot, opts = {}) {
|
|
|
820
849
|
}
|
|
821
850
|
if (!rootSet.has(filePath) && !vskSet.has(filePath))
|
|
822
851
|
continue;
|
|
823
|
-
|
|
852
|
+
let sourceOffset = diag.start ?? 0;
|
|
853
|
+
let line;
|
|
854
|
+
let column;
|
|
855
|
+
if (vskFiles.has(filePath)) {
|
|
856
|
+
const source = vskFiles.get(filePath);
|
|
857
|
+
const generated = compileVskCodegen(source);
|
|
858
|
+
const mapped = mapGeneratedOffset(generated.mappings, sourceOffset);
|
|
859
|
+
if (mapped !== null)
|
|
860
|
+
sourceOffset = mapped;
|
|
861
|
+
const pos = sourcePosition(source, sourceOffset);
|
|
862
|
+
line = pos.line;
|
|
863
|
+
column = pos.character;
|
|
864
|
+
}
|
|
865
|
+
else {
|
|
866
|
+
const pos = file.getLineAndCharacterOfPosition(diag.start ?? 0);
|
|
867
|
+
line = pos.line + 1;
|
|
868
|
+
column = pos.character + 1;
|
|
869
|
+
}
|
|
824
870
|
const code = typeof diag.code === 'number' ? `TS${diag.code}` : String(diag.code);
|
|
825
871
|
errors.push({
|
|
826
872
|
file: relative(projectRoot, filePath),
|
|
827
|
-
line
|
|
828
|
-
column
|
|
873
|
+
line,
|
|
874
|
+
column,
|
|
829
875
|
code,
|
|
830
876
|
message: ts.flattenDiagnosticMessageText(diag.messageText, '\n'),
|
|
831
877
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk compiler — lexer, parser, semantic analysis, IR, codegen",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@sveltejs/acorn-typescript": "^1.0.0",
|
|
23
|
-
"@vesk/types": "^0.2.
|
|
23
|
+
"@vesk/types": "^0.2.41",
|
|
24
24
|
"acorn": "^8.15.0",
|
|
25
25
|
"esrap": "^2.3.0",
|
|
26
26
|
"is-reference": "^3.0.0",
|