@litsx/babel-preset-litsx 0.8.1 → 0.9.0

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.
@@ -6,6 +6,10 @@ import fs from "node:fs";
6
6
  import path from "node:path";
7
7
  import { normalizeFilePath } from "@litsx/typescript-session";
8
8
  import { ensureTypescriptModule } from "./transform-litsx-properties.js";
9
+ import {
10
+ ensureStaticIr,
11
+ setStaticIrBabelTypes,
12
+ } from "./transform-litsx-static-ir.js";
9
13
 
10
14
  const { declare } = helperPluginUtils;
11
15
  const traverse = babelTraverse.default || babelTraverse;
@@ -32,6 +36,7 @@ let t;
32
36
 
33
37
  export function setElementCandidatesBabelTypes(nextTypes) {
34
38
  t = nextTypes;
39
+ setStaticIrBabelTypes(nextTypes);
35
40
  }
36
41
 
37
42
  function isInsideFunctionOrClass(path) {
@@ -59,6 +64,13 @@ function createEmptyCandidateResult() {
59
64
  };
60
65
  }
61
66
 
67
+ function annotateElementCandidates(node, result) {
68
+ if (!node) return;
69
+ const staticIr = ensureStaticIr(node);
70
+ staticIr.elements.localCandidates = [...result.localCandidates];
71
+ staticIr.elements.importedCandidates = [...result.importedCandidates.values()];
72
+ }
73
+
62
74
  function cloneCandidateResult(result) {
63
75
  return {
64
76
  localCandidates: new Set(result?.localCandidates || []),
@@ -536,7 +548,10 @@ function getOrCreateModuleAnalysis(filename, context) {
536
548
 
537
549
  let programPath = null;
538
550
  try {
539
- const ast = parser.parse(source, { sourceType: "module" });
551
+ const ast = parser.parse(source, {
552
+ sourceType: "module",
553
+ plugins: getParserPluginsForModule(normalizedFilename, source),
554
+ });
540
555
  traverse(ast, {
541
556
  Program(path) {
542
557
  if (!programPath) {
@@ -665,6 +680,73 @@ function resolveExportedHelper(moduleAnalysis, exportedName, context, seen = new
665
680
  return null;
666
681
  }
667
682
 
683
+ function getParserPluginsForModule(filename, source) {
684
+ if (/\.(?:[cm]?ts|tsx|litsx)$/i.test(filename)) {
685
+ return ["typescript"];
686
+ }
687
+
688
+ if (/\b(?:as|satisfies)\s+[^;,)]+/.test(source)) {
689
+ return ["typescript"];
690
+ }
691
+
692
+ return [];
693
+ }
694
+
695
+ function unwrapNamespaceAliasExpression(node) {
696
+ let current = node;
697
+ while (
698
+ t.isTSAsExpression(current) ||
699
+ t.isTSTypeAssertion(current) ||
700
+ t.isTSNonNullExpression(current) ||
701
+ t.isTSSatisfiesExpression?.(current)
702
+ ) {
703
+ current = current.expression;
704
+ }
705
+ return current;
706
+ }
707
+
708
+ function getNamespaceMemberAliasInfo(candidateName, moduleAnalysis) {
709
+ const binding = moduleAnalysis.programPath.scope.getBinding(candidateName);
710
+ if (!binding || !isProgramLevelBinding(binding)) {
711
+ return null;
712
+ }
713
+
714
+ const declaratorPath = binding.path.isVariableDeclarator?.()
715
+ ? binding.path
716
+ : binding.path.parentPath;
717
+ if (!declaratorPath?.isVariableDeclarator?.()) {
718
+ return null;
719
+ }
720
+
721
+ const init = unwrapNamespaceAliasExpression(declaratorPath.node.init);
722
+ if (
723
+ !t.isMemberExpression(init) ||
724
+ init.computed ||
725
+ !t.isIdentifier(unwrapNamespaceAliasExpression(init.object)) ||
726
+ !t.isIdentifier(init.property)
727
+ ) {
728
+ return null;
729
+ }
730
+
731
+ const namespaceObject = unwrapNamespaceAliasExpression(init.object);
732
+ const namespaceImport = moduleAnalysis.importBindings.get(namespaceObject.name);
733
+ if (
734
+ !namespaceImport ||
735
+ namespaceImport.importedName !== "*" ||
736
+ !namespaceImport.resolvedSource
737
+ ) {
738
+ return null;
739
+ }
740
+
741
+ return {
742
+ localName: candidateName,
743
+ namespaceName: namespaceObject.name,
744
+ importedName: init.property.name,
745
+ sourceValue: namespaceImport.sourceValue,
746
+ resolvedSource: namespaceImport.resolvedSource,
747
+ };
748
+ }
749
+
668
750
  function resolveImportedElementRequirement(candidateName, moduleAnalysis, context, rootFilename) {
669
751
  const binding = moduleAnalysis.programPath.scope.getBinding(candidateName);
670
752
  if (!binding || !isProgramLevelBinding(binding)) {
@@ -692,6 +774,20 @@ function resolveImportedElementRequirement(candidateName, moduleAnalysis, contex
692
774
  };
693
775
  }
694
776
 
777
+ const namespaceAliasInfo = getNamespaceMemberAliasInfo(candidateName, moduleAnalysis);
778
+ if (namespaceAliasInfo) {
779
+ return {
780
+ sourceFile: namespaceAliasInfo.resolvedSource,
781
+ sourceSpecifier: isRelativeSpecifier(namespaceAliasInfo.sourceValue)
782
+ ? null
783
+ : namespaceAliasInfo.sourceValue,
784
+ importedName: namespaceAliasInfo.importedName,
785
+ originalName: candidateName,
786
+ tagName: candidateName.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(),
787
+ rootFilename,
788
+ };
789
+ }
790
+
695
791
  const exportInfo =
696
792
  moduleAnalysis.exportBindings.get(candidateName) ||
697
793
  moduleAnalysis.exportBindings.get("default");
@@ -904,16 +1000,18 @@ function collectCandidateResult(functionPath, programPath, options = {}) {
904
1000
  }
905
1001
 
906
1002
  export function getAnnotatedElementCandidates(path, programPath, options = {}) {
907
- if (path?.node?._litsxElementCandidates instanceof Set) {
908
- return new Set(path.node._litsxElementCandidates);
1003
+ const localCandidates = path?.node?._litsxStaticIr?.elements?.localCandidates;
1004
+ if (Array.isArray(localCandidates)) {
1005
+ return new Set(localCandidates);
909
1006
  }
910
1007
 
911
1008
  return collectCandidateResult(path, programPath, options).localCandidates;
912
1009
  }
913
1010
 
914
1011
  export function getAnnotatedImportedElementCandidates(path, programPath, options = {}) {
915
- if (Array.isArray(path?.node?._litsxImportedElementCandidates)) {
916
- return [...path.node._litsxImportedElementCandidates];
1012
+ const importedCandidates = path?.node?._litsxStaticIr?.elements?.importedCandidates;
1013
+ if (Array.isArray(importedCandidates)) {
1014
+ return [...importedCandidates];
917
1015
  }
918
1016
 
919
1017
  return [...collectCandidateResult(path, programPath, options).importedCandidates.values()];
@@ -1126,8 +1224,7 @@ export default declare((api) => {
1126
1224
  filename: state.file?.opts?.filename || "",
1127
1225
  }
1128
1226
  );
1129
- path.node._litsxElementCandidates = result.localCandidates;
1130
- path.node._litsxImportedElementCandidates = [...result.importedCandidates.values()];
1227
+ annotateElementCandidates(path.node, result);
1131
1228
  },
1132
1229
  },
1133
1230
  ArrowFunctionExpression: {
@@ -1145,8 +1242,7 @@ export default declare((api) => {
1145
1242
  filename: state.file?.opts?.filename || "",
1146
1243
  }
1147
1244
  );
1148
- path.node._litsxElementCandidates = result.localCandidates;
1149
- path.node._litsxImportedElementCandidates = [...result.importedCandidates.values()];
1245
+ annotateElementCandidates(path.node, result);
1150
1246
  },
1151
1247
  },
1152
1248
  FunctionExpression: {
@@ -1164,8 +1260,7 @@ export default declare((api) => {
1164
1260
  filename: state.file?.opts?.filename || "",
1165
1261
  }
1166
1262
  );
1167
- path.node._litsxElementCandidates = result.localCandidates;
1168
- path.node._litsxImportedElementCandidates = [...result.importedCandidates.values()];
1263
+ annotateElementCandidates(path.node, result);
1169
1264
  },
1170
1265
  },
1171
1266
  },