@alloy-js/python 0.4.0-dev.2 → 0.4.0-dev.5
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/dev/src/builtins/python.js +30 -0
- package/dist/dev/src/builtins/python.js.map +1 -0
- package/dist/dev/src/components/Atom.js +122 -0
- package/dist/dev/src/components/Atom.js.map +1 -0
- package/dist/dev/src/components/CallSignature.js +195 -0
- package/dist/dev/src/components/CallSignature.js.map +1 -0
- package/dist/dev/src/components/ClassDeclaration.js +112 -0
- package/dist/dev/src/components/ClassDeclaration.js.map +1 -0
- package/dist/dev/src/components/ClassInstantiation.js +40 -0
- package/dist/dev/src/components/ClassInstantiation.js.map +1 -0
- package/dist/dev/src/components/ClassMethodDeclaration.js +40 -0
- package/dist/dev/src/components/ClassMethodDeclaration.js.map +1 -0
- package/dist/dev/src/components/ConstructorDeclaration.js +39 -0
- package/dist/dev/src/components/ConstructorDeclaration.js.map +1 -0
- package/dist/dev/src/components/DataclassDeclaration.js +177 -0
- package/dist/dev/src/components/DataclassDeclaration.js.map +1 -0
- package/dist/dev/src/components/Declaration.js +31 -0
- package/dist/dev/src/components/Declaration.js.map +1 -0
- package/dist/dev/src/components/DunderMethodDeclaration.js +33 -0
- package/dist/dev/src/components/DunderMethodDeclaration.js.map +1 -0
- package/dist/dev/src/components/EnumDeclaration.js +259 -0
- package/dist/dev/src/components/EnumDeclaration.js.map +1 -0
- package/dist/dev/src/components/EnumMember.js +95 -0
- package/dist/dev/src/components/EnumMember.js.map +1 -0
- package/dist/dev/src/components/FunctionBase.js +130 -0
- package/dist/dev/src/components/FunctionBase.js.map +1 -0
- package/dist/dev/src/components/FunctionCallExpression.js +53 -0
- package/dist/dev/src/components/FunctionCallExpression.js.map +1 -0
- package/dist/dev/src/components/FunctionDeclaration.js +45 -0
- package/dist/dev/src/components/FunctionDeclaration.js.map +1 -0
- package/dist/dev/src/components/FutureStatement.js +31 -0
- package/dist/dev/src/components/FutureStatement.js.map +1 -0
- package/dist/dev/src/components/ImportStatement.js +167 -0
- package/dist/dev/src/components/ImportStatement.js.map +1 -0
- package/dist/dev/src/components/LexicalScope.js +26 -0
- package/dist/dev/src/components/LexicalScope.js.map +1 -0
- package/dist/dev/src/components/MemberExpression.js +290 -0
- package/dist/dev/src/components/MemberExpression.js.map +1 -0
- package/dist/dev/src/components/MemberScope.js +23 -0
- package/dist/dev/src/components/MemberScope.js.map +1 -0
- package/dist/dev/src/components/MethodBase.js +40 -0
- package/dist/dev/src/components/MethodBase.js.map +1 -0
- package/dist/dev/src/components/MethodDeclaration.js +38 -0
- package/dist/dev/src/components/MethodDeclaration.js.map +1 -0
- package/dist/dev/src/components/PropertyDeclaration.js +287 -0
- package/dist/dev/src/components/PropertyDeclaration.js.map +1 -0
- package/dist/dev/src/components/PyDoc.js +1478 -0
- package/dist/dev/src/components/PyDoc.js.map +1 -0
- package/dist/dev/src/components/PythonBlock.js +35 -0
- package/dist/dev/src/components/PythonBlock.js.map +1 -0
- package/dist/dev/src/components/Reference.js +23 -0
- package/dist/dev/src/components/Reference.js.map +1 -0
- package/dist/dev/src/components/SourceFile.js +385 -0
- package/dist/dev/src/components/SourceFile.js.map +1 -0
- package/dist/dev/src/components/StatementList.js +34 -0
- package/dist/dev/src/components/StatementList.js.map +1 -0
- package/dist/dev/src/components/StaticMethodDeclaration.js +40 -0
- package/dist/dev/src/components/StaticMethodDeclaration.js.map +1 -0
- package/dist/dev/src/components/TypeArguments.js +22 -0
- package/dist/dev/src/components/TypeArguments.js.map +1 -0
- package/dist/dev/src/components/TypeRefContext.js +33 -0
- package/dist/dev/src/components/TypeRefContext.js.map +1 -0
- package/dist/dev/src/components/TypeReference.js +67 -0
- package/dist/dev/src/components/TypeReference.js.map +1 -0
- package/dist/dev/src/components/UnionTypeExpression.js +57 -0
- package/dist/dev/src/components/UnionTypeExpression.js.map +1 -0
- package/dist/dev/src/components/VariableDeclaration.js +150 -0
- package/dist/dev/src/components/VariableDeclaration.js.map +1 -0
- package/dist/dev/src/components/index.js +32 -0
- package/dist/dev/src/components/index.js.map +1 -0
- package/dist/dev/src/context/index.js +2 -0
- package/dist/dev/src/context/index.js.map +1 -0
- package/dist/dev/src/context/type-ref-context.js +17 -0
- package/dist/dev/src/context/type-ref-context.js.map +1 -0
- package/dist/dev/src/create-module.js +64 -0
- package/dist/dev/src/create-module.js.map +1 -0
- package/dist/dev/src/index.js +8 -0
- package/dist/dev/src/index.js.map +1 -0
- package/dist/dev/src/name-conflict-resolver.js +8 -0
- package/dist/dev/src/name-conflict-resolver.js.map +1 -0
- package/dist/dev/src/name-policy.js +48 -0
- package/dist/dev/src/name-policy.js.map +1 -0
- package/dist/dev/src/parameter-descriptor.js +8 -0
- package/dist/dev/src/parameter-descriptor.js.map +1 -0
- package/dist/dev/src/symbol-creation.js +58 -0
- package/dist/dev/src/symbol-creation.js.map +1 -0
- package/dist/dev/src/symbols/factories.js +28 -0
- package/dist/dev/src/symbols/factories.js.map +1 -0
- package/dist/dev/src/symbols/index.js +8 -0
- package/dist/dev/src/symbols/index.js.map +1 -0
- package/dist/dev/src/symbols/python-lexical-scope.js +15 -0
- package/dist/dev/src/symbols/python-lexical-scope.js.map +1 -0
- package/dist/dev/src/symbols/python-member-scope.js +7 -0
- package/dist/dev/src/symbols/python-member-scope.js.map +1 -0
- package/dist/dev/src/symbols/python-module-scope.js +86 -0
- package/dist/dev/src/symbols/python-module-scope.js.map +1 -0
- package/dist/dev/src/symbols/python-output-symbol.js +73 -0
- package/dist/dev/src/symbols/python-output-symbol.js.map +1 -0
- package/dist/dev/src/symbols/reference.js +87 -0
- package/dist/dev/src/symbols/reference.js.map +1 -0
- package/dist/dev/src/symbols/scopes.js +13 -0
- package/dist/dev/src/symbols/scopes.js.map +1 -0
- package/dist/dev/src/utils.js +13 -0
- package/dist/dev/src/utils.js.map +1 -0
- package/dist/dev/test/callsignatures.test.js +482 -0
- package/dist/dev/test/callsignatures.test.js.map +1 -0
- package/dist/dev/test/class-method-declaration.test.js +85 -0
- package/dist/dev/test/class-method-declaration.test.js.map +1 -0
- package/dist/dev/test/classdeclarations.test.js +654 -0
- package/dist/dev/test/classdeclarations.test.js.map +1 -0
- package/dist/dev/test/classinstantiations.test.js +281 -0
- package/dist/dev/test/classinstantiations.test.js.map +1 -0
- package/dist/dev/test/constructordeclaration.test.js +86 -0
- package/dist/dev/test/constructordeclaration.test.js.map +1 -0
- package/dist/dev/test/dataclassdeclarations.test.js +1068 -0
- package/dist/dev/test/dataclassdeclarations.test.js.map +1 -0
- package/dist/dev/test/dundermethoddeclaration.test.js +93 -0
- package/dist/dev/test/dundermethoddeclaration.test.js.map +1 -0
- package/dist/dev/test/enums.test.js +263 -0
- package/dist/dev/test/enums.test.js.map +1 -0
- package/dist/dev/test/externals.test.js +307 -0
- package/dist/dev/test/externals.test.js.map +1 -0
- package/dist/dev/test/factories.test.js +122 -0
- package/dist/dev/test/factories.test.js.map +1 -0
- package/dist/dev/test/functioncallexpressions.test.js +257 -0
- package/dist/dev/test/functioncallexpressions.test.js.map +1 -0
- package/dist/dev/test/functiondeclaration.test.js +817 -0
- package/dist/dev/test/functiondeclaration.test.js.map +1 -0
- package/dist/dev/test/imports.test.js +372 -0
- package/dist/dev/test/imports.test.js.map +1 -0
- package/dist/dev/test/memberexpressions.test.js +1668 -0
- package/dist/dev/test/memberexpressions.test.js.map +1 -0
- package/dist/dev/test/methoddeclaration.test.js +344 -0
- package/dist/dev/test/methoddeclaration.test.js.map +1 -0
- package/dist/dev/test/namepolicies.test.js +154 -0
- package/dist/dev/test/namepolicies.test.js.map +1 -0
- package/dist/dev/test/propertydeclaration.test.js +354 -0
- package/dist/dev/test/propertydeclaration.test.js.map +1 -0
- package/dist/dev/test/pydocs.test.js +1675 -0
- package/dist/dev/test/pydocs.test.js.map +1 -0
- package/dist/dev/test/references.test.js +66 -0
- package/dist/dev/test/references.test.js.map +1 -0
- package/dist/dev/test/sourcefiles.test.js +1802 -0
- package/dist/dev/test/sourcefiles.test.js.map +1 -0
- package/dist/dev/test/staticmethoddeclaration.test.js +85 -0
- package/dist/dev/test/staticmethoddeclaration.test.js.map +1 -0
- package/dist/dev/test/type-checking-imports.test.js +617 -0
- package/dist/dev/test/type-checking-imports.test.js.map +1 -0
- package/dist/dev/test/typereference.test.js +79 -0
- package/dist/dev/test/typereference.test.js.map +1 -0
- package/dist/dev/test/uniontypeexpression.test.js +307 -0
- package/dist/dev/test/uniontypeexpression.test.js.map +1 -0
- package/dist/dev/test/utils.js +100 -0
- package/dist/dev/test/utils.js.map +1 -0
- package/dist/dev/test/values.test.js +182 -0
- package/dist/dev/test/values.test.js.map +1 -0
- package/dist/dev/test/variables.test.js +363 -0
- package/dist/dev/test/variables.test.js.map +1 -0
- package/dist/src/components/CallSignature.d.ts.map +1 -1
- package/dist/src/components/CallSignature.js +12 -3
- package/dist/src/components/CallSignature.js.map +1 -1
- package/dist/src/components/ImportStatement.d.ts +12 -0
- package/dist/src/components/ImportStatement.d.ts.map +1 -1
- package/dist/src/components/ImportStatement.js +47 -5
- package/dist/src/components/ImportStatement.js.map +1 -1
- package/dist/src/components/MemberExpression.d.ts +1 -1
- package/dist/src/components/MemberExpression.d.ts.map +1 -1
- package/dist/src/components/MemberExpression.js +98 -180
- package/dist/src/components/MemberExpression.js.map +1 -1
- package/dist/src/components/Reference.d.ts.map +1 -1
- package/dist/src/components/Reference.js +5 -1
- package/dist/src/components/Reference.js.map +1 -1
- package/dist/src/components/SourceFile.d.ts +1 -1
- package/dist/src/components/SourceFile.d.ts.map +1 -1
- package/dist/src/components/SourceFile.js +46 -7
- package/dist/src/components/SourceFile.js.map +1 -1
- package/dist/src/components/TypeRefContext.d.ts +26 -0
- package/dist/src/components/TypeRefContext.d.ts.map +1 -0
- package/dist/src/components/TypeRefContext.js +29 -0
- package/dist/src/components/TypeRefContext.js.map +1 -0
- package/dist/src/components/TypeReference.d.ts +5 -0
- package/dist/src/components/TypeReference.d.ts.map +1 -1
- package/dist/src/components/TypeReference.js +19 -9
- package/dist/src/components/TypeReference.js.map +1 -1
- package/dist/src/components/VariableDeclaration.d.ts.map +1 -1
- package/dist/src/components/VariableDeclaration.js +7 -2
- package/dist/src/components/VariableDeclaration.js.map +1 -1
- package/dist/src/components/index.d.ts +1 -1
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +1 -1
- package/dist/src/components/index.js.map +1 -1
- package/dist/src/context/index.d.ts +2 -0
- package/dist/src/context/index.d.ts.map +1 -0
- package/dist/src/context/index.js +2 -0
- package/dist/src/context/index.js.map +1 -0
- package/dist/src/context/type-ref-context.d.ts +13 -0
- package/dist/src/context/type-ref-context.d.ts.map +1 -0
- package/dist/src/context/type-ref-context.js +17 -0
- package/dist/src/context/type-ref-context.js.map +1 -0
- package/dist/src/symbols/python-module-scope.d.ts +13 -1
- package/dist/src/symbols/python-module-scope.d.ts.map +1 -1
- package/dist/src/symbols/python-module-scope.js +36 -2
- package/dist/src/symbols/python-module-scope.js.map +1 -1
- package/dist/src/symbols/python-output-symbol.d.ts +11 -0
- package/dist/src/symbols/python-output-symbol.d.ts.map +1 -1
- package/dist/src/symbols/python-output-symbol.js +26 -2
- package/dist/src/symbols/python-output-symbol.js.map +1 -1
- package/dist/src/symbols/reference.d.ts +8 -1
- package/dist/src/symbols/reference.d.ts.map +1 -1
- package/dist/src/symbols/reference.js +4 -2
- package/dist/src/symbols/reference.js.map +1 -1
- package/dist/test/dataclassdeclarations.test.js +5 -2
- package/dist/test/dataclassdeclarations.test.js.map +1 -1
- package/dist/test/externals.test.js +8 -2
- package/dist/test/externals.test.js.map +1 -1
- package/dist/test/functiondeclaration.test.js +6 -3
- package/dist/test/functiondeclaration.test.js.map +1 -1
- package/dist/test/imports.test.js +3 -3
- package/dist/test/imports.test.js.map +1 -1
- package/dist/test/references.test.js +1 -1
- package/dist/test/references.test.js.map +1 -1
- package/dist/test/sourcefiles.test.js +26 -26
- package/dist/test/sourcefiles.test.js.map +1 -1
- package/dist/test/type-checking-imports.test.d.ts +2 -0
- package/dist/test/type-checking-imports.test.d.ts.map +1 -0
- package/dist/test/type-checking-imports.test.js +437 -0
- package/dist/test/type-checking-imports.test.js.map +1 -0
- package/dist/test/uniontypeexpression.test.js +4 -1
- package/dist/test/uniontypeexpression.test.js.map +1 -1
- package/dist/test/variables.test.js +4 -1
- package/dist/test/variables.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -4
- package/src/components/CallSignature.tsx +6 -2
- package/src/components/ImportStatement.tsx +52 -5
- package/src/components/MemberExpression.tsx +174 -298
- package/src/components/Reference.tsx +3 -1
- package/src/components/SourceFile.tsx +44 -8
- package/src/components/TypeRefContext.tsx +36 -0
- package/src/components/TypeReference.tsx +15 -7
- package/src/components/VariableDeclaration.tsx +5 -1
- package/src/components/index.ts +1 -1
- package/src/context/index.ts +1 -0
- package/src/context/type-ref-context.tsx +16 -0
- package/src/symbols/python-module-scope.ts +55 -2
- package/src/symbols/python-output-symbol.ts +32 -1
- package/src/symbols/reference.tsx +10 -0
- package/temp/api.json +443 -338
- package/test/dataclassdeclarations.test.tsx +8 -2
- package/test/externals.test.tsx +8 -2
- package/test/functiondeclaration.test.tsx +6 -3
- package/test/imports.test.tsx +6 -6
- package/test/references.test.tsx +1 -1
- package/test/sourcefiles.test.tsx +13 -13
- package/test/type-checking-imports.test.tsx +363 -0
- package/test/uniontypeexpression.test.tsx +4 -1
- package/test/variables.test.tsx +4 -1
- package/vitest.config.ts +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alloy-js/python",
|
|
3
|
-
"version": "0.4.0-dev.
|
|
3
|
+
"version": "0.4.0-dev.5",
|
|
4
4
|
"description": "Python bindings for Alloy",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,9 +8,11 @@
|
|
|
8
8
|
},
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
+
"development": "./dist/dev/src/index.js",
|
|
11
12
|
"import": "./dist/src/index.js"
|
|
12
13
|
},
|
|
13
14
|
"./stc": {
|
|
15
|
+
"development": "./dist/dev/src/components/stc/index.js",
|
|
14
16
|
"import": "./dist/src/components/stc/index.js"
|
|
15
17
|
}
|
|
16
18
|
},
|
|
@@ -18,12 +20,12 @@
|
|
|
18
20
|
"author": "",
|
|
19
21
|
"license": "MIT",
|
|
20
22
|
"dependencies": {
|
|
21
|
-
"@alloy-js/core": "~0.22.0 || >= 0.23.0-dev.
|
|
23
|
+
"@alloy-js/core": "~0.22.0 || >= 0.23.0-dev.12",
|
|
22
24
|
"change-case": "^5.4.4",
|
|
23
25
|
"pathe": "^2.0.3"
|
|
24
26
|
},
|
|
25
27
|
"devDependencies": {
|
|
26
|
-
"@alloy-js/cli": "~0.22.0 || >= 0.23.0-dev.
|
|
28
|
+
"@alloy-js/cli": "~0.22.0 || >= 0.23.0-dev.4",
|
|
27
29
|
"@alloy-js/rollup-plugin": "~0.1.0 || >= 0.1.1-dev.1",
|
|
28
30
|
"@microsoft/api-extractor": "~7.52.8",
|
|
29
31
|
"@rollup/plugin-typescript": "^12.1.2",
|
|
@@ -34,7 +36,7 @@
|
|
|
34
36
|
"type": "module",
|
|
35
37
|
"scripts": {
|
|
36
38
|
"generate-docs": "api-extractor run",
|
|
37
|
-
"build": "alloy build && pnpm run generate-docs",
|
|
39
|
+
"build": "alloy build --with-dev && pnpm run generate-docs",
|
|
38
40
|
"clean": "rimraf dist/ .temp/",
|
|
39
41
|
"test:watch": "vitest -w",
|
|
40
42
|
"watch": "alloy build --watch",
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import { createPythonSymbol } from "../symbol-creation.js";
|
|
14
14
|
import { PythonOutputSymbol } from "../symbols/index.js";
|
|
15
15
|
import { Atom } from "./Atom.jsx";
|
|
16
|
+
import { TypeRefContext } from "./TypeRefContext.jsx";
|
|
16
17
|
|
|
17
18
|
export type ParameterMarker = "*" | "/";
|
|
18
19
|
|
|
@@ -75,7 +76,10 @@ function parameter(param: DeclaredParameterDescriptor) {
|
|
|
75
76
|
<group>
|
|
76
77
|
{param.symbol.name}
|
|
77
78
|
<Show when={!!param.type}>
|
|
78
|
-
:
|
|
79
|
+
:{" "}
|
|
80
|
+
<TypeRefContext>
|
|
81
|
+
<TypeSlot>{param.type}</TypeSlot>
|
|
82
|
+
</TypeRefContext>
|
|
79
83
|
</Show>
|
|
80
84
|
<Show when={param.default !== undefined}>
|
|
81
85
|
<Show when={!param.type}>=</Show>
|
|
@@ -184,7 +188,7 @@ export function CallSignature(props: CallSignatureProps) {
|
|
|
184
188
|
props.returnType ?
|
|
185
189
|
<>
|
|
186
190
|
{" -> "}
|
|
187
|
-
{props.returnType}
|
|
191
|
+
<TypeRefContext>{props.returnType}</TypeRefContext>
|
|
188
192
|
</>
|
|
189
193
|
: undefined;
|
|
190
194
|
|
|
@@ -6,6 +6,53 @@ export interface ImportStatementsProps {
|
|
|
6
6
|
joinImportsFromSameModule?: boolean;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
export interface CategorizedImports {
|
|
10
|
+
/** Imports used only in type annotation contexts (for TYPE_CHECKING block) */
|
|
11
|
+
typeImports: ImportRecords;
|
|
12
|
+
/** Regular imports used at runtime */
|
|
13
|
+
valueImports: ImportRecords;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Categorize import records into type-only and value imports.
|
|
18
|
+
* Type-only imports are those used only in type annotation contexts.
|
|
19
|
+
* Value imports are regular imports used at runtime.
|
|
20
|
+
*/
|
|
21
|
+
export function categorizeImportRecords(
|
|
22
|
+
records: ImportRecords,
|
|
23
|
+
): CategorizedImports {
|
|
24
|
+
const typeImports = new Map() as ImportRecords;
|
|
25
|
+
const valueImports = new Map() as ImportRecords;
|
|
26
|
+
|
|
27
|
+
for (const [module, properties] of records) {
|
|
28
|
+
if (!properties.symbols || properties.symbols.size === 0) {
|
|
29
|
+
// Module-level imports without symbols go to value imports
|
|
30
|
+
valueImports.set(module, properties);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const typeSymbols = new Set<ImportedSymbol>();
|
|
35
|
+
const valueSymbols = new Set<ImportedSymbol>();
|
|
36
|
+
|
|
37
|
+
for (const sym of properties.symbols) {
|
|
38
|
+
if (sym.local.isTypeOnly) {
|
|
39
|
+
typeSymbols.add(sym);
|
|
40
|
+
} else {
|
|
41
|
+
valueSymbols.add(sym);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (typeSymbols.size > 0) {
|
|
46
|
+
typeImports.set(module, { symbols: typeSymbols });
|
|
47
|
+
}
|
|
48
|
+
if (valueSymbols.size > 0) {
|
|
49
|
+
valueImports.set(module, { symbols: valueSymbols });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return { typeImports, valueImports };
|
|
54
|
+
}
|
|
55
|
+
|
|
9
56
|
/**
|
|
10
57
|
* A component that renders import statements based on the provided import records.
|
|
11
58
|
*
|
|
@@ -16,11 +63,11 @@ export interface ImportStatementsProps {
|
|
|
16
63
|
*/
|
|
17
64
|
export function ImportStatements(props: ImportStatementsProps) {
|
|
18
65
|
// Sort the import records by module name
|
|
19
|
-
const imports = computed(() =>
|
|
20
|
-
[...props.records].sort(([a], [b]) => {
|
|
66
|
+
const imports = computed(() => {
|
|
67
|
+
return [...props.records].sort(([a], [b]) => {
|
|
21
68
|
return a.name.localeCompare(b.name);
|
|
22
|
-
})
|
|
23
|
-
);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
24
71
|
|
|
25
72
|
return mapJoin(
|
|
26
73
|
() => imports.value,
|
|
@@ -45,7 +92,7 @@ export function ImportStatements(props: ImportStatementsProps) {
|
|
|
45
92
|
return sortedSymbols.map((symbol, idx, arr) => (
|
|
46
93
|
<>
|
|
47
94
|
<ImportStatement path={targetPath} symbols={new Set([symbol])} />
|
|
48
|
-
{idx < arr.length - 1 && <hbr />}
|
|
95
|
+
{/*@once*/ idx < arr.length - 1 && <hbr />}
|
|
49
96
|
</>
|
|
50
97
|
));
|
|
51
98
|
}
|
|
@@ -1,57 +1,126 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Children,
|
|
3
|
-
childrenArray,
|
|
4
3
|
computed,
|
|
4
|
+
createAccessExpression,
|
|
5
5
|
For,
|
|
6
|
-
isComponentCreator,
|
|
7
6
|
List,
|
|
8
7
|
OutputSymbol,
|
|
9
|
-
reactive,
|
|
10
|
-
ref,
|
|
11
8
|
Refkey,
|
|
12
9
|
Show,
|
|
13
|
-
takeSymbols,
|
|
14
|
-
ToRefs,
|
|
15
|
-
useBinder,
|
|
16
10
|
} from "@alloy-js/core";
|
|
17
11
|
|
|
18
12
|
export interface MemberExpressionProps {
|
|
19
13
|
children: Children;
|
|
20
14
|
}
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
type PartDescriptor = {
|
|
17
|
+
type: "call" | "subscription" | "attribute";
|
|
18
|
+
name: Children | undefined;
|
|
19
|
+
expression: Children | undefined;
|
|
20
|
+
quoted: boolean;
|
|
21
|
+
args: Children[] | undefined;
|
|
22
|
+
};
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
const exclusiveParts: (keyof MemberExpressionPartProps)[] = [
|
|
25
|
+
"args",
|
|
26
|
+
"refkey",
|
|
27
|
+
"symbol",
|
|
28
|
+
"id",
|
|
29
|
+
"key",
|
|
30
|
+
"keys",
|
|
31
|
+
"slice",
|
|
32
|
+
];
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
const { Expression, Part, registerOuterComponent } = createAccessExpression<
|
|
35
|
+
MemberExpressionPartProps,
|
|
36
|
+
PartDescriptor
|
|
37
|
+
>({
|
|
38
|
+
createDescriptor(partProps, sym, first) {
|
|
39
|
+
const foundProps = exclusiveParts.filter((key) => key in partProps);
|
|
40
|
+
if (foundProps.length > 1) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Only one of ${foundProps.join(", ")} can be used for a MemberExpression part at a time`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
38
45
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
// Validate slice syntax
|
|
47
|
+
if (partProps.slice) {
|
|
48
|
+
const { start, stop, step } = partProps.slice;
|
|
49
|
+
if (!start && !stop && !step) {
|
|
50
|
+
throw new Error("MemberExpression.Part: slice object cannot be empty");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
// Validate keys array
|
|
55
|
+
if (partProps.keys?.length === 0) {
|
|
56
|
+
throw new Error("MemberExpression.Part: keys array cannot be empty");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (partProps.args !== undefined) {
|
|
60
|
+
return {
|
|
61
|
+
type: "call" as const,
|
|
62
|
+
name: undefined,
|
|
63
|
+
expression: undefined,
|
|
64
|
+
quoted: false,
|
|
65
|
+
args: partProps.args === true ? [] : (partProps.args as Children[]),
|
|
66
|
+
};
|
|
67
|
+
} else if (
|
|
68
|
+
partProps.key !== undefined ||
|
|
69
|
+
partProps.keys !== undefined ||
|
|
70
|
+
partProps.slice !== undefined
|
|
71
|
+
) {
|
|
72
|
+
return {
|
|
73
|
+
type: "subscription" as const,
|
|
74
|
+
name: undefined,
|
|
75
|
+
expression: getSubscriptionValue(partProps),
|
|
76
|
+
quoted:
|
|
77
|
+
partProps.key !== undefined && typeof partProps.key === "string",
|
|
78
|
+
args: undefined,
|
|
79
|
+
};
|
|
80
|
+
} else {
|
|
81
|
+
let name: Children;
|
|
82
|
+
if (first && partProps.refkey) {
|
|
83
|
+
name = partProps.refkey;
|
|
84
|
+
} else if (partProps.id !== undefined) {
|
|
85
|
+
if (!isValidIdentifier(partProps.id)) {
|
|
86
|
+
throw new Error(`Invalid identifier: ${partProps.id}`);
|
|
87
|
+
}
|
|
88
|
+
name = partProps.id;
|
|
89
|
+
} else if (sym) {
|
|
90
|
+
name = sym.name;
|
|
91
|
+
} else {
|
|
92
|
+
name = "<unresolved symbol>";
|
|
93
|
+
}
|
|
50
94
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
95
|
+
return {
|
|
96
|
+
type: "attribute" as const,
|
|
97
|
+
name,
|
|
98
|
+
expression: undefined,
|
|
99
|
+
quoted: false,
|
|
100
|
+
args: undefined,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
getBase(part) {
|
|
106
|
+
if (part.type !== "attribute") {
|
|
107
|
+
throw new Error(
|
|
108
|
+
"The first part of a MemberExpression must be an id or refkey",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return part.name;
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
formatPart(part, _prevPart, _inCallChain) {
|
|
115
|
+
if (part.type === "call") {
|
|
116
|
+
return formatCallOutput(part);
|
|
117
|
+
} else if (part.type === "attribute") {
|
|
118
|
+
return formatAttributeOutput(part);
|
|
119
|
+
} else {
|
|
120
|
+
return formatSubscriptionOutput(part);
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
});
|
|
55
124
|
|
|
56
125
|
/**
|
|
57
126
|
* Create a member expression from parts. Each part can provide one of
|
|
@@ -83,237 +152,20 @@ type PartDescriptor =
|
|
|
83
152
|
* ```
|
|
84
153
|
*/
|
|
85
154
|
export function MemberExpression(props: MemberExpressionProps): Children {
|
|
86
|
-
|
|
87
|
-
const parts = childrenToPartDescriptors(children);
|
|
88
|
-
// any symbols emitted from the children won't be relevant to
|
|
89
|
-
// parent scopes. TODO: emit the proper symbol if we know it?
|
|
90
|
-
takeSymbols();
|
|
91
|
-
|
|
92
|
-
if (parts.length === 0) {
|
|
93
|
-
return <></>;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return computed(() => {
|
|
97
|
-
return formatChain(parts);
|
|
98
|
-
});
|
|
155
|
+
return Expression(props);
|
|
99
156
|
}
|
|
100
157
|
|
|
101
158
|
/**
|
|
102
|
-
*
|
|
103
|
-
|
|
104
|
-
function childrenToPartDescriptors(children: Children[]): PartDescriptor[] {
|
|
105
|
-
const parts: PartDescriptor[] = [];
|
|
106
|
-
for (const child of children) {
|
|
107
|
-
if (!isComponentCreator(child, MemberExpression.Part)) {
|
|
108
|
-
// we ignore non-parts
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
parts.push(
|
|
113
|
-
createPartDescriptorFromProps(child.props, child === children[0]),
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return parts;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const exclusiveParts: (keyof MemberExpressionPartProps)[] = [
|
|
121
|
-
"args",
|
|
122
|
-
"refkey",
|
|
123
|
-
"symbol",
|
|
124
|
-
"id",
|
|
125
|
-
"key",
|
|
126
|
-
"keys",
|
|
127
|
-
"slice",
|
|
128
|
-
];
|
|
129
|
-
/**
|
|
130
|
-
* Creates a reactive part descriptor from the given part props.
|
|
159
|
+
* A part of a member expression. Each part can provide one of the following
|
|
160
|
+
* props:
|
|
131
161
|
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
|
|
136
|
-
function createPartDescriptorFromProps(
|
|
137
|
-
partProps: MemberExpressionPartProps,
|
|
138
|
-
first: boolean,
|
|
139
|
-
) {
|
|
140
|
-
const foundProps = exclusiveParts.filter((key) => {
|
|
141
|
-
return key in partProps;
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
if (foundProps.length > 1) {
|
|
145
|
-
throw new Error(
|
|
146
|
-
`Only one of ${foundProps.join(", ")} can be used for a MemberExpression part at a time`,
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Validate slice syntax
|
|
151
|
-
if (partProps.slice) {
|
|
152
|
-
const { start, stop, step } = partProps.slice;
|
|
153
|
-
if (!start && !stop && !step) {
|
|
154
|
-
throw new Error("MemberExpression.Part: slice object cannot be empty");
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Validate keys array
|
|
159
|
-
if (partProps.keys?.length === 0) {
|
|
160
|
-
throw new Error("MemberExpression.Part: keys array cannot be empty");
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const symbolSource = computed(() => {
|
|
164
|
-
if (partProps.refkey) {
|
|
165
|
-
return getSymbolForRefkey(partProps.refkey).value;
|
|
166
|
-
} else if (partProps.symbol) {
|
|
167
|
-
return partProps.symbol;
|
|
168
|
-
} else {
|
|
169
|
-
return undefined;
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
// Return different descriptor types based on what props are provided
|
|
174
|
-
let part: ToRefs<PartDescriptor>;
|
|
175
|
-
if (partProps.args !== undefined) {
|
|
176
|
-
// CallDescriptor
|
|
177
|
-
part = {
|
|
178
|
-
type: computed(() => {
|
|
179
|
-
return "call" as const;
|
|
180
|
-
}),
|
|
181
|
-
args: ref<any>(partProps.args === true ? [] : partProps.args),
|
|
182
|
-
};
|
|
183
|
-
} else if (
|
|
184
|
-
partProps.key !== undefined ||
|
|
185
|
-
partProps.keys !== undefined ||
|
|
186
|
-
partProps.slice !== undefined
|
|
187
|
-
) {
|
|
188
|
-
// SubscriptionDescriptor
|
|
189
|
-
part = {
|
|
190
|
-
type: computed(() => {
|
|
191
|
-
return "subscription" as const;
|
|
192
|
-
}),
|
|
193
|
-
expression: computed(() => {
|
|
194
|
-
return getSubscriptionValue(partProps);
|
|
195
|
-
}),
|
|
196
|
-
quoted: computed(() => {
|
|
197
|
-
return partProps.key !== undefined && typeof partProps.key === "string";
|
|
198
|
-
}),
|
|
199
|
-
};
|
|
200
|
-
} else {
|
|
201
|
-
// IdentifierDescriptor
|
|
202
|
-
part = {
|
|
203
|
-
type: computed(() => {
|
|
204
|
-
return "attribute" as const;
|
|
205
|
-
}),
|
|
206
|
-
name: computed(() => {
|
|
207
|
-
if (first && partProps.refkey) {
|
|
208
|
-
return partProps.refkey;
|
|
209
|
-
} else if (partProps.id !== undefined) {
|
|
210
|
-
if (!isValidIdentifier(partProps.id)) {
|
|
211
|
-
throw new Error(`Invalid identifier: ${partProps.id}`);
|
|
212
|
-
}
|
|
213
|
-
return partProps.id;
|
|
214
|
-
} else if (symbolSource.value) {
|
|
215
|
-
return symbolSource.value.name;
|
|
216
|
-
} else {
|
|
217
|
-
return "<unresolved symbol>";
|
|
218
|
-
}
|
|
219
|
-
}),
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
return reactive(part);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Convert a refkey to a symbol ref using the current binder.
|
|
227
|
-
*/
|
|
228
|
-
function getSymbolForRefkey(refkey: Refkey) {
|
|
229
|
-
const binder = useBinder();
|
|
230
|
-
return binder!.getSymbolForRefkey(refkey);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Format a chain of parts into a MemberExpression.
|
|
235
|
-
*/
|
|
236
|
-
function formatChain(parts: PartDescriptor[]): Children {
|
|
237
|
-
return computed(() => {
|
|
238
|
-
const expression: Children[] = [];
|
|
239
|
-
|
|
240
|
-
for (let i = 0; i < parts.length; i++) {
|
|
241
|
-
const part = parts[i];
|
|
242
|
-
if (i === 0) {
|
|
243
|
-
if (!isAttributeDescriptor(part)) {
|
|
244
|
-
throw new Error(
|
|
245
|
-
"The first part of a MemberExpression must be an id or refkey",
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
expression.push(part.name);
|
|
249
|
-
} else {
|
|
250
|
-
if (isCallDescriptor(part)) {
|
|
251
|
-
expression.push(formatCallOutput(part));
|
|
252
|
-
} else if (isAttributeDescriptor(part)) {
|
|
253
|
-
expression.push(formatAttributeOutput(part));
|
|
254
|
-
} else if (isSubscriptionDescriptor(part)) {
|
|
255
|
-
expression.push(formatSubscriptionOutput(part));
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
return expression;
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Format a part of a member expression that is an array access.
|
|
266
|
-
* This is used for parts like `foo[0]` or `foo["bar"]`.
|
|
162
|
+
* * **id**: The identifier for the member expression part
|
|
163
|
+
* * **refkey**: A refkey for a symbol whose name becomes the identifier
|
|
164
|
+
* * **symbol**: a symbol whose name becomes the identifier part
|
|
165
|
+
* * **args**: create a method call with the given args
|
|
267
166
|
*/
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
<group>
|
|
271
|
-
{""}[
|
|
272
|
-
<indent>
|
|
273
|
-
<sbr />
|
|
274
|
-
{part.quoted && '"'}
|
|
275
|
-
{part.expression}
|
|
276
|
-
{part.quoted && '"'}
|
|
277
|
-
</indent>
|
|
278
|
-
<sbr />]
|
|
279
|
-
</group>
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function formatAttributeOutput(part: AttributeDescriptor) {
|
|
284
|
-
return (
|
|
285
|
-
<group>
|
|
286
|
-
<indent>
|
|
287
|
-
<ifBreak> \</ifBreak>
|
|
288
|
-
<sbr />
|
|
289
|
-
{"."}
|
|
290
|
-
{part.name}
|
|
291
|
-
</indent>
|
|
292
|
-
</group>
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
function formatCallOutput(part: CallDescriptor) {
|
|
297
|
-
const args = computed(() => {
|
|
298
|
-
return typeof part.args === "boolean" ? [] : (part.args ?? []);
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
return (
|
|
302
|
-
<group>
|
|
303
|
-
{""}(<Show when={args.value.length <= 1}>{args.value[0]}</Show>
|
|
304
|
-
<Show when={args.value.length > 1}>
|
|
305
|
-
<indent>
|
|
306
|
-
<sbr />
|
|
307
|
-
<For each={args} comma line>
|
|
308
|
-
{(arg) => arg}
|
|
309
|
-
</For>
|
|
310
|
-
</indent>
|
|
311
|
-
<sbr />
|
|
312
|
-
</Show>
|
|
313
|
-
)
|
|
314
|
-
</group>
|
|
315
|
-
);
|
|
316
|
-
}
|
|
167
|
+
MemberExpression.Part = Part;
|
|
168
|
+
registerOuterComponent(MemberExpression);
|
|
317
169
|
|
|
318
170
|
export interface MemberExpressionPartProps {
|
|
319
171
|
/**
|
|
@@ -359,43 +211,6 @@ export interface MemberExpressionPartProps {
|
|
|
359
211
|
*/
|
|
360
212
|
args?: Children[] | boolean;
|
|
361
213
|
}
|
|
362
|
-
/**
|
|
363
|
-
* A part of a member expression. Each part can provide one of the following
|
|
364
|
-
* props:
|
|
365
|
-
*
|
|
366
|
-
* * **id**: The identifier for the member expression part
|
|
367
|
-
* * **refkey**: A refkey for a symbol whose name becomes the identifier
|
|
368
|
-
* * **symbol**: a symbol whose name becomes the identifier part
|
|
369
|
-
* * **args**: create a method call with the given args
|
|
370
|
-
*/
|
|
371
|
-
MemberExpression.Part = function (props: MemberExpressionPartProps) {
|
|
372
|
-
/**
|
|
373
|
-
* This component does nothing except hold props which are retrieved by
|
|
374
|
-
* the `MemberExpression` component.
|
|
375
|
-
*/
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
function isValidIdentifier(id: Children) {
|
|
379
|
-
if (typeof id === "string" && id.includes('"')) {
|
|
380
|
-
return false;
|
|
381
|
-
}
|
|
382
|
-
return true;
|
|
383
|
-
}
|
|
384
|
-
function isCallDescriptor(part: PartDescriptor): part is CallDescriptor {
|
|
385
|
-
return "type" in part && part.type === MEMBER_ACCESS_TYPES.CALL;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
function isAttributeDescriptor(
|
|
389
|
-
part: PartDescriptor,
|
|
390
|
-
): part is AttributeDescriptor {
|
|
391
|
-
return "type" in part && part.type === MEMBER_ACCESS_TYPES.ATTRIBUTE;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
function isSubscriptionDescriptor(
|
|
395
|
-
part: PartDescriptor,
|
|
396
|
-
): part is SubscriptionDescriptor {
|
|
397
|
-
return "type" in part && part.type === MEMBER_ACCESS_TYPES.SUBSCRIPTION;
|
|
398
|
-
}
|
|
399
214
|
|
|
400
215
|
export interface SubscriptionProps {
|
|
401
216
|
/**
|
|
@@ -421,6 +236,67 @@ export interface SubscriptionProps {
|
|
|
421
236
|
};
|
|
422
237
|
}
|
|
423
238
|
|
|
239
|
+
// --- Formatting helpers ---
|
|
240
|
+
|
|
241
|
+
function formatSubscriptionOutput(part: PartDescriptor) {
|
|
242
|
+
return (
|
|
243
|
+
<group>
|
|
244
|
+
{""}[
|
|
245
|
+
<indent>
|
|
246
|
+
<sbr />
|
|
247
|
+
{part.quoted && '"'}
|
|
248
|
+
{part.expression}
|
|
249
|
+
{part.quoted && '"'}
|
|
250
|
+
</indent>
|
|
251
|
+
<sbr />]
|
|
252
|
+
</group>
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function formatAttributeOutput(part: PartDescriptor) {
|
|
257
|
+
return (
|
|
258
|
+
<group>
|
|
259
|
+
<indent>
|
|
260
|
+
<ifBreak> \</ifBreak>
|
|
261
|
+
<sbr />
|
|
262
|
+
{"."}
|
|
263
|
+
{part.name}
|
|
264
|
+
</indent>
|
|
265
|
+
</group>
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function formatCallOutput(part: PartDescriptor) {
|
|
270
|
+
const args = computed(() => {
|
|
271
|
+
return typeof part.args === "boolean" ? [] : (part.args ?? []);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
return (
|
|
275
|
+
<group>
|
|
276
|
+
{""}(<Show when={args.value.length <= 1}>{args.value[0]}</Show>
|
|
277
|
+
<Show when={args.value.length > 1}>
|
|
278
|
+
<indent>
|
|
279
|
+
<sbr />
|
|
280
|
+
<For each={args} comma line>
|
|
281
|
+
{(arg) => arg}
|
|
282
|
+
</For>
|
|
283
|
+
</indent>
|
|
284
|
+
<sbr />
|
|
285
|
+
</Show>
|
|
286
|
+
)
|
|
287
|
+
</group>
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// --- Utilities ---
|
|
292
|
+
|
|
293
|
+
function isValidIdentifier(id: Children) {
|
|
294
|
+
if (typeof id === "string" && id.includes('"')) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
|
|
424
300
|
function getSubscriptionValue(partProps: SubscriptionProps): Children {
|
|
425
301
|
// Handle tuple keys: obj[a, b] → (a, b)
|
|
426
302
|
if (partProps.keys?.length) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { computed, emitSymbol, Refkey } from "@alloy-js/core";
|
|
2
|
+
import { isTypeRefContext } from "../context/type-ref-context.js";
|
|
2
3
|
import { ref } from "../symbols/index.js";
|
|
3
4
|
|
|
4
5
|
export interface ReferenceProps {
|
|
@@ -13,7 +14,8 @@ export interface ReferenceProps {
|
|
|
13
14
|
* It takes a `refkey` prop which is the key of the symbol to reference.
|
|
14
15
|
*/
|
|
15
16
|
export function Reference({ refkey }: ReferenceProps) {
|
|
16
|
-
const
|
|
17
|
+
const inTypeRef = isTypeRefContext();
|
|
18
|
+
const reference = ref(refkey, { type: inTypeRef });
|
|
17
19
|
const symbolRef = computed(() => reference()[1]);
|
|
18
20
|
|
|
19
21
|
emitSymbol(symbolRef);
|