@xnoxs/flux-lang 4.0.8 → 4.1.1
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/CHANGELOG.md +7 -0
- package/dist/flux-cli.js +8093 -4979
- package/dist/flux.cjs.js +3 -2
- package/dist/flux.esm.js +12 -11
- package/dist/flux.min.js +2 -2
- package/index.js +10 -9
- package/package.json +5 -4
- package/src/self/bundler.flux +16 -21
- package/src/self/bundler.js +1 -185
- package/src/self/cli.flux +220 -274
- package/src/self/cli.js +58 -124
- package/src/self/config.flux +28 -36
- package/src/self/config.js +31 -34
- package/src/self/pkg.flux +136 -39
- package/src/self/pkg.js +124 -37
- package/src/self/transpiler.flux +1 -1
- package/src/self/transpiler.js +1 -3
package/src/self/bundler.js
CHANGED
|
@@ -1,185 +1 @@
|
|
|
1
|
-
|
|
2
|
-
'use strict';
|
|
3
|
-
// Generated by Flux Transpiler v3.5.3 (self-hosted)
|
|
4
|
-
"use strict";
|
|
5
|
-
|
|
6
|
-
const Fs = require("fs");
|
|
7
|
-
const Path = require("path");
|
|
8
|
-
const { lexerize } = require("./lexer");
|
|
9
|
-
const { makeParser } = require("./parser");
|
|
10
|
-
const { makeCodeGen } = require("./codegen");
|
|
11
|
-
function toModuleId(absPath) {
|
|
12
|
-
const base = Path.basename(absPath, ".flux");
|
|
13
|
-
return ("_flux_" + base.replace(/[^a-zA-Z0-9]/g, "_"));
|
|
14
|
-
}
|
|
15
|
-
function extractModuleInfo(ast, fromFile) {
|
|
16
|
-
const imports = [];
|
|
17
|
-
const npmImports = [];
|
|
18
|
-
const exports = [];
|
|
19
|
-
const body = [];
|
|
20
|
-
const dir = Path.dirname(fromFile);
|
|
21
|
-
for (const node of ast.body) {
|
|
22
|
-
if ((node.type == "ImportDecl")) {
|
|
23
|
-
const src = node.source;
|
|
24
|
-
if ((src.startsWith("./") || src.startsWith("../"))) {
|
|
25
|
-
let resolved = src;
|
|
26
|
-
if (!resolved.endsWith(".flux")) {
|
|
27
|
-
resolved = (resolved + ".flux");
|
|
28
|
-
}
|
|
29
|
-
const absPath = Path.resolve(dir, resolved);
|
|
30
|
-
imports.push({ names: node.names, source: node.source, absPath });
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
npmImports.push({ names: node.names, source: src });
|
|
34
|
-
body.push(node);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
else if ((node.type == "ExportDecl")) {
|
|
38
|
-
const inner = node.decl;
|
|
39
|
-
if ((inner.type == "FnDecl")) {
|
|
40
|
-
exports.push(inner.name);
|
|
41
|
-
}
|
|
42
|
-
if ((inner.type == "ClassDecl")) {
|
|
43
|
-
exports.push(inner.name);
|
|
44
|
-
}
|
|
45
|
-
if ((inner.type == "VarDecl")) {
|
|
46
|
-
exports.push(inner.name);
|
|
47
|
-
}
|
|
48
|
-
body.push(inner);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
body.push(node);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return { cleanAst: { type: "Program", body }, imports, npmImports, exports };
|
|
55
|
-
}
|
|
56
|
-
function codegenModule(ast) {
|
|
57
|
-
const cg = makeCodeGen({ indent: " " });
|
|
58
|
-
const result = cg.generate(ast);
|
|
59
|
-
const lines = result.code.split("\n");
|
|
60
|
-
const start = lines.findIndex((l) => (((l.trim() != "") && !l.includes("Generated by Flux")) && !l.includes("\"use strict\"")));
|
|
61
|
-
return lines.slice(start).join("\n");
|
|
62
|
-
}
|
|
63
|
-
class Bundler {
|
|
64
|
-
constructor(entryFile, options, modules, order, visited, inStack) {
|
|
65
|
-
this.entryFile = entryFile;
|
|
66
|
-
this.options = options;
|
|
67
|
-
this.modules = modules;
|
|
68
|
-
this.order = order;
|
|
69
|
-
this.visited = visited;
|
|
70
|
-
this.inStack = inStack;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
bundle() {
|
|
74
|
-
this.collect(this.entryFile);
|
|
75
|
-
return this.link();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
collect(absPath) {
|
|
79
|
-
if (this.visited.has(absPath)) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
if (this.inStack.has(absPath)) {
|
|
83
|
-
throw new Error(((("[" + Path.basename(absPath)) + "] Circular dependency detected: ") + absPath));
|
|
84
|
-
}
|
|
85
|
-
if (!Fs.existsSync(absPath)) {
|
|
86
|
-
throw new Error(((("[" + Path.basename(absPath)) + "] File not found: ") + absPath));
|
|
87
|
-
}
|
|
88
|
-
this.inStack.add(absPath);
|
|
89
|
-
const source = Fs.readFileSync(absPath, "utf8");
|
|
90
|
-
let ast = null;
|
|
91
|
-
try {
|
|
92
|
-
const tokens = lexerize(source).tokenize();
|
|
93
|
-
ast = makeParser(tokens).parse();
|
|
94
|
-
}
|
|
95
|
-
catch (e) {
|
|
96
|
-
throw new Error(((("[" + Path.basename(absPath)) + "] Parse error: ") + e.message));
|
|
97
|
-
}
|
|
98
|
-
const info = extractModuleInfo(ast, absPath);
|
|
99
|
-
this.modules.set(absPath, { cleanAst: info.cleanAst, imports: info.imports, exports: info.exports, source, absPath });
|
|
100
|
-
for (const imp of info.imports) {
|
|
101
|
-
this.collect(imp.absPath);
|
|
102
|
-
}
|
|
103
|
-
this.inStack.delete(absPath);
|
|
104
|
-
this.visited.add(absPath);
|
|
105
|
-
this.order.push(absPath);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
link() {
|
|
109
|
-
const lines = [];
|
|
110
|
-
const banner = (this.options.banner != false);
|
|
111
|
-
if (banner) {
|
|
112
|
-
lines.push("// Generated by Flux Bundler (self-hosted)");
|
|
113
|
-
lines.push(("// Entry: " + Path.basename(this.entryFile)));
|
|
114
|
-
lines.push(("// Modules: " + this.order.length));
|
|
115
|
-
lines.push("\"use strict\";");
|
|
116
|
-
lines.push("");
|
|
117
|
-
}
|
|
118
|
-
lines.push("(function() {");
|
|
119
|
-
lines.push("");
|
|
120
|
-
for (const absPath of this.order) {
|
|
121
|
-
const mod = this.modules.get(absPath);
|
|
122
|
-
const isEntry = (absPath == this.entryFile);
|
|
123
|
-
const modId = toModuleId(absPath);
|
|
124
|
-
const relName = Path.relative(process.cwd(), absPath);
|
|
125
|
-
lines.push((" // " + "─".repeat(60)));
|
|
126
|
-
lines.push((" // Module: " + relName));
|
|
127
|
-
lines.push((" // " + "─".repeat(60)));
|
|
128
|
-
if (!isEntry) {
|
|
129
|
-
lines.push(((" var " + modId) + " = (function() {"));
|
|
130
|
-
lines.push(" var _exports = {};");
|
|
131
|
-
lines.push("");
|
|
132
|
-
}
|
|
133
|
-
for (const imp of mod.imports) {
|
|
134
|
-
const srcId = toModuleId(imp.absPath);
|
|
135
|
-
for (const name of imp.names) {
|
|
136
|
-
const localName = (name.alias ?? name.name);
|
|
137
|
-
const importedName = name.name;
|
|
138
|
-
lines.push(((((((((((((" var " + localName) + " = ") + srcId) + "._exports ? ") + srcId) + "._exports.") + importedName) + " : ") + srcId) + ".") + importedName) + ";"));
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if ((mod.imports.length > 0)) {
|
|
142
|
-
lines.push("");
|
|
143
|
-
}
|
|
144
|
-
const moduleCode = codegenModule(mod.cleanAst);
|
|
145
|
-
lines.push(moduleCode);
|
|
146
|
-
if (!isEntry) {
|
|
147
|
-
if ((mod.exports.length > 0)) {
|
|
148
|
-
lines.push("");
|
|
149
|
-
for (const expName of mod.exports) {
|
|
150
|
-
lines.push(((((" _exports." + expName) + " = ") + expName) + ";"));
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
lines.push("");
|
|
154
|
-
lines.push(" return _exports;");
|
|
155
|
-
lines.push(" })()");
|
|
156
|
-
lines.push(((((" " + modId) + "._exports = ") + modId) + ";"));
|
|
157
|
-
}
|
|
158
|
-
lines.push("");
|
|
159
|
-
}
|
|
160
|
-
lines.push("})();");
|
|
161
|
-
return { code: lines.join("\n"), modules: this.order.length };
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
module.exports.Bundler = Bundler;
|
|
167
|
-
function makeBundler(entryFile, options) {
|
|
168
|
-
return new Bundler(Path.resolve(entryFile), (options ?? { }), new Map(), [], new Set(), new Set());
|
|
169
|
-
}
|
|
170
|
-
module.exports.makeBundler = makeBundler;
|
|
171
|
-
function bundle(entryFile, options) {
|
|
172
|
-
const result = { success: false, code: "", modules: 0, errors: [] };
|
|
173
|
-
try {
|
|
174
|
-
const b = makeBundler(entryFile, options);
|
|
175
|
-
const out = b.bundle();
|
|
176
|
-
result.code = out.code;
|
|
177
|
-
result.modules = out.modules;
|
|
178
|
-
result.success = true;
|
|
179
|
-
}
|
|
180
|
-
catch (e) {
|
|
181
|
-
result.errors.push({ message: e.message, name: e.name, file: null });
|
|
182
|
-
}
|
|
183
|
-
return result;
|
|
184
|
-
}
|
|
185
|
-
module.exports.bundle = bundle;
|
|
1
|
+
function findIndex(arr, fn) { return arr.findIndex(fn); } function join(arr, sep) { return arr.join(sep != null ? sep : ','); } function includes(arr, val) { return arr.includes(val); } function trim(s) { return String(s).trim(); } function startsWith(s, prefix) { return String(s).startsWith(prefix); } function endsWith(s, suffix) { return String(s).endsWith(suffix); } function repeat(s, n) { return String(s).repeat(n); } "use strict"; const Fs = require("fs"); const Path = require("path"); const { lexerize } = require("./lexer"); const { makeParser } = require("./parser"); const { makeCodeGen } = require("./codegen"); function _a(_d) { const base = Path.basename(_d, ".flux"); return ("_flux_" + base.replace(/[^a-zA-Z0-9]/g, "_")); } function _b(_e, _f) { const imports = []; const exports = []; const body = []; const dir = Path.dirname(_f); for (const _g of _e.body) { if ((_g.type == "ImportDecl")) { let src = _g.source; if (!src.endsWith(".flux")) { src = (src + ".flux"); } const _d = Path.resolve(dir, src); imports.push({ names: _g.names, source: _g.source, absPath: _d }); } else if ((_g.type == "ExportDecl")) { const inner = _g.decl; if ((inner.type == "FnDecl")) { exports.push(inner.name); } if ((inner.type == "ClassDecl")) { exports.push(inner.name); } if ((inner.type == "VarDecl")) { exports.push(inner.name); } body.push(inner); } else { body.push(_g); } } return { cleanAst: { type: "Program", body }, imports, exports }; } function _c(_e) { const cg = makeCodeGen({ indent: " " }); const result = cg.generate(_e); const lines = result.code.split("\n"); const start = lines.findIndex((_h) => (((_h.trim() != "") && !_h.includes("Generated by Flux")) && !_h.includes("\"use strict\""))); return lines.slice(start).join("\n"); } class Bundler { constructor(entryFile, options, modules, order, visited, inStack) { this.entryFile = entryFile; this.options = options; this.modules = modules; this.order = order; this.visited = visited; this.inStack = inStack; } bundle() { this.collect(this.entryFile); return this.link(); } collect(_d) { if (this.visited.has(_d)) { return; } if (this.inStack.has(_d)) { throw new Error(((("[" + Path.basename(_d)) + "] Circular dependency detected: ") + _d)); } if (!Fs.existsSync(_d)) { throw new Error(((("[" + Path.basename(_d)) + "] File not found: ") + _d)); } this.inStack.add(_d); const source = Fs.readFileSync(_d, "utf8"); let _e = null; try { const tokens = lexerize(source).tokenize(); _e = makeParser(tokens).parse(); } catch (_i) { throw new Error(((("[" + Path.basename(_d)) + "] Parse error: ") + _i.message)); } const info = _b(_e, _d); this.modules.set(_d, { cleanAst: info.cleanAst, imports: info.imports, exports: info.exports, source, absPath: _d }); for (const _j of info.imports) { this.collect(_j.absPath); } this.inStack.delete(_d); this.visited.add(_d); this.order.push(_d); } link() { const lines = []; const banner = (this.options.banner != false); if (banner) { lines.push("// Generated by Flux Bundler (self-hosted)"); lines.push(("// Entry: " + Path.basename(this.entryFile))); lines.push(("// Modules: " + this.order.length)); lines.push("\"use strict\";"); lines.push(""); } lines.push("// flux_modules resolver"); lines.push(`(function()${var _p=require('path'),_fs=require('fs'),_M=require('module'),_d=_p.join(process.cwd(),'flux_modules','node_modules');if(_fs.existsSync(_d)){var _o=_M._resolveFilename.bind(_M);_M._resolveFilename=function(r,p,m,op){if(!r.startsWith('.')&&!r.startsWith('/')&&!r.startsWith('_g:')){var _fp=_p.join(_d,r.split('/')[0]);if(_fs.existsSync(_fp)){try{return _o(_p.join(_d,r),p,m,op);}catch(_e){}}}return _o(r,p,m,op);};}})();`); lines.push(""); lines.push("(function() {"); lines.push(""); for (const _d of this.order) { const mod = this.modules.get(_d); const isEntry = (_d == this.entryFile); const modId = _a(_d); const relName = Path.relative(process.cwd(), _d); lines.push((" // " + "─".repeat(60))); lines.push((" // Module: " + relName)); lines.push((" // " + "─".repeat(60))); if (!isEntry) { lines.push(((" var " + modId) + " = (function() {")); lines.push(" var _exports = {};"); lines.push(""); } for (const _j of mod.imports) { const srcId = _a(_j.absPath); for (const _k of _j.names) { const localName = (_k.alias ?? _k.name); const importedName = _k.name; lines.push(((((((((((((" var " + localName) + " = ") + srcId) + "._exports ? ") + srcId) + "._exports.") + importedName) + " : ") + srcId) + ".") + importedName) + ";")); } } if ((mod.imports.length > 0)) { lines.push(""); } const moduleCode = _c(mod.cleanAst); lines.push(moduleCode); if (!isEntry) { if ((mod.exports.length > 0)) { lines.push(""); for (const _l of mod.exports) { lines.push(((((" _exports." + _l) + " = ") + _l) + ";")); } } lines.push(""); lines.push(" return _exports;"); lines.push(" })()"); lines.push(((((" " + modId) + "._exports = ") + modId) + ";")); } lines.push(""); } lines.push("})();"); return { code: lines.join("\n"), modules: this.order.length }; } } module.exports.Bundler = Bundler; function makeBundler(_m, _n) { return new Bundler(Path.resolve(_m), (_n ?? { }), new Map(), [], new Set(), new Set()); } module.exports.makeBundler = makeBundler; function bundle(_m, _n) { const result = { success: false, code: "", modules: 0, errors: [] }; try { const b = makeBundler(_m, _n); const out = b.bundle(); result.code = out.code; result.modules = out.modules; result.success = true; } catch (_i) { result.errors.push({ message: _i.message, name: _i.name, file: null }); } return result; } module.exports.bundle = bundle;
|