@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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
childrenArray,
|
|
3
3
|
ComponentContext,
|
|
4
|
+
computed,
|
|
4
5
|
SourceFile as CoreSourceFile,
|
|
5
6
|
createNamedContext,
|
|
6
7
|
createScope,
|
|
@@ -14,8 +15,12 @@ import {
|
|
|
14
15
|
} from "@alloy-js/core";
|
|
15
16
|
import { join } from "pathe";
|
|
16
17
|
import { PythonModuleScope } from "../symbols/index.js";
|
|
17
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
categorizeImportRecords,
|
|
20
|
+
ImportStatements,
|
|
21
|
+
} from "./ImportStatement.js";
|
|
18
22
|
import { SimpleCommentBlock } from "./PyDoc.js";
|
|
23
|
+
import { PythonBlock } from "./PythonBlock.js";
|
|
19
24
|
import { Reference } from "./Reference.js";
|
|
20
25
|
|
|
21
26
|
// Non top-level definitions
|
|
@@ -99,7 +104,7 @@ export interface SourceFileProps {
|
|
|
99
104
|
/**
|
|
100
105
|
* __future__ imports to render after the docstring but before regular imports.
|
|
101
106
|
*/
|
|
102
|
-
futureImports?: Children;
|
|
107
|
+
futureImports?: Children[];
|
|
103
108
|
}
|
|
104
109
|
|
|
105
110
|
/**
|
|
@@ -167,6 +172,28 @@ export function SourceFile(props: SourceFileProps) {
|
|
|
167
172
|
props.doc !== undefined ||
|
|
168
173
|
props.futureImports !== undefined;
|
|
169
174
|
|
|
175
|
+
const imports = computed(() => {
|
|
176
|
+
// Quick scan for any type-only imports
|
|
177
|
+
const hasTypeImports = [...scope.importedModules.values()].some(
|
|
178
|
+
(props) =>
|
|
179
|
+
props.symbols && [...props.symbols].some((s) => s.local.isTypeOnly),
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
// Add TYPE_CHECKING before categorizing so it's naturally included
|
|
183
|
+
const typeImportSymbol = hasTypeImports ? scope.addTypeImport() : undefined;
|
|
184
|
+
|
|
185
|
+
// Single categorize - TYPE_CHECKING is already in scope.importedModules
|
|
186
|
+
const { valueImports, typeImports } = categorizeImportRecords(
|
|
187
|
+
scope.importedModules,
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
valueImports,
|
|
192
|
+
typeImports,
|
|
193
|
+
typeImportSymbol,
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
|
|
170
197
|
return (
|
|
171
198
|
<CoreSourceFile
|
|
172
199
|
path={props.path}
|
|
@@ -216,12 +243,21 @@ export function SourceFile(props: SourceFileProps) {
|
|
|
216
243
|
<hbr />
|
|
217
244
|
</Show>
|
|
218
245
|
</Show>
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
<
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
246
|
+
{/* Regular (non-type-only) imports */}
|
|
247
|
+
<Show when={imports.value.valueImports.size > 0}>
|
|
248
|
+
<ImportStatements records={imports.value.valueImports} />
|
|
249
|
+
<hbr />
|
|
250
|
+
</Show>
|
|
251
|
+
{/* TYPE_CHECKING block with type-only imports */}
|
|
252
|
+
<Show when={imports.value.typeImports.size > 0}>
|
|
253
|
+
<hbr />
|
|
254
|
+
<PythonBlock opener={`if ${imports.value.typeImportSymbol!.name}:`}>
|
|
255
|
+
<ImportStatements records={imports.value.typeImports} />
|
|
256
|
+
</PythonBlock>
|
|
257
|
+
</Show>
|
|
258
|
+
{/* Spacing after imports */}
|
|
259
|
+
<Show when={hasChildren && scope.importedModules.size > 0}>
|
|
260
|
+
<hbr />
|
|
225
261
|
</Show>
|
|
226
262
|
{/* Extra blank line before top-level definitions */}
|
|
227
263
|
<Show
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Children } from "@alloy-js/core";
|
|
2
|
+
import {
|
|
3
|
+
isTypeRefContext,
|
|
4
|
+
TypeRefContextDef,
|
|
5
|
+
} from "../context/type-ref-context.js";
|
|
6
|
+
|
|
7
|
+
// Re-export for external use
|
|
8
|
+
export { isTypeRefContext };
|
|
9
|
+
|
|
10
|
+
export interface TypeRefContextProps {
|
|
11
|
+
/**
|
|
12
|
+
* Children
|
|
13
|
+
*/
|
|
14
|
+
children: Children;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Set the current context of reference to be type reference.
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* References used inside the children of this component will be treated as
|
|
22
|
+
* type-only references. When a symbol is only referenced in type contexts,
|
|
23
|
+
* it will be imported inside a `if TYPE_CHECKING:` block.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* <TypeRefContext>
|
|
28
|
+
* {someTypeRefkey}
|
|
29
|
+
* </TypeRefContext>
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export const TypeRefContext = ({ children }: TypeRefContextProps) => {
|
|
33
|
+
return (
|
|
34
|
+
<TypeRefContextDef.Provider value>{children}</TypeRefContextDef.Provider>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Children, Refkey, Show } from "@alloy-js/core";
|
|
2
2
|
import { TypeArguments } from "./TypeArguments.js";
|
|
3
|
+
import { TypeRefContext } from "./TypeRefContext.js";
|
|
3
4
|
|
|
4
5
|
export interface TypeReferenceProps {
|
|
5
6
|
/** A refkey to a declared symbol. */
|
|
@@ -12,6 +13,11 @@ export interface TypeReferenceProps {
|
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* A type reference like Foo[T, P] or int.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* This component automatically wraps its content in a type reference context,
|
|
19
|
+
* so any symbols referenced via refkey will be imported as type-only
|
|
20
|
+
* (inside a `if TYPE_CHECKING:` block) unless also used as values elsewhere.
|
|
15
21
|
*/
|
|
16
22
|
export function TypeReference(props: TypeReferenceProps) {
|
|
17
23
|
const type = props.refkey ? props.refkey : props.name;
|
|
@@ -21,13 +27,15 @@ export function TypeReference(props: TypeReferenceProps) {
|
|
|
21
27
|
: undefined;
|
|
22
28
|
|
|
23
29
|
return (
|
|
24
|
-
<
|
|
25
|
-
<
|
|
30
|
+
<TypeRefContext>
|
|
31
|
+
<group>
|
|
32
|
+
<indent>
|
|
33
|
+
<sbr />
|
|
34
|
+
{type}
|
|
35
|
+
<Show when={Boolean(typeArgs)}>{typeArgs}</Show>
|
|
36
|
+
</indent>
|
|
26
37
|
<sbr />
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
</indent>
|
|
30
|
-
<sbr />
|
|
31
|
-
</group>
|
|
38
|
+
</group>
|
|
39
|
+
</TypeRefContext>
|
|
32
40
|
);
|
|
33
41
|
}
|
|
@@ -10,6 +10,7 @@ import { createPythonSymbol } from "../symbol-creation.js";
|
|
|
10
10
|
import { Atom } from "./Atom.jsx";
|
|
11
11
|
import { BaseDeclarationProps } from "./Declaration.jsx";
|
|
12
12
|
import { SimpleCommentBlock } from "./PyDoc.jsx";
|
|
13
|
+
import { TypeRefContext } from "./TypeRefContext.jsx";
|
|
13
14
|
|
|
14
15
|
export interface VariableDeclarationProps extends BaseDeclarationProps {
|
|
15
16
|
/**
|
|
@@ -93,7 +94,10 @@ export function VariableDeclaration(props: VariableDeclarationProps) {
|
|
|
93
94
|
if (!props.type || props.callStatementVar) return undefined;
|
|
94
95
|
return (
|
|
95
96
|
<>
|
|
96
|
-
:
|
|
97
|
+
:{" "}
|
|
98
|
+
<TypeRefContext>
|
|
99
|
+
<TypeSymbolSlot>{props.type}</TypeSymbolSlot>
|
|
100
|
+
</TypeRefContext>
|
|
97
101
|
</>
|
|
98
102
|
);
|
|
99
103
|
});
|
package/src/components/index.ts
CHANGED
|
@@ -13,7 +13,6 @@ export type { CommonFunctionProps } from "./FunctionBase.js";
|
|
|
13
13
|
export * from "./FunctionCallExpression.js";
|
|
14
14
|
export * from "./FunctionDeclaration.js";
|
|
15
15
|
export * from "./FutureStatement.js";
|
|
16
|
-
export * from "./ImportStatement.js";
|
|
17
16
|
export * from "./LexicalScope.js";
|
|
18
17
|
export * from "./MemberExpression.js";
|
|
19
18
|
export * from "./MemberScope.jsx";
|
|
@@ -27,6 +26,7 @@ export * from "./SourceFile.js";
|
|
|
27
26
|
export * from "./StatementList.js";
|
|
28
27
|
export * from "./StaticMethodDeclaration.js";
|
|
29
28
|
export * from "./TypeArguments.js";
|
|
29
|
+
export * from "./TypeRefContext.js";
|
|
30
30
|
export * from "./TypeReference.js";
|
|
31
31
|
export * from "./UnionTypeExpression.js";
|
|
32
32
|
export * from "./VariableDeclaration.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./type-ref-context.js";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ComponentContext, createContext, useContext } from "@alloy-js/core";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Context for tracking whether we are in a type annotation position.
|
|
5
|
+
* Used to determine if imports should be guarded with TYPE_CHECKING.
|
|
6
|
+
*
|
|
7
|
+
* @internal Use the TypeRefContext component instead.
|
|
8
|
+
*/
|
|
9
|
+
export const TypeRefContextDef: ComponentContext<true> = createContext<true>();
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @returns 'true' if in a type context, 'false' if in a value context.
|
|
13
|
+
*/
|
|
14
|
+
export function isTypeRefContext(): boolean {
|
|
15
|
+
return useContext(TypeRefContextDef) === true;
|
|
16
|
+
}
|
|
@@ -2,6 +2,30 @@ import { createSymbol, reactive, shallowReactive } from "@alloy-js/core";
|
|
|
2
2
|
import { PythonLexicalScope } from "./python-lexical-scope.js";
|
|
3
3
|
import { PythonOutputSymbol } from "./python-output-symbol.js";
|
|
4
4
|
|
|
5
|
+
// Internal typing module for TYPE_CHECKING imports
|
|
6
|
+
let _typingModuleScope: PythonModuleScope | undefined;
|
|
7
|
+
let _typeCheckingSymbol: PythonOutputSymbol | undefined;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get the internal typing module scope and TYPE_CHECKING symbol.
|
|
11
|
+
* Used by addTypeImport() to add TYPE_CHECKING imports without
|
|
12
|
+
* going through the binder's refkey resolution.
|
|
13
|
+
*/
|
|
14
|
+
function getTypingModuleInternal(): {
|
|
15
|
+
scope: PythonModuleScope;
|
|
16
|
+
TYPE_CHECKING: PythonOutputSymbol;
|
|
17
|
+
} {
|
|
18
|
+
if (!_typingModuleScope) {
|
|
19
|
+
_typingModuleScope = new PythonModuleScope("typing", undefined);
|
|
20
|
+
_typeCheckingSymbol = new PythonOutputSymbol(
|
|
21
|
+
"TYPE_CHECKING",
|
|
22
|
+
_typingModuleScope.symbols,
|
|
23
|
+
{},
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return { scope: _typingModuleScope, TYPE_CHECKING: _typeCheckingSymbol! };
|
|
27
|
+
}
|
|
28
|
+
|
|
5
29
|
export class ImportedSymbol {
|
|
6
30
|
local: PythonOutputSymbol;
|
|
7
31
|
target: PythonOutputSymbol;
|
|
@@ -22,6 +46,14 @@ export interface ImportRecordProps {
|
|
|
22
46
|
|
|
23
47
|
export class ImportRecords extends Map<PythonModuleScope, ImportRecordProps> {}
|
|
24
48
|
|
|
49
|
+
export interface AddImportOptions {
|
|
50
|
+
/**
|
|
51
|
+
* If true, this import is only used in type annotation contexts.
|
|
52
|
+
* Such imports will be guarded with `if TYPE_CHECKING:`.
|
|
53
|
+
*/
|
|
54
|
+
type?: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
25
57
|
export class PythonModuleScope extends PythonLexicalScope {
|
|
26
58
|
#importedSymbols: Map<PythonOutputSymbol, PythonOutputSymbol> =
|
|
27
59
|
shallowReactive(new Map());
|
|
@@ -34,9 +66,17 @@ export class PythonModuleScope extends PythonLexicalScope {
|
|
|
34
66
|
return this.#importedModules;
|
|
35
67
|
}
|
|
36
68
|
|
|
37
|
-
addImport(
|
|
69
|
+
addImport(
|
|
70
|
+
targetSymbol: PythonOutputSymbol,
|
|
71
|
+
targetModule: PythonModuleScope,
|
|
72
|
+
options?: AddImportOptions,
|
|
73
|
+
) {
|
|
38
74
|
const existing = this.importedSymbols.get(targetSymbol);
|
|
39
75
|
if (existing) {
|
|
76
|
+
// If existing is type-only but now used as value, upgrade it
|
|
77
|
+
if (!options?.type && existing.isTypeOnly) {
|
|
78
|
+
existing.markAsValue();
|
|
79
|
+
}
|
|
40
80
|
return existing;
|
|
41
81
|
}
|
|
42
82
|
|
|
@@ -50,7 +90,11 @@ export class PythonModuleScope extends PythonLexicalScope {
|
|
|
50
90
|
PythonOutputSymbol,
|
|
51
91
|
targetSymbol.name,
|
|
52
92
|
this.symbols,
|
|
53
|
-
{
|
|
93
|
+
{
|
|
94
|
+
binder: this.binder,
|
|
95
|
+
aliasTarget: targetSymbol,
|
|
96
|
+
typeOnly: options?.type,
|
|
97
|
+
},
|
|
54
98
|
);
|
|
55
99
|
|
|
56
100
|
this.importedSymbols.set(targetSymbol, localSymbol);
|
|
@@ -62,6 +106,15 @@ export class PythonModuleScope extends PythonLexicalScope {
|
|
|
62
106
|
return localSymbol;
|
|
63
107
|
}
|
|
64
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Add TYPE_CHECKING import from the typing module.
|
|
111
|
+
* Returns the local symbol for use in the if block opener.
|
|
112
|
+
*/
|
|
113
|
+
addTypeImport(): PythonOutputSymbol {
|
|
114
|
+
const typing = getTypingModuleInternal();
|
|
115
|
+
return this.addImport(typing.TYPE_CHECKING, typing.scope);
|
|
116
|
+
}
|
|
117
|
+
|
|
65
118
|
override get debugInfo(): Record<string, unknown> {
|
|
66
119
|
return {
|
|
67
120
|
...super.debugInfo,
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
|
+
createSymbol,
|
|
2
3
|
Namekey,
|
|
3
4
|
OutputSpace,
|
|
4
5
|
OutputSymbol,
|
|
5
6
|
OutputSymbolOptions,
|
|
6
|
-
|
|
7
|
+
track,
|
|
8
|
+
TrackOpTypes,
|
|
9
|
+
trigger,
|
|
10
|
+
TriggerOpTypes,
|
|
7
11
|
} from "@alloy-js/core";
|
|
8
12
|
|
|
9
13
|
export interface PythonOutputSymbolOptions extends OutputSymbolOptions {
|
|
10
14
|
module?: string;
|
|
15
|
+
/** Whether this symbol is only used in type annotation contexts */
|
|
16
|
+
typeOnly?: boolean;
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
export interface CreatePythonSymbolFunctionOptions
|
|
@@ -28,6 +34,7 @@ export class PythonOutputSymbol extends OutputSymbol {
|
|
|
28
34
|
) {
|
|
29
35
|
super(name, spaces, options);
|
|
30
36
|
this.#module = options.module ?? undefined;
|
|
37
|
+
this.#typeOnly = options.typeOnly ?? false;
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
// The module in which the symbol is defined
|
|
@@ -37,6 +44,29 @@ export class PythonOutputSymbol extends OutputSymbol {
|
|
|
37
44
|
return this.#module;
|
|
38
45
|
}
|
|
39
46
|
|
|
47
|
+
#typeOnly: boolean;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Returns true if this symbol is only used in type annotation contexts.
|
|
51
|
+
* Such symbols can be imported inside a TYPE_CHECKING block.
|
|
52
|
+
*/
|
|
53
|
+
get isTypeOnly() {
|
|
54
|
+
track(this, TrackOpTypes.GET, "typeOnly");
|
|
55
|
+
return this.#typeOnly;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Mark this symbol as also being used as a value (not just a type).
|
|
60
|
+
*/
|
|
61
|
+
markAsValue() {
|
|
62
|
+
if (!this.#typeOnly) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const oldValue = this.#typeOnly;
|
|
66
|
+
this.#typeOnly = false;
|
|
67
|
+
trigger(this, TriggerOpTypes.SET, "typeOnly", false, oldValue);
|
|
68
|
+
}
|
|
69
|
+
|
|
40
70
|
get staticMembers() {
|
|
41
71
|
return this.memberSpaceFor("static")!;
|
|
42
72
|
}
|
|
@@ -69,6 +99,7 @@ export class PythonOutputSymbol extends OutputSymbol {
|
|
|
69
99
|
aliasTarget: this.aliasTarget,
|
|
70
100
|
module: this.module,
|
|
71
101
|
metadata: this.metadata,
|
|
102
|
+
typeOnly: this.isTypeOnly,
|
|
72
103
|
});
|
|
73
104
|
|
|
74
105
|
this.initializeCopy(copy);
|
|
@@ -13,8 +13,17 @@ import { PythonModuleScope } from "./python-module-scope.js";
|
|
|
13
13
|
import { PythonOutputSymbol } from "./python-output-symbol.js";
|
|
14
14
|
import { PythonOutputScope } from "./scopes.js";
|
|
15
15
|
|
|
16
|
+
export interface RefOptions {
|
|
17
|
+
/**
|
|
18
|
+
* If true, this reference is only used in a type annotation context.
|
|
19
|
+
* The import will be guarded with `if TYPE_CHECKING:`.
|
|
20
|
+
*/
|
|
21
|
+
type?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
export function ref(
|
|
17
25
|
refkey: Refkey,
|
|
26
|
+
options?: RefOptions,
|
|
18
27
|
): () => [Children, PythonOutputSymbol | undefined] {
|
|
19
28
|
const sourceFile = useContext(PythonSourceFileContext);
|
|
20
29
|
const resolveResult = resolve<PythonOutputScope, PythonOutputSymbol>(
|
|
@@ -41,6 +50,7 @@ export function ref(
|
|
|
41
50
|
sourceFile!.scope.addImport(
|
|
42
51
|
lexicalDeclaration,
|
|
43
52
|
pathDown[0] as PythonModuleScope,
|
|
53
|
+
{ type: options?.type },
|
|
44
54
|
),
|
|
45
55
|
);
|
|
46
56
|
}
|