@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.
@@ -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;AAmT/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,CA4N9E"}
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"}
@@ -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;
@@ -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;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,eAAe,CA4FlG;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAItE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAI1E"}
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 { vskToTsx, generateVskDts } from '@vesk/compiler/src/vsk-tsx';
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 = vskToTsx(vskFiles.get(file));
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 vskToTsx(vskFiles.get(file));
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
- const pos = file.getLineAndCharacterOfPosition(diag.start ?? 0);
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: pos.line + 1,
828
- column: pos.character + 1,
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.39",
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.39",
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",