Skip to content
This repository was archived by the owner on Oct 8, 2024. It is now read-only.

Commit 1653a3e

Browse files
authored
fix: import issues (#135)
* fix: import issues * format
1 parent ccf1fef commit 1653a3e

File tree

3 files changed

+199
-66
lines changed

3 files changed

+199
-66
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Add functions and example for accessing PostgreSQL [#119](https://github.com/hypermodeAI/functions-as/pull/119)
66
- Make plugin version optional [#133](https://github.com/hypermodeAI/functions-as/pull/133)
77
- Fix transform display of optional string literal [#134](https://github.com/hypermodeAI/functions-as/pull/134)
8+
- Fix exporting imported functions or exporting as an alias does not work [#135](https://github.com/hypermodeAI/functions-as/pull/135)
89

910
## 2024-07-10 - Version 0.9.4
1011

src/transform/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default class HypermodeTransform extends Transform {
2121
return 0;
2222
}
2323
});
24-
24+
mpgen.sources = sources;
2525
for (const source of sources) {
2626
mpgen.visitSource(source);
2727
}

src/transform/src/multiparam.ts

Lines changed: 197 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
CommonFlags,
55
FloatLiteralExpression,
66
FunctionDeclaration,
7-
IdentifierExpression,
87
IntegerLiteralExpression,
98
LiteralExpression,
109
LiteralKind,
@@ -22,14 +21,29 @@ import {
2221
Token,
2322
Tokenizer,
2423
ExportStatement,
24+
ImportStatement,
2525
} from "assemblyscript/dist/assemblyscript.js";
2626
import { Parameter } from "./types.js";
27-
2827
class OptionalParam {
2928
param: Parameter;
3029
defaultValue: string | null = null;
3130
}
3231

32+
class NameMeta {
33+
localName: string | null;
34+
foreignName: string | null;
35+
exportedName: string | null;
36+
constructor(
37+
localName: string | null = null,
38+
foreignName: string | null = null,
39+
exportedName: string | null = null,
40+
) {
41+
this.localName = localName;
42+
this.foreignName = foreignName;
43+
this.exportedName = exportedName;
44+
}
45+
}
46+
3347
/**
3448
* Overrides the default multi-param generated by ASC
3549
* By default, you must have optional params declared in sequential order
@@ -63,41 +77,28 @@ class OptionalParam {
6377
*/
6478
export class MultiParamGen {
6579
static SN: MultiParamGen = new MultiParamGen();
66-
public required_fns: string[] = [];
80+
public sources: Source[] = [];
81+
public foreign_fns = new Map<string, NameMeta[]>();
82+
public foreign_files = new Set<string>();
83+
84+
public exported_fns: NameMeta[] = [];
6785
public optional_fns = new Map<string, OptionalParam[]>();
6886
static init(): MultiParamGen {
6987
if (!MultiParamGen.SN) MultiParamGen.SN = new MultiParamGen();
7088
return MultiParamGen.SN;
7189
}
72-
visitExportStatement(node: ExportStatement): void {
73-
const source = node.range.source;
74-
if (source.sourceKind != SourceKind.UserEntry) return;
75-
for (const member of node.members) {
76-
const name = member.localName.text;
77-
this.required_fns.push(name);
78-
}
79-
}
8090
visitFunctionDeclaration(node: FunctionDeclaration) {
8191
const source = node.range.source;
82-
let name = node.name.text;
83-
if (!node.body && node.decorators?.length) {
84-
const decorator = node.decorators.find(
85-
(e) => (e.name as IdentifierExpression).text === "external",
86-
);
87-
if (
88-
decorator.args.length > 1 &&
89-
decorator.args[1].kind === NodeKind.Literal
90-
) {
91-
name = (decorator.args[1] as StringLiteralExpression).value.toString();
92-
}
93-
}
92+
const name = node.name.text;
93+
const exported = isExported(name, source);
94+
if (!exported) return;
9495
if (
9596
source.sourceKind != SourceKind.UserEntry &&
96-
!this.required_fns.includes(name)
97+
!this.foreign_fns
98+
.get(source.internalPath)
99+
?.find((v) => v.foreignName == name)
97100
)
98101
return;
99-
if (node.flags != CommonFlags.Export && !this.required_fns.includes(name))
100-
return;
101102
if (node.signature.parameters.length > 63) {
102103
throw new Error("Functions exceeding 64 parameters not allowed!");
103104
}
@@ -117,52 +118,117 @@ export class MultiParamGen {
117118
});
118119
}
119120

120-
this.optional_fns.set(name, params);
121+
const exportedName = getExportedName(name, source);
122+
this.optional_fns.set(exportedName, params);
121123

122-
initDefaultValues(node);
124+
if (
125+
node.flags == CommonFlags.Export ||
126+
node.flags == CommonFlags.ModuleExport
127+
) {
128+
if (name != exportedName) {
129+
this.optional_fns.set(name, params);
130+
}
131+
}
123132

124-
if (node.body == null) {
125-
let name = node.name.text;
126-
if (!node.body && node.decorators?.length) {
127-
const decorator = node.decorators.find(
128-
(e) => (e.name as IdentifierExpression).text === "external",
129-
);
130-
if (
131-
decorator.args.length > 1 &&
132-
decorator.args[1].kind === NodeKind.Literal
133-
) {
134-
name = (
135-
decorator.args[1] as StringLiteralExpression
136-
).value.toString();
133+
initDefaultValues(node);
134+
}
135+
visitSource(source: Source) {
136+
if (this.foreign_files.has(source.internalPath)) {
137+
for (const stmt of source.statements) {
138+
if (stmt.kind === NodeKind.FunctionDeclaration) {
139+
const node = stmt as FunctionDeclaration;
140+
const foreignName = node.name.text;
141+
const internalPath = source.internalPath;
142+
const exported = isExported(foreignName, source);
143+
const exportedName = getExportedName(foreignName, source);
144+
if (exported) {
145+
if (this.foreign_fns.has(internalPath)) {
146+
this.foreign_fns
147+
.get(foreignName)
148+
?.push(new NameMeta(foreignName, foreignName, exportedName));
149+
} else {
150+
this.foreign_fns.set(internalPath, [
151+
new NameMeta(foreignName, foreignName, exportedName),
152+
]);
153+
}
154+
}
155+
this.exported_fns.push(
156+
new NameMeta(foreignName, foreignName, exportedName),
157+
);
158+
console.log(this.exported_fns);
137159
}
138160
}
139-
const params: OptionalParam[] = [];
140-
for (const param of node.signature.parameters) {
141-
const defaultValue = getDefaultValue(param);
142-
params.push({
143-
param: {
144-
name: param.name.text,
145-
type: {
146-
name: "UNINITIALIZED_VALUE",
147-
path: "UNINITIALIZED_VALUE",
148-
},
149-
optional: !!param.initializer,
150-
},
151-
defaultValue,
152-
});
153-
if (param.initializer) param.initializer = null;
154-
}
155-
this.optional_fns.set(name, params);
156161
}
157-
}
158-
visitSource(node: Source) {
159-
if (node.isLibrary) return;
160-
for (const stmt of node.statements) {
161-
if (stmt.kind === NodeKind.Export) {
162-
this.visitExportStatement(stmt as ExportStatement);
162+
if (source.sourceKind === SourceKind.UserEntry) {
163+
for (const stmt of source.statements) {
164+
if (stmt.kind === NodeKind.Import) {
165+
const internalPath = (stmt as ImportStatement).internalPath;
166+
for (const node of (stmt as ImportStatement).declarations) {
167+
const source = node.range.source;
168+
if (source.sourceKind != SourceKind.UserEntry) return;
169+
const foreignName = getRealName(
170+
node.foreignName.text,
171+
this.sources.find((src) => src.internalPath == internalPath),
172+
);
173+
const localName = node.name.text;
174+
const exported = isExported(localName, source);
175+
if (!exported) return;
176+
if (this.foreign_fns.has(internalPath)) {
177+
this.foreign_fns
178+
.get(internalPath)
179+
.push(new NameMeta(localName, foreignName));
180+
} else {
181+
this.foreign_fns.set(internalPath, [
182+
new NameMeta(localName, foreignName),
183+
]);
184+
}
185+
}
186+
} else if (stmt.kind === NodeKind.Export) {
187+
const node = stmt as ExportStatement;
188+
const internalPath = node.internalPath;
189+
if (internalPath) {
190+
if (node.members?.length) {
191+
if (!this.foreign_fns.has(internalPath)) {
192+
this.foreign_fns.set(internalPath, []);
193+
}
194+
const foreign_fns = this.foreign_fns.get(internalPath);
195+
for (const member of node.members) {
196+
const localName = member.localName.text;
197+
const exportedName = member.exportedName.text;
198+
const exists = foreign_fns.find(
199+
(v) => v.localName == localName,
200+
);
201+
if (exists) {
202+
exists.exportedName = exportedName;
203+
} else {
204+
foreign_fns.push(
205+
new NameMeta(localName, localName, exportedName),
206+
);
207+
}
208+
}
209+
} else {
210+
this.foreign_files.add(internalPath);
211+
}
212+
} else {
213+
if (!node.members?.length) continue;
214+
for (const member of node.members) {
215+
const localName = member.localName.text;
216+
let foreignName: string = localName;
217+
for (const v of this.foreign_fns.values()) {
218+
for (const value of v) {
219+
if (value.localName === localName)
220+
foreignName = value.foreignName;
221+
}
222+
}
223+
const exportedName = member.exportedName.text;
224+
const meta = new NameMeta(localName, foreignName, exportedName);
225+
this.exported_fns.push(meta);
226+
}
227+
}
228+
}
163229
}
164230
}
165-
for (const stmt of node.statements) {
231+
for (const stmt of source.statements) {
166232
if (stmt.kind === NodeKind.FunctionDeclaration) {
167233
this.visitFunctionDeclaration(stmt as FunctionDeclaration);
168234
}
@@ -315,3 +381,69 @@ function initDefaultValues(node: FunctionDeclaration) {
315381
}
316382
}
317383
}
384+
385+
function isExported(name: string, source: Source): boolean {
386+
let i = source.statements.length - 1;
387+
while (i >= 0) {
388+
const stmt = source.statements[i];
389+
if (stmt.kind === NodeKind.FunctionDeclaration) {
390+
const node = stmt as FunctionDeclaration;
391+
return (
392+
node.flags === CommonFlags.Export ||
393+
node.flags === CommonFlags.ModuleExport
394+
);
395+
} else if (stmt.kind === NodeKind.Export) {
396+
const node = stmt as ExportStatement;
397+
// export { ... } from "..."
398+
if (node.members) {
399+
for (const member of node.members) {
400+
const localName = member.localName.text;
401+
if (name === localName) return true;
402+
}
403+
}
404+
}
405+
i--;
406+
}
407+
return false;
408+
}
409+
410+
function getExportedName(name: string, source: Source): string {
411+
const exists = MultiParamGen.SN.exported_fns.find(
412+
(v) => v.foreignName == name,
413+
);
414+
if (exists) return exists.exportedName;
415+
let i = source.statements.length - 1;
416+
while (i >= 0) {
417+
const stmt = source.statements[i];
418+
if (stmt.kind === NodeKind.Export) {
419+
const node = stmt as ExportStatement;
420+
// export { ... } from "..."
421+
if (node.members) {
422+
for (const member of node.members) {
423+
const localName = member.localName.text;
424+
const exportedName = member.exportedName.text;
425+
if (name === localName) return exportedName || localName;
426+
}
427+
}
428+
}
429+
i--;
430+
}
431+
return name;
432+
}
433+
434+
function getRealName(name: string, source: Source): string {
435+
if (!source || !source?.statements) return name;
436+
for (const stmt of source.statements) {
437+
if (stmt.kind === NodeKind.Export) {
438+
const node = stmt as ExportStatement;
439+
if (node.members) {
440+
for (const member of node.members) {
441+
const localName = member.localName.text;
442+
const exportedName = member.exportedName.text;
443+
if (name === exportedName) return localName;
444+
}
445+
}
446+
}
447+
}
448+
return name;
449+
}

0 commit comments

Comments
 (0)