motoko 3.0.0-beta0 → 3.0.0-beta2
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +26 -6
- package/lib/ast.d.ts +23 -0
- package/lib/ast.d.ts.map +1 -0
- package/lib/ast.js +31 -0
- package/lib/ast.js.map +1 -0
- package/lib/file.d.ts +5 -6
- package/lib/file.d.ts.map +1 -1
- package/lib/file.js +3 -0
- package/lib/file.js.map +1 -1
- package/lib/index.d.ts +20 -17
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +39 -8
- package/lib/index.js.map +1 -1
- package/lib/package.d.ts +3 -2
- package/lib/package.d.ts.map +1 -1
- package/lib/package.js +42 -6
- package/lib/package.js.map +1 -1
- package/lib/utils/resolveEntryPoint.d.ts +4 -0
- package/lib/utils/resolveEntryPoint.d.ts.map +1 -0
- package/lib/utils/resolveEntryPoint.js +48 -0
- package/lib/utils/resolveEntryPoint.js.map +1 -0
- package/lib/versions/interpreter.d.ts +18 -16
- package/lib/versions/interpreter.d.ts.map +1 -1
- package/lib/versions/moc.d.ts +18 -16
- package/lib/versions/moc.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/ast.ts +69 -0
- package/src/file.ts +3 -0
- package/src/index.ts +51 -14
- package/src/package.ts +56 -3
- package/src/utils/resolveEntryPoint.ts +64 -0
- package/versions/latest/moc.min.js +1 -1
- package/versions/latest/moc_interpreter.min.js +1 -1
@@ -17,24 +17,25 @@ declare const _default: {
|
|
17
17
|
};
|
18
18
|
candid(): string;
|
19
19
|
wasm(mode: import("..").WasmMode): any;
|
20
|
-
parseMotoko():
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
parseCandid(): {
|
25
|
-
ast: object;
|
20
|
+
parseMotoko(): import("../ast").Node;
|
21
|
+
parseMotokoTyped(): {
|
22
|
+
ast: import("../ast").Node;
|
23
|
+
type: import("../ast").Node;
|
26
24
|
};
|
25
|
+
parseCandid(): object;
|
27
26
|
};
|
28
27
|
read(path: string): string;
|
29
28
|
write(path: string, content?: string): void;
|
30
29
|
rename(path: string, newPath: string): void;
|
31
30
|
delete(path: string): void;
|
32
31
|
list(directory: string): string[];
|
33
|
-
fetchPackage(info: string | import("../package").PackageInfo): Promise<import("../package").Package>;
|
34
|
-
|
35
|
-
|
32
|
+
fetchPackage(name: string, info: string | import("../package").PackageInfo): Promise<import("../package").Package>;
|
33
|
+
installPackages(packages: Record<string, string | import("../package").PackageInfo>): Promise<void>;
|
34
|
+
loadPackage(pkg: import("../package").Package): void;
|
35
|
+
usePackage(name: string, directory: string): void;
|
36
36
|
clearPackages(): void;
|
37
|
-
|
37
|
+
validatePackage(pkg: import("../package").Package): void;
|
38
|
+
setAliases(aliases: Record<string, string>): void;
|
38
39
|
setMetadata(values: string): void;
|
39
40
|
check(path: string): import("..").Diagnostic[];
|
40
41
|
run(path: string, libPaths?: string[]): {
|
@@ -44,13 +45,14 @@ declare const _default: {
|
|
44
45
|
};
|
45
46
|
candid(path: string): string;
|
46
47
|
wasm(path: string, mode: import("..").WasmMode): any;
|
47
|
-
parseMotoko(content: string):
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
parseCandid(content: string): {
|
52
|
-
ast: object;
|
48
|
+
parseMotoko(content: string): import("../ast").Node;
|
49
|
+
parseMotokoTyped(content: string): {
|
50
|
+
ast: import("../ast").Node;
|
51
|
+
type: import("../ast").Node;
|
53
52
|
};
|
53
|
+
parseCandid(content: string): object;
|
54
|
+
resolveMain(directory?: string): string;
|
55
|
+
resolveLib(directory?: string): string;
|
54
56
|
};
|
55
57
|
export default _default;
|
56
58
|
//# sourceMappingURL=interpreter.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../../src/versions/interpreter.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../../src/versions/interpreter.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,wBAAwD"}
|
package/lib/versions/moc.d.ts
CHANGED
@@ -17,24 +17,25 @@ declare const _default: {
|
|
17
17
|
};
|
18
18
|
candid(): string;
|
19
19
|
wasm(mode: import("..").WasmMode): any;
|
20
|
-
parseMotoko():
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
parseCandid(): {
|
25
|
-
ast: object;
|
20
|
+
parseMotoko(): import("../ast").Node;
|
21
|
+
parseMotokoTyped(): {
|
22
|
+
ast: import("../ast").Node;
|
23
|
+
type: import("../ast").Node;
|
26
24
|
};
|
25
|
+
parseCandid(): object;
|
27
26
|
};
|
28
27
|
read(path: string): string;
|
29
28
|
write(path: string, content?: string): void;
|
30
29
|
rename(path: string, newPath: string): void;
|
31
30
|
delete(path: string): void;
|
32
31
|
list(directory: string): string[];
|
33
|
-
fetchPackage(info: string | import("../package").PackageInfo): Promise<import("../package").Package>;
|
34
|
-
|
35
|
-
|
32
|
+
fetchPackage(name: string, info: string | import("../package").PackageInfo): Promise<import("../package").Package>;
|
33
|
+
installPackages(packages: Record<string, string | import("../package").PackageInfo>): Promise<void>;
|
34
|
+
loadPackage(pkg: import("../package").Package): void;
|
35
|
+
usePackage(name: string, directory: string): void;
|
36
36
|
clearPackages(): void;
|
37
|
-
|
37
|
+
validatePackage(pkg: import("../package").Package): void;
|
38
|
+
setAliases(aliases: Record<string, string>): void;
|
38
39
|
setMetadata(values: string): void;
|
39
40
|
check(path: string): import("..").Diagnostic[];
|
40
41
|
run(path: string, libPaths?: string[]): {
|
@@ -44,13 +45,14 @@ declare const _default: {
|
|
44
45
|
};
|
45
46
|
candid(path: string): string;
|
46
47
|
wasm(path: string, mode: import("..").WasmMode): any;
|
47
|
-
parseMotoko(content: string):
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
parseCandid(content: string): {
|
52
|
-
ast: object;
|
48
|
+
parseMotoko(content: string): import("../ast").Node;
|
49
|
+
parseMotokoTyped(content: string): {
|
50
|
+
ast: import("../ast").Node;
|
51
|
+
type: import("../ast").Node;
|
53
52
|
};
|
53
|
+
parseCandid(content: string): object;
|
54
|
+
resolveMain(directory?: string): string;
|
55
|
+
resolveLib(directory?: string): string;
|
54
56
|
};
|
55
57
|
export default _default;
|
56
58
|
//# sourceMappingURL=moc.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"moc.d.ts","sourceRoot":"","sources":["../../src/versions/moc.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"moc.d.ts","sourceRoot":"","sources":["../../src/versions/moc.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,wBAA4C"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "motoko",
|
3
|
-
"version": "3.0.0-
|
3
|
+
"version": "3.0.0-beta2",
|
4
4
|
"description": "Compile and run Motoko smart contracts in Node.js or the browser.",
|
5
5
|
"author": "Ryan Vandersmith (https://github.com/rvanasa)",
|
6
6
|
"license": "Apache-2.0",
|
@@ -21,7 +21,8 @@
|
|
21
21
|
"dependencies": {
|
22
22
|
"cross-fetch": "3.1.5",
|
23
23
|
"debug": "4.3.4",
|
24
|
-
"isomorphic-parse-github-url": "1.0.2"
|
24
|
+
"isomorphic-parse-github-url": "1.0.2",
|
25
|
+
"sanitize-filename": "^1.6.3"
|
25
26
|
},
|
26
27
|
"devDependencies": {
|
27
28
|
"@types/jest": "^28.1.3",
|
package/src/ast.ts
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
export type CompilerAST = CompilerAST[] | CompilerNode | string | null;
|
2
|
+
export type CompilerSpan = { name: 'Pos'; args: [string, string, string] };
|
3
|
+
|
4
|
+
export interface CompilerNode {
|
5
|
+
name: string;
|
6
|
+
args: CompilerAST[];
|
7
|
+
}
|
8
|
+
|
9
|
+
export type Span = [number, number];
|
10
|
+
export type AST = AST[] | Node | string | null;
|
11
|
+
|
12
|
+
export interface Node {
|
13
|
+
name: string;
|
14
|
+
file?: string;
|
15
|
+
start?: Span;
|
16
|
+
end?: Span;
|
17
|
+
type?: Node;
|
18
|
+
args?: AST[];
|
19
|
+
}
|
20
|
+
|
21
|
+
// export type TypeAST = AST[] | Node | string | number | null;
|
22
|
+
// export type TypeNode = {
|
23
|
+
// name: string;
|
24
|
+
// args: TypeAST[];
|
25
|
+
// };
|
26
|
+
|
27
|
+
export function simplifyAST(ast: CompilerNode): Node;
|
28
|
+
export function simplifyAST(ast: CompilerAST[]): AST[];
|
29
|
+
export function simplifyAST<T extends CompilerAST>(ast: T): T;
|
30
|
+
|
31
|
+
export function simplifyAST(ast: CompilerAST): AST {
|
32
|
+
if (Array.isArray(ast)) {
|
33
|
+
return ast.map((a) => simplifyAST(a));
|
34
|
+
}
|
35
|
+
if (typeof ast !== 'object') {
|
36
|
+
return ast;
|
37
|
+
}
|
38
|
+
if (ast.name === '@') {
|
39
|
+
const [start, end, subAst] = ast.args as [
|
40
|
+
CompilerSpan,
|
41
|
+
CompilerSpan,
|
42
|
+
CompilerAST,
|
43
|
+
];
|
44
|
+
return {
|
45
|
+
...(typeof subAst === 'string'
|
46
|
+
? { name: subAst }
|
47
|
+
: simplifyAST(subAst)),
|
48
|
+
file: start.args[0],
|
49
|
+
start: [+start.args[1], +start.args[2]],
|
50
|
+
end: [+end.args[1], +end.args[2]],
|
51
|
+
};
|
52
|
+
}
|
53
|
+
if (ast.name === ':') {
|
54
|
+
const [type, subAst] = ast.args as [CompilerNode, CompilerAST];
|
55
|
+
// console.log(subAst); ////
|
56
|
+
return {
|
57
|
+
...(typeof subAst === 'string'
|
58
|
+
? { name: subAst }
|
59
|
+
: simplifyAST(subAst)),
|
60
|
+
type: simplifyAST(type),
|
61
|
+
};
|
62
|
+
}
|
63
|
+
return {
|
64
|
+
name: ast.name,
|
65
|
+
args: simplifyAST(ast.args),
|
66
|
+
};
|
67
|
+
}
|
68
|
+
|
69
|
+
// export function getTypeString(type: Type) {}
|
package/src/file.ts
CHANGED
@@ -60,6 +60,9 @@ export const file = (mo: Motoko, path: string) => {
|
|
60
60
|
parseMotoko() {
|
61
61
|
return mo.parseMotoko(result.read());
|
62
62
|
},
|
63
|
+
parseMotokoTyped() {
|
64
|
+
return mo.parseMotokoTyped(result.read());
|
65
|
+
},
|
63
66
|
parseCandid() {
|
64
67
|
return mo.parseCandid(result.read());
|
65
68
|
},
|
package/src/index.ts
CHANGED
@@ -1,5 +1,13 @@
|
|
1
|
+
import { Node, simplifyAST } from './ast';
|
1
2
|
import { file } from './file';
|
2
|
-
import {
|
3
|
+
import {
|
4
|
+
fetchPackage,
|
5
|
+
installPackages,
|
6
|
+
Package,
|
7
|
+
PackageInfo,
|
8
|
+
validatePackage,
|
9
|
+
} from './package';
|
10
|
+
import { resolveMain, resolveLib } from './utils/resolveEntryPoint';
|
3
11
|
|
4
12
|
export type Motoko = ReturnType<typeof wrapMotoko>;
|
5
13
|
|
@@ -21,7 +29,7 @@ export type Diagnostic = {
|
|
21
29
|
export type WasmMode = 'ic' | 'wasi';
|
22
30
|
|
23
31
|
export default function wrapMotoko(compiler: Compiler, version: string) {
|
24
|
-
const debug = require('debug')(
|
32
|
+
const debug = require('debug')(`motoko:${version}`);
|
25
33
|
|
26
34
|
const invoke = (key: string, unwrap: boolean, args: any[]) => {
|
27
35
|
if (!compiler) {
|
@@ -86,21 +94,36 @@ export default function wrapMotoko(compiler: Compiler, version: string) {
|
|
86
94
|
list(directory: string): string[] {
|
87
95
|
return invoke('readDir', false, [directory]);
|
88
96
|
},
|
89
|
-
async fetchPackage(info: string | PackageInfo) {
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
return
|
94
|
-
},
|
95
|
-
|
96
|
-
|
97
|
+
async fetchPackage(name:string, info: string | PackageInfo) {
|
98
|
+
if(!info){
|
99
|
+
throw new Error('Please specify both a name and source');
|
100
|
+
}
|
101
|
+
return fetchPackage(name,info);
|
102
|
+
},
|
103
|
+
async installPackages(packages: Record<string, string | PackageInfo>) {
|
104
|
+
return installPackages(mo, packages);
|
105
|
+
},
|
106
|
+
loadPackage(pkg: Package) {
|
107
|
+
debug('+package', pkg.name);
|
108
|
+
mo.validatePackage(pkg);
|
109
|
+
const directory = `.node-motoko/${pkg.name}/${pkg.version}`;
|
110
|
+
Object.entries(pkg.files).forEach(([path, file]) => {
|
111
|
+
mo.write(`${directory}/${path}`, file.content);
|
112
|
+
});
|
113
|
+
mo.usePackage(pkg.name, directory);
|
114
|
+
},
|
115
|
+
usePackage(name: string, directory: string) {
|
116
|
+
debug('@package', name, directory);
|
97
117
|
invoke('addPackage', false, [name, directory]);
|
98
118
|
},
|
99
119
|
clearPackages() {
|
100
120
|
debug('-packages');
|
101
121
|
invoke('clearPackage', false, []);
|
102
122
|
},
|
103
|
-
|
123
|
+
validatePackage(pkg: Package) {
|
124
|
+
validatePackage(pkg);
|
125
|
+
},
|
126
|
+
setAliases(aliases: Record<string, string>) {
|
104
127
|
debug('aliases', aliases);
|
105
128
|
invoke('setActorAliases', false, [Object.entries(aliases)]);
|
106
129
|
},
|
@@ -128,12 +151,26 @@ export default function wrapMotoko(compiler: Compiler, version: string) {
|
|
128
151
|
}
|
129
152
|
return invoke('compileWasm', true, [mode, path]);
|
130
153
|
},
|
131
|
-
parseMotoko(content: string):
|
132
|
-
|
154
|
+
parseMotoko(content: string): Node {
|
155
|
+
const ast = invoke('parseMotoko', true, [content]);
|
156
|
+
return simplifyAST(ast);
|
133
157
|
},
|
134
|
-
|
158
|
+
parseMotokoTyped(content: string): { ast: Node; type: Node } {
|
159
|
+
const { ast, typ } = invoke('parseMotokoTyped', true, [content]);
|
160
|
+
return {
|
161
|
+
ast: simplifyAST(ast),
|
162
|
+
type: simplifyAST(typ),
|
163
|
+
};
|
164
|
+
},
|
165
|
+
parseCandid(content: string): object {
|
135
166
|
return invoke('parseCandid', true, [content]);
|
136
167
|
},
|
168
|
+
resolveMain(directory: string = ''): string | undefined {
|
169
|
+
return resolveMain(mo, directory);
|
170
|
+
},
|
171
|
+
resolveLib(directory: string = ''): string | undefined {
|
172
|
+
return resolveLib(mo, directory);
|
173
|
+
},
|
137
174
|
};
|
138
175
|
// @ts-ignore
|
139
176
|
mo.default = mo;
|
package/src/package.ts
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
import { default as parse } from 'isomorphic-parse-github-url';
|
5
5
|
import fetch from 'cross-fetch';
|
6
6
|
import { Motoko } from '.';
|
7
|
+
import sanitize from 'sanitize-filename';
|
7
8
|
|
8
9
|
export interface PackageInfo {
|
9
10
|
name: string;
|
@@ -42,7 +43,7 @@ async function loadPackage(mo: Motoko, info: PackageInfo) {
|
|
42
43
|
};
|
43
44
|
const result = await fetchGithub_(mo, repo, info.name);
|
44
45
|
if (result) {
|
45
|
-
mo.
|
46
|
+
mo.usePackage(info.name, info.name + '/');
|
46
47
|
}
|
47
48
|
return result ? true : false;
|
48
49
|
}
|
@@ -279,6 +280,7 @@ async function fetchFromService(
|
|
279
280
|
}
|
280
281
|
|
281
282
|
export async function fetchPackage(
|
283
|
+
name: string,
|
282
284
|
info: string | PackageInfo,
|
283
285
|
): Promise<Package | undefined> {
|
284
286
|
if (typeof info === 'string') {
|
@@ -289,13 +291,13 @@ export async function fetchPackage(
|
|
289
291
|
return;
|
290
292
|
}
|
291
293
|
return {
|
292
|
-
name
|
294
|
+
name,
|
293
295
|
version: info.version,
|
294
296
|
files,
|
295
297
|
};
|
296
298
|
}
|
297
299
|
|
298
|
-
export async function
|
300
|
+
export async function installPackages(
|
299
301
|
mo: Motoko,
|
300
302
|
packages: Record<string, string | PackageInfo>,
|
301
303
|
) {
|
@@ -309,3 +311,54 @@ export async function loadPackages(
|
|
309
311
|
}),
|
310
312
|
);
|
311
313
|
}
|
314
|
+
|
315
|
+
export function validatePackage(pkg: Package) {
|
316
|
+
function showValue(value: any) {
|
317
|
+
const string = JSON.stringify(value);
|
318
|
+
return string.length > 50 ? string.substring(0, 50) + '...' : string;
|
319
|
+
}
|
320
|
+
function getPackageDisplayName() {
|
321
|
+
return `(${pkg.name} / ${pkg.version})`;
|
322
|
+
}
|
323
|
+
|
324
|
+
if (typeof pkg !== 'object' || Array.isArray(pkg)) {
|
325
|
+
throw new Error(`Unexpected package: ${showValue(pkg)}`);
|
326
|
+
}
|
327
|
+
if (typeof pkg.name !== 'string' || sanitize(pkg.name) !== pkg.name) {
|
328
|
+
throw new Error(`Invalid package name ${getPackageDisplayName()}`);
|
329
|
+
}
|
330
|
+
if (
|
331
|
+
typeof pkg.version !== 'string' ||
|
332
|
+
sanitize(pkg.version) !== pkg.version
|
333
|
+
) {
|
334
|
+
throw new Error(`Invalid package version ${getPackageDisplayName()}`);
|
335
|
+
}
|
336
|
+
if (typeof pkg.files !== 'object' || Array.isArray(pkg.files)) {
|
337
|
+
throw new Error(`Invalid package files: ${showValue(pkg.files)}`);
|
338
|
+
}
|
339
|
+
|
340
|
+
Object.entries(pkg.files).forEach(([path, file]) => {
|
341
|
+
if (
|
342
|
+
typeof path !== 'string' ||
|
343
|
+
path.split('/').some((p) => sanitize(p) !== p)
|
344
|
+
) {
|
345
|
+
throw new Error(
|
346
|
+
`Invalid file path ${getPackageDisplayName()} [${path}]`,
|
347
|
+
);
|
348
|
+
}
|
349
|
+
if (typeof file !== 'object' || Array.isArray(file)) {
|
350
|
+
throw new Error(
|
351
|
+
`Invalid file ${getPackageDisplayName()} [${path}]: ${showValue(
|
352
|
+
file,
|
353
|
+
)}`,
|
354
|
+
);
|
355
|
+
}
|
356
|
+
if (typeof file.content !== 'string') {
|
357
|
+
throw new Error(
|
358
|
+
`Invalid file content ${getPackageDisplayName()} [${path}]: ${showValue(
|
359
|
+
file.content,
|
360
|
+
)}`,
|
361
|
+
);
|
362
|
+
}
|
363
|
+
});
|
364
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import { Motoko } from '..';
|
2
|
+
|
3
|
+
// function getOne<T>(values: T[]): T | undefined {
|
4
|
+
// if (values.length) {
|
5
|
+
// return values[0];
|
6
|
+
// }
|
7
|
+
// }
|
8
|
+
|
9
|
+
function resolveEntryPoint(
|
10
|
+
mo: Motoko,
|
11
|
+
directory: string,
|
12
|
+
expected: string,
|
13
|
+
): string {
|
14
|
+
directory = directory || '';
|
15
|
+
if (directory && !directory.endsWith('/')) {
|
16
|
+
directory += '/';
|
17
|
+
}
|
18
|
+
|
19
|
+
const moFiles = mo.list(directory).filter((f) => /\.mo$/i.test(f));
|
20
|
+
if (moFiles.length === 1) {
|
21
|
+
return moFiles[0];
|
22
|
+
} else if (moFiles.length === 0) {
|
23
|
+
throw new Error(
|
24
|
+
'Could not find any Motoko files in the top-level directory',
|
25
|
+
);
|
26
|
+
}
|
27
|
+
|
28
|
+
const expectedFiles = moFiles.filter(
|
29
|
+
(f) => f.toLowerCase() === expected.toLowerCase(),
|
30
|
+
);
|
31
|
+
if (expectedFiles.length === 1) {
|
32
|
+
return expectedFiles[0];
|
33
|
+
} else if (expectedFiles.length > 1) {
|
34
|
+
throw new Error(
|
35
|
+
`Found ${expectedFiles.length} entry point files with different capitalization`,
|
36
|
+
);
|
37
|
+
}
|
38
|
+
|
39
|
+
throw new Error(
|
40
|
+
`Found ${moFiles.length} possible entry points. Please rename one of these files to '${expected}'`,
|
41
|
+
);
|
42
|
+
|
43
|
+
// TODO: evaluate whether we want to choose an entry point by parsing files
|
44
|
+
|
45
|
+
// const parsedFiles = moFiles.map((f) => {
|
46
|
+
// try {
|
47
|
+
// return mo.parseMotoko(mo.read(directory + f));
|
48
|
+
// } catch (err) {
|
49
|
+
// throw new Error(`Parse error in ${f}`);
|
50
|
+
// }
|
51
|
+
// });
|
52
|
+
|
53
|
+
// console.log(parsedFiles);
|
54
|
+
|
55
|
+
// return getOne(parsedFiles.filter());
|
56
|
+
}
|
57
|
+
|
58
|
+
export function resolveMain(mo: Motoko, directory: string): string {
|
59
|
+
return resolveEntryPoint(mo, directory, 'Main.mo');
|
60
|
+
}
|
61
|
+
|
62
|
+
export function resolveLib(mo: Motoko, directory: string): string {
|
63
|
+
return resolveEntryPoint(mo, directory, 'Lib.mo');
|
64
|
+
}
|