Skip to content

Commit 79bbb8d

Browse files
committed
fix: import/export
1 parent 16ad652 commit 79bbb8d

File tree

11 files changed

+63
-27
lines changed

11 files changed

+63
-27
lines changed

packages/language-server/src/codegen/context.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import type { Code } from "../types";
33
class CodegenContext {
44
needCaptureReturn = 0;
55
returnType: (Code[] | null)[] = [];
6+
exportingTypes = new Set<string>();
67
}
78

89
// TODO: Make this not singleton
910
export const context = new CodegenContext();
11+
12+
export function refreshCodegenContext() {
13+
Object.assign(context, new CodegenContext());
14+
}

packages/language-server/src/codegen/enum.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import type { SyntaxNode } from "tree-sitter";
22
import type { Code } from "../types";
3+
import { context } from "./context";
34
import { escapeCtorName } from "./escaping";
45
import { generateFieldDeclarationList } from "./struct";
56
import { generateType, generateTypeParameters } from "./type";
67

78
export function* generateEnum(node: SyntaxNode): Generator<Code> {
9+
const exporting = node.namedChildren[0]?.type === "visibility_modifier" ? "export " : "";
810
const name = node.childForFieldName("name")!;
911
const typeParameters = node.childForFieldName("type_parameters");
1012
const body = node.childForFieldName("body")!;
1113

14+
if (exporting)
15+
context.exportingTypes.add(name.text);
16+
1217
const symbolName = `__JSRS_${name.text}_Symbol`;
1318
yield `const ${symbolName} = Symbol();\n`;
1419

@@ -17,12 +22,12 @@ export function* generateEnum(node: SyntaxNode): Generator<Code> {
1722
...generateTypeParameters(typeParameters),
1823
];
1924

20-
yield `interface `;
25+
yield `${exporting}interface `;
2126
yield* enumType;
2227
yield ` { [${symbolName}]: typeof ${symbolName} }\n`;
2328

2429
const ctorName = escapeCtorName(name.text);
25-
yield `interface ${ctorName}`;
30+
yield `${exporting}interface ${ctorName}`;
2631
if (typeParameters)
2732
yield* generateTypeParameters(typeParameters);
2833
yield ` {\n`;
@@ -34,7 +39,7 @@ export function* generateEnum(node: SyntaxNode): Generator<Code> {
3439
}
3540
}
3641
yield `}\n`;
37-
yield `var `;
42+
yield `${exporting}var `;
3843
yield name;
3944
yield `!: ${ctorName}\n`;
4045
}

packages/language-server/src/codegen/impl.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { SyntaxNode } from "tree-sitter";
22
import type { Code } from "../types";
3+
import { context } from "./context";
34
import { escapeCtorName } from "./escaping";
45
import { FunctionKind, generateFunction } from "./function";
56
import { generateTypeParameters, getTypeParamPlaceholders } from "./type";
@@ -13,6 +14,8 @@ export function* generateImpl(node: SyntaxNode): Generator<
1314
const body = node.childForFieldName("body")!;
1415
const name = type.text; // FIXME: A::B
1516

17+
const exporting = context.exportingTypes.has(name) ? "export " : "";
18+
1619
const staticMethods: SyntaxNode[] = [];
1720
const instanceMethods: SyntaxNode[] = [];
1821
for (const child of body.namedChildren) {
@@ -40,13 +43,13 @@ export function* generateImpl(node: SyntaxNode): Generator<
4043
const traitName = trait.text;
4144
yield `satisfies ${escapeCtorName(traitName)}; }\n`;
4245
// TODO: declare module "..." {
43-
yield `interface ${escapeCtorName(name)} extends ${escapeCtorName(traitName)} {}\n`;
46+
yield `${exporting}interface ${escapeCtorName(name)} extends ${escapeCtorName(traitName)} {}\n`;
4447
}
4548
else {
4649
yield "}\n";
4750
const typeParamPlaceholders = getTypeParamPlaceholders(typeParams);
4851
yield `type ${implName}_T${typeParamPlaceholders} = ReturnType<typeof ${implName}${typeParamPlaceholders}>;\n`;
49-
yield `interface ${escapeCtorName(name)} extends ${implName}_T${typeParamPlaceholders} {}\n`;
52+
yield `${exporting}interface ${escapeCtorName(name)} extends ${implName}_T${typeParamPlaceholders} {}\n`;
5053
}
5154
}
5255

@@ -65,13 +68,13 @@ export function* generateImpl(node: SyntaxNode): Generator<
6568
const traitName = trait.text;
6669
yield `satisfies ${traitName}; }\n`;
6770
// TODO: declare module "..." {
68-
yield `interface ${name} extends ${traitName} {}\n`;
71+
yield `${exporting}interface ${name} extends ${traitName} {}\n`;
6972
}
7073
else {
7174
yield "}\n";
7275
const typeParamPlaceholders = getTypeParamPlaceholders(typeParams);
7376
yield `type ${implName}_T${typeParamPlaceholders} = ReturnType<typeof ${implName}${typeParamPlaceholders}>;\n`;
74-
yield `interface ${name} extends ${implName}_T${typeParamPlaceholders} {}\n`;
77+
yield `${exporting}interface ${name} extends ${implName}_T${typeParamPlaceholders} {}\n`;
7578
}
7679
}
7780
}

