@alloy-js/python 0.1.0-dev.4 → 0.1.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/src/components/CallSignature.d.ts.map +1 -1
- package/dist/src/components/CallSignature.js +8 -11
- package/dist/src/components/ClassDeclaration.d.ts.map +1 -1
- package/dist/src/components/ClassDeclaration.js +6 -20
- package/dist/src/components/ClassInstantiation.d.ts.map +1 -1
- package/dist/src/components/ClassInstantiation.js +4 -4
- package/dist/src/components/Declaration.d.ts +1 -5
- package/dist/src/components/Declaration.d.ts.map +1 -1
- package/dist/src/components/Declaration.js +6 -15
- package/dist/src/components/EnumDeclaration.d.ts.map +1 -1
- package/dist/src/components/EnumDeclaration.js +33 -59
- package/dist/src/components/EnumMember.d.ts.map +1 -1
- package/dist/src/components/EnumMember.js +3 -4
- package/dist/src/components/FunctionDeclaration.d.ts.map +1 -1
- package/dist/src/components/FunctionDeclaration.js +6 -15
- package/dist/src/components/LexicalScope.d.ts +8 -0
- package/dist/src/components/LexicalScope.d.ts.map +1 -0
- package/dist/src/components/LexicalScope.js +21 -0
- package/dist/src/components/MemberScope.d.ts +8 -0
- package/dist/src/components/MemberScope.d.ts.map +1 -0
- package/dist/src/components/MemberScope.js +15 -0
- package/dist/src/components/SourceFile.js +1 -2
- package/dist/src/components/VariableDeclaration.d.ts.map +1 -1
- package/dist/src/components/VariableDeclaration.js +8 -31
- package/dist/src/components/index.d.ts +2 -0
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +2 -0
- package/dist/src/create-module.d.ts.map +1 -1
- package/dist/src/create-module.js +3 -4
- package/dist/src/name-conflict-resolver.d.ts +3 -0
- package/dist/src/name-conflict-resolver.d.ts.map +1 -0
- package/dist/src/name-conflict-resolver.js +7 -0
- package/dist/src/symbol-creation.d.ts +13 -2
- package/dist/src/symbol-creation.d.ts.map +1 -1
- package/dist/src/symbol-creation.js +33 -9
- package/dist/src/symbols/index.d.ts +1 -1
- package/dist/src/symbols/index.d.ts.map +1 -1
- package/dist/src/symbols/index.js +1 -1
- package/dist/src/symbols/python-lexical-scope.d.ts +7 -0
- package/dist/src/symbols/python-lexical-scope.d.ts.map +1 -0
- package/dist/src/symbols/python-lexical-scope.js +14 -0
- package/dist/src/symbols/python-member-scope.d.ts +3 -4
- package/dist/src/symbols/python-member-scope.d.ts.map +1 -1
- package/dist/src/symbols/python-member-scope.js +4 -7
- package/dist/src/symbols/python-module-scope.d.ts +4 -9
- package/dist/src/symbols/python-module-scope.d.ts.map +1 -1
- package/dist/src/symbols/python-module-scope.js +6 -14
- package/dist/src/symbols/python-output-symbol.d.ts +10 -7
- package/dist/src/symbols/python-output-symbol.d.ts.map +1 -1
- package/dist/src/symbols/python-output-symbol.js +23 -6
- package/dist/src/symbols/reference.d.ts +2 -2
- package/dist/src/symbols/reference.d.ts.map +1 -1
- package/dist/src/symbols/reference.js +36 -36
- package/dist/src/symbols/scopes.d.ts +3 -1
- package/dist/src/symbols/scopes.d.ts.map +1 -1
- package/dist/src/symbols/scopes.js +8 -0
- package/dist/test/classdeclarations.test.js +87 -52
- package/dist/test/enums.test.js +8 -2
- package/dist/test/externals.test.js +6 -5
- package/dist/test/functiondeclaration.test.js +73 -36
- package/dist/test/imports.test.js +9 -36
- package/dist/test/utils.d.ts +2 -3
- package/dist/test/utils.d.ts.map +1 -1
- package/dist/test/utils.js +3 -2
- package/dist/test/variables.test.js +11 -11
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/components/CallSignature.tsx +9 -17
- package/src/components/ClassDeclaration.tsx +5 -32
- package/src/components/ClassInstantiation.tsx +6 -12
- package/src/components/Declaration.tsx +1 -20
- package/src/components/EnumDeclaration.tsx +18 -41
- package/src/components/EnumMember.tsx +1 -3
- package/src/components/FunctionDeclaration.tsx +5 -24
- package/src/components/LexicalScope.tsx +24 -0
- package/src/components/MemberScope.tsx +18 -0
- package/src/components/SourceFile.tsx +2 -2
- package/src/components/VariableDeclaration.tsx +7 -35
- package/src/components/index.ts +2 -0
- package/src/create-module.ts +7 -13
- package/src/name-conflict-resolver.ts +21 -0
- package/src/symbol-creation.ts +50 -11
- package/src/symbols/index.ts +1 -1
- package/src/symbols/python-lexical-scope.ts +16 -0
- package/src/symbols/python-member-scope.ts +4 -8
- package/src/symbols/python-module-scope.ts +6 -32
- package/src/symbols/python-output-symbol.ts +36 -10
- package/src/symbols/reference.tsx +70 -0
- package/src/symbols/scopes.ts +15 -1
- package/temp/api.json +897 -539
- package/test/classdeclarations.test.tsx +66 -31
- package/test/enums.test.tsx +2 -2
- package/test/externals.test.tsx +6 -7
- package/test/functiondeclaration.test.tsx +48 -39
- package/test/imports.test.tsx +11 -36
- package/test/utils.tsx +9 -5
- package/test/variables.test.tsx +11 -7
- package/dist/src/symbols/custom-output-scope.d.ts +0 -10
- package/dist/src/symbols/custom-output-scope.d.ts.map +0 -1
- package/dist/src/symbols/custom-output-scope.js +0 -25
- package/src/symbols/custom-output-scope.ts +0 -35
- package/src/symbols/reference.ts +0 -99
package/src/symbol-creation.ts
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
OutputScopeOptions,
|
|
3
|
+
OutputSpace,
|
|
4
|
+
useBinder,
|
|
5
|
+
useContext,
|
|
6
|
+
} from "@alloy-js/core";
|
|
2
7
|
import { PythonSourceFileContext } from "./components/SourceFile.js";
|
|
3
8
|
import { PythonElements, usePythonNamePolicy } from "./name-policy.js";
|
|
4
9
|
import {
|
|
5
|
-
CreatePythonSymbolOptions,
|
|
6
10
|
PythonOutputSymbol,
|
|
11
|
+
PythonOutputSymbolOptions,
|
|
12
|
+
usePythonScope,
|
|
7
13
|
} from "./symbols/index.js";
|
|
14
|
+
import { PythonLexicalScope } from "./symbols/python-lexical-scope.js";
|
|
8
15
|
|
|
16
|
+
interface CreatePythonSymbolOptions extends PythonOutputSymbolOptions {
|
|
17
|
+
space?: OutputSpace;
|
|
18
|
+
instance?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Creates a symbol for a python declaration in the current scope.
|
|
22
|
+
*/
|
|
9
23
|
export function createPythonSymbol(
|
|
10
24
|
name: string,
|
|
11
|
-
options: CreatePythonSymbolOptions,
|
|
25
|
+
options: CreatePythonSymbolOptions = {},
|
|
12
26
|
kind?: PythonElements,
|
|
13
|
-
createRefkeyIfNeeded = false,
|
|
14
27
|
): PythonOutputSymbol {
|
|
15
28
|
let processedName = name;
|
|
16
29
|
const sfContext = useContext(PythonSourceFileContext);
|
|
@@ -21,16 +34,42 @@ export function createPythonSymbol(
|
|
|
21
34
|
processedName = namePolicy.getName(name, kind);
|
|
22
35
|
}
|
|
23
36
|
}
|
|
37
|
+
const currentScope = usePythonScope();
|
|
38
|
+
let targetSpace = options.space ?? undefined;
|
|
39
|
+
if (!options.space && currentScope) {
|
|
40
|
+
if (currentScope.isMemberScope) {
|
|
41
|
+
if (options.instance) {
|
|
42
|
+
targetSpace = currentScope.ownerSymbol!.instanceMembers;
|
|
43
|
+
} else {
|
|
44
|
+
targetSpace = currentScope.ownerSymbol!.staticMembers;
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
if (options.instance) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`Cannot declare instance variable ${name} outside of a member scope`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
targetSpace = (currentScope as PythonLexicalScope).symbols;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const binder = options.binder ?? currentScope?.binder ?? useBinder();
|
|
24
57
|
|
|
25
|
-
return new PythonOutputSymbol(processedName, {
|
|
26
|
-
binder:
|
|
58
|
+
return new PythonOutputSymbol(processedName, targetSpace, {
|
|
59
|
+
binder: binder,
|
|
27
60
|
aliasTarget: options.aliasTarget,
|
|
28
|
-
|
|
29
|
-
refkeys:
|
|
30
|
-
options.refkeys ??
|
|
31
|
-
(createRefkeyIfNeeded ? refkey(processedName) : undefined),
|
|
32
|
-
flags: options.flags,
|
|
61
|
+
refkeys: options.refkeys,
|
|
33
62
|
metadata: options.metadata,
|
|
34
63
|
module: sfContext?.module,
|
|
64
|
+
type: options.type,
|
|
35
65
|
});
|
|
36
66
|
}
|
|
67
|
+
|
|
68
|
+
export function createLexicalScope(
|
|
69
|
+
name: string,
|
|
70
|
+
options: OutputScopeOptions = {},
|
|
71
|
+
) {
|
|
72
|
+
const parent = usePythonScope();
|
|
73
|
+
|
|
74
|
+
return new PythonLexicalScope(name, parent, options);
|
|
75
|
+
}
|
package/src/symbols/index.ts
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OutputScope } from "@alloy-js/core";
|
|
2
|
+
|
|
3
|
+
export class PythonLexicalScope extends OutputScope {
|
|
4
|
+
public static readonly declarationSpaces: readonly string[] = ["symbols"];
|
|
5
|
+
|
|
6
|
+
get symbols() {
|
|
7
|
+
return this.spaceFor("symbols")!;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Lexical scopes do not have an owner symbol. This ensures that we get the
|
|
11
|
+
// correct type when using `usePythonScope` (i.e. we don't get the
|
|
12
|
+
// OutputScope's `OutputSymbol | undefined` type).
|
|
13
|
+
get ownerSymbol(): undefined {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OutputScope } from "@alloy-js/core";
|
|
2
2
|
import { PythonOutputSymbol } from "./python-output-symbol.js";
|
|
3
3
|
|
|
4
|
-
export class PythonMemberScope extends
|
|
5
|
-
get
|
|
6
|
-
return
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
get owner() {
|
|
10
|
-
return super.owner as PythonOutputSymbol;
|
|
4
|
+
export class PythonMemberScope extends OutputScope {
|
|
5
|
+
get ownerSymbol() {
|
|
6
|
+
return super.ownerSymbol as PythonOutputSymbol;
|
|
11
7
|
}
|
|
12
8
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { reactive, shallowReactive } from "@alloy-js/core";
|
|
2
|
-
import {
|
|
3
|
-
import { CustomOutputScope } from "./custom-output-scope.js";
|
|
2
|
+
import { PythonLexicalScope } from "./python-lexical-scope.js";
|
|
4
3
|
import { PythonOutputSymbol } from "./python-output-symbol.js";
|
|
5
4
|
|
|
6
5
|
export class ImportedSymbol {
|
|
@@ -21,23 +20,9 @@ export interface ImportRecordProps {
|
|
|
21
20
|
symbols: Set<ImportedSymbol>;
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
export const ImportRecords = Map as {
|
|
27
|
-
new (): ImportRecords;
|
|
28
|
-
new (
|
|
29
|
-
entries?:
|
|
30
|
-
| readonly (readonly [PythonModuleScope, ImportRecordProps])[]
|
|
31
|
-
| null,
|
|
32
|
-
): ImportRecords;
|
|
33
|
-
prototype: Map<PythonModuleScope, ImportRecordProps>;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export class PythonModuleScope extends CustomOutputScope {
|
|
37
|
-
get kind() {
|
|
38
|
-
return "module" as const;
|
|
39
|
-
}
|
|
23
|
+
export class ImportRecords extends Map<PythonModuleScope, ImportRecordProps> {}
|
|
40
24
|
|
|
25
|
+
export class PythonModuleScope extends PythonLexicalScope {
|
|
41
26
|
#importedSymbols: Map<PythonOutputSymbol, PythonOutputSymbol> =
|
|
42
27
|
shallowReactive(new Map());
|
|
43
28
|
get importedSymbols() {
|
|
@@ -55,29 +40,18 @@ export class PythonModuleScope extends CustomOutputScope {
|
|
|
55
40
|
return existing;
|
|
56
41
|
}
|
|
57
42
|
|
|
58
|
-
if (targetModule.kind !== "module") {
|
|
59
|
-
throw new Error("Cannot import symbol that isn't in module scope");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
43
|
if (!this.importedModules.has(targetModule)) {
|
|
63
44
|
this.importedModules.set(targetModule, {
|
|
64
45
|
symbols: new Set<ImportedSymbol>(),
|
|
65
46
|
});
|
|
66
47
|
}
|
|
67
48
|
|
|
68
|
-
const localSymbol =
|
|
49
|
+
const localSymbol = new PythonOutputSymbol(
|
|
69
50
|
targetSymbol.name,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
scope: this,
|
|
73
|
-
aliasTarget: targetSymbol,
|
|
74
|
-
},
|
|
75
|
-
undefined,
|
|
76
|
-
false,
|
|
51
|
+
this.symbols,
|
|
52
|
+
{ binder: this.binder, aliasTarget: targetSymbol },
|
|
77
53
|
);
|
|
78
54
|
|
|
79
|
-
targetSymbol.copyTo(localSymbol);
|
|
80
|
-
|
|
81
55
|
this.importedSymbols.set(targetSymbol, localSymbol);
|
|
82
56
|
this.importedModules.get(targetModule)!.symbols?.add({
|
|
83
57
|
local: localSymbol,
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { OutputSymbol, OutputSymbolOptions } from "@alloy-js/core";
|
|
2
|
-
import { PythonMemberScope } from "./python-member-scope.js";
|
|
1
|
+
import { OutputSpace, OutputSymbol, OutputSymbolOptions } from "@alloy-js/core";
|
|
3
2
|
|
|
4
|
-
export interface
|
|
3
|
+
export interface PythonOutputSymbolOptions extends OutputSymbolOptions {
|
|
5
4
|
module?: string;
|
|
6
5
|
}
|
|
7
6
|
|
|
8
7
|
export interface CreatePythonSymbolFunctionOptions
|
|
9
|
-
extends
|
|
8
|
+
extends PythonOutputSymbolOptions {
|
|
10
9
|
name: string;
|
|
11
10
|
}
|
|
12
11
|
|
|
@@ -14,8 +13,14 @@ export interface CreatePythonSymbolFunctionOptions
|
|
|
14
13
|
* Represents an 'exported' symbol from a .py file. Class, enum, interface etc.
|
|
15
14
|
*/
|
|
16
15
|
export class PythonOutputSymbol extends OutputSymbol {
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
static readonly memberSpaces = ["static", "instance"] as const;
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
name: string,
|
|
20
|
+
spaces: OutputSpace[] | OutputSpace | undefined,
|
|
21
|
+
options: PythonOutputSymbolOptions,
|
|
22
|
+
) {
|
|
23
|
+
super(name, spaces, options);
|
|
19
24
|
this.#module = options.module ?? undefined;
|
|
20
25
|
}
|
|
21
26
|
|
|
@@ -26,11 +31,32 @@ export class PythonOutputSymbol extends OutputSymbol {
|
|
|
26
31
|
return this.#module;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
this
|
|
34
|
+
get staticMembers() {
|
|
35
|
+
return this.memberSpaceFor("static")!;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get instanceMembers() {
|
|
39
|
+
return this.memberSpaceFor("instance")!;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get isStaticMemberSymbol() {
|
|
43
|
+
return !this.isInstanceMemberSymbol;
|
|
31
44
|
}
|
|
32
45
|
|
|
33
|
-
get
|
|
34
|
-
return
|
|
46
|
+
get isInstanceMemberSymbol() {
|
|
47
|
+
return this.spaces.some((s) => s.key === "instance");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
copy() {
|
|
51
|
+
const copy = new PythonOutputSymbol(this.name, undefined, {
|
|
52
|
+
binder: this.binder,
|
|
53
|
+
aliasTarget: this.aliasTarget,
|
|
54
|
+
module: this.module,
|
|
55
|
+
metadata: this.metadata,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
this.initializeCopy(copy);
|
|
59
|
+
|
|
60
|
+
return copy;
|
|
35
61
|
}
|
|
36
62
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Children,
|
|
3
|
+
memo,
|
|
4
|
+
Refkey,
|
|
5
|
+
resolve,
|
|
6
|
+
untrack,
|
|
7
|
+
useContext,
|
|
8
|
+
} from "@alloy-js/core";
|
|
9
|
+
import { MemberExpression } from "../components/MemberExpression.jsx";
|
|
10
|
+
import { PythonSourceFileContext } from "../components/SourceFile.jsx";
|
|
11
|
+
import {
|
|
12
|
+
PythonModuleScope,
|
|
13
|
+
PythonOutputScope,
|
|
14
|
+
PythonOutputSymbol,
|
|
15
|
+
} from "./index.js";
|
|
16
|
+
|
|
17
|
+
export function ref(
|
|
18
|
+
refkey: Refkey,
|
|
19
|
+
): () => [Children, PythonOutputSymbol | undefined] {
|
|
20
|
+
const sourceFile = useContext(PythonSourceFileContext);
|
|
21
|
+
const resolveResult = resolve<PythonOutputScope, PythonOutputSymbol>(
|
|
22
|
+
refkey as Refkey,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
return memo(() => {
|
|
26
|
+
if (resolveResult.value === undefined) {
|
|
27
|
+
return ["<Unresolved Symbol>", undefined];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const { commonScope, lexicalDeclaration, symbol, pathDown, memberPath } =
|
|
31
|
+
resolveResult.value;
|
|
32
|
+
|
|
33
|
+
// Where the target declaration is relative to the referencing scope.
|
|
34
|
+
// * module: target symbol is in a different module
|
|
35
|
+
// * local: target symbol is within the current module
|
|
36
|
+
const targetLocation =
|
|
37
|
+
pathDown[0] instanceof PythonModuleScope ? "module" : "local";
|
|
38
|
+
let localSymbol: PythonOutputSymbol | undefined;
|
|
39
|
+
|
|
40
|
+
if (targetLocation === "module") {
|
|
41
|
+
localSymbol = untrack(() =>
|
|
42
|
+
sourceFile!.scope.addImport(
|
|
43
|
+
lexicalDeclaration,
|
|
44
|
+
pathDown[0] as PythonModuleScope,
|
|
45
|
+
),
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const parts = [];
|
|
50
|
+
|
|
51
|
+
if (commonScope && commonScope.isMemberScope) {
|
|
52
|
+
// we are referencing a member of a type we are inside
|
|
53
|
+
if (lexicalDeclaration.isInstanceMemberSymbol) {
|
|
54
|
+
parts.push(<MemberExpression.Part id="self" />);
|
|
55
|
+
} else {
|
|
56
|
+
parts.push(<MemberExpression.Part symbol={commonScope.ownerSymbol} />);
|
|
57
|
+
}
|
|
58
|
+
parts.push(<MemberExpression.Part symbol={lexicalDeclaration} />);
|
|
59
|
+
} else {
|
|
60
|
+
parts.push(
|
|
61
|
+
<MemberExpression.Part symbol={localSymbol ?? lexicalDeclaration} />,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
for (const part of memberPath) {
|
|
65
|
+
parts.push(<MemberExpression.Part symbol={part} />);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return [<MemberExpression children={parts} />, localSymbol ?? symbol];
|
|
69
|
+
});
|
|
70
|
+
}
|
package/src/symbols/scopes.ts
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import { useScope } from "@alloy-js/core";
|
|
2
|
+
import { PythonLexicalScope } from "./python-lexical-scope.js";
|
|
2
3
|
import { PythonMemberScope } from "./python-member-scope.js";
|
|
3
4
|
import { PythonModuleScope } from "./python-module-scope.js";
|
|
4
5
|
|
|
5
|
-
export type PythonOutputScope =
|
|
6
|
+
export type PythonOutputScope =
|
|
7
|
+
| PythonLexicalScope
|
|
8
|
+
| PythonModuleScope
|
|
9
|
+
| PythonMemberScope;
|
|
6
10
|
|
|
7
11
|
export function usePythonScope() {
|
|
8
12
|
return useScope() as PythonOutputScope;
|
|
9
13
|
}
|
|
14
|
+
|
|
15
|
+
export function usePythonLexicalScope() {
|
|
16
|
+
const scope = usePythonScope();
|
|
17
|
+
if (!(scope instanceof PythonLexicalScope)) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
"Expected a PythonLexicalScope, but got " + scope.constructor.name,
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return scope;
|
|
23
|
+
}
|