packages/language-server/src/codegen/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { context } from "./context";
66
import { generateEnum } from "./enum";
77
import { FunctionKind, generateFunction } from "./function";
88
import { generateImpl } from "./impl";
9+
import { generateMacroInvocation } from "./macro";
910
import { generateMatch, getPatternBindings } from "./match";
1011
import { generatePrelude } from "./prelude";
1112
import { generateStruct, generateStructExpression } from "./struct";
@@ -74,6 +75,9 @@ export function* generateStatement(node: SyntaxNode): Generator<Code> {
7475
case "if_expression":
7576
yield* generateIf(node);
7677
break;
78+
case "macro_invocation":
79+
yield* generateMacroInvocation(node);
80+
break;
7781
default:
7882
yield* generateExpression(node);
7983
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { SyntaxNode } from "tree-sitter";
2+
import type { Code } from "../types";
3+
4+
export function* generateMacroInvocation(node: SyntaxNode): Generator<Code> {
5+
const macro = node.childForFieldName("macro")!;
6+
if (macro.text === "import") {
7+
yield [
8+
node.text.replaceAll(/[!()]/g, " "),
9+
node.startIndex,
10+
];
11+
}
12+
}

packages/language-server/src/codegen/struct.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
import type { SyntaxNode } from "tree-sitter";
22
import type { Code } from "../types";
33
import { generateExpression } from ".";
4+
import { context } from "./context";
45
import { escapeCtorName, escapeDataName } from "./escaping";
56
import { generateType, generateTypeParameters } from "./type";
67
import { generateChildren } from "./utils";
78

89
export function* generateStruct(node: SyntaxNode): Generator<Code> {
10+
const exporting = node.namedChildren[0]?.type === "visibility_modifier" ? "export " : "";
911
const name = node.childForFieldName("name")!;
1012
const typeParameters = node.childForFieldName("type_parameters");
1113
const body = node.childForFieldName("body");
1214

1315
const ctorName = escapeCtorName(name.text);
1416
const dataName = escapeDataName(name.text);
1517

16-
yield `interface ${ctorName} { (_: ${dataName}): ${name.text}; }\n`;
17-
yield `var ${name.text}!: ${ctorName};\n`;
18+
if (exporting)
19+
context.exportingTypes.add(name.text);
20+
21+
yield `${exporting}interface ${ctorName} { (_: ${dataName}): ${name.text}; }\n`;
22+
yield `${exporting}var ${name.text}!: ${ctorName};\n`;
1823

1924
yield `interface `;
2025
yield dataName;
@@ -24,7 +29,7 @@ export function* generateStruct(node: SyntaxNode): Generator<Code> {
2429
else
2530
yield `{}`;
2631

27-
yield `\ninterface `;
32+
yield `\n${exporting}interface `;
2833
yield name;
2934
yield ` extends ${dataName} {}\n`;
3035
}

packages/language-server/src/codegen/use.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -148,27 +148,24 @@ export function* generateUse(node: SyntaxNode): Generator<Code> {
148148
return base ? `${base}/${printScopedIdentifier(path)}` : printScopedIdentifier(path);
149149
}
150150

151-
function getSelfName(path: SyntaxNode): string {
152-
if (path.type === "identifier") {
153-
return path.text;
154-
}
155-
else if (path.type === "scoped_identifier") {
151+
function getSelfName(path: SyntaxNode): SyntaxNode {
152+
if (path.type === "scoped_identifier") {
156153
return getSelfName(path.namedChildren[1]);
157154
}
158-
else if (path.type === "crate") {
159-
return "crate";
160-
}
161155
else {
162-
return "";
156+
return path;
163157
}
164158
}
165159
}
166160

167161
function generatePath(node: SyntaxNode, path: string): Generator<Code> {
162+
if (path.startsWith(".") && !path.match(/\.[^/]*$/)) {
163+
path = `${path}.jsrs`;
164+
}
168165
return wrapWith(
169166
node.startIndex,
170167
node.endIndex,
171-
codeFeatures.verification,
168+
codeFeatures.all,
172169
`"`,
173170
path,
174171
`"`,
@@ -184,7 +181,10 @@ export function printScopedIdentifier(path: SyntaxNode): string {
184181
return `${printScopedIdentifier(path.namedChildren[0])}/${path.namedChildren[1].text}`;
185182
}
186183
else if (path.type === "crate") {
187-
return `@`;
184+
return `.`;
185+
}
186+
else if (path.type === "super") {
187+
return `..`;
188188
}
189189
else {
190190
return "";

packages/language-server/src/virtualCode.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Parser from "tree-sitter";
66
import _Rust from "tree-sitter-rust";
77
import { TextDocument } from "vscode-languageserver-textdocument";
88
import { generateRoot } from "./codegen";
9+
import { refreshCodegenContext } from "./codegen/context";
910
import { resolveCodes } from "./utils/resolveCodes";
1011

1112
let parser: Parser | undefined;
@@ -78,6 +79,7 @@ export class JsrsVirtualCode implements VirtualCode {
7879
}
7980

8081
updateEmbeddedCodes() {
82+
refreshCodegenContext();
8183
this.embeddedCodes = [
8284
resolveCodes("jsrs", "typescript", generateRoot(this.tree.rootNode)),
8385
];

packages/transpiler/src/nodes.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,10 @@ export class Printer {
734734
return `${getPathImpl(path.namedChildren[0])}/${path.namedChildren[1].text}`;
735735
}
736736
else if (path.type === "crate") {
737-
return `@`;
737+
return `.`;
738+
}
739+
else if (path.type === "super") {
740+
return `..`;
738741
}
739742
else {
740743
throw new Error(`Not implemented: ${path.type}`);

playground/basic.jsrs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
// pub use crate::x::{x::y::{self, y1, y2}, z::self as t, t as h};
2-
// pub use t::x;
3-
// pub use s::s;
4-
// pub use r;
1+
import!({ A } from "./struct.jsrs");
52

63
1 + 1;
74
let mut a = 1;

playground/struct.jsrs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
struct A {
1+
pub struct A {
22
field: number
33
}
44

0 commit comments

Comments
 (0)