Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve importing #534

Merged
merged 5 commits into from
Jan 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ build/wenyan-win.exe
temp
dist
/tools/calendar.html
藏書樓
藏書樓
.node-xmlhttprequest-*
18 changes: 14 additions & 4 deletions src/macro.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function extractMacros(txt, options = {}) {
const { lib, reader, lang, importPaths, requestOptions } = options;
const { lib, reader, lang, importOptions } = options;

function getImports() {
var imps = [];
Expand Down Expand Up @@ -117,15 +117,25 @@ function extractMacros(txt, options = {}) {
var imports = getImports();
var macros = getMacros();
for (var i = 0; i < imports.length; i++) {
var isrc;
var isrc, entry;
if (imports[i] in lib[lang]) {
isrc = lib[lang][imports[i]];
} else if (imports[i] in lib) {
isrc = lib[imports[i]];
} else {
isrc = reader(imports[i], importPaths, requestOptions);
const file = reader(imports[i], importOptions);
isrc = file.src;
entry = file.entry;
}
macros = macros.concat(extractMacros(isrc, options));
macros = macros.concat(
extractMacros(isrc, {
...options,
importOptions: {
...importOptions,
entryFilepath: entry
}
})
);
}
return macros;
}
Expand Down
39 changes: 28 additions & 11 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ function defaultLogCallback(x) {
: console.dir(x, { depth: null, maxArrayLength: null });
}

function defaultErrorCallback(e) {
console.error(e);
process.exit();
}

function tokens2asc(
tokens,
assert = (msg, pos, b) => {
Expand Down Expand Up @@ -677,19 +682,29 @@ function compile(arg1, arg2, arg3) {
romanizeIdentifiers = "none",
resetVarCnt = true,
logCallback = defaultLogCallback,
errorCallback = process.exit,
lib = typeof STDLIB == "undefined" ? {} : STDLIB,
reader = defaultImportReader,
importPaths = [],
errorCallback = defaultErrorCallback,
lib = STDLIB,
strict = false,

// import options
entryFilepath = undefined,
importPaths = [],
importCache = {},
importContext = {},
allowHttp = false,
trustedHosts = [],
requestTimeout = 2000
} = options;

trustedHosts.push(...defaultTrustedHosts);

const requestOptions = {
const reader = defaultImportReader;

const importOptions = {
entryFilepath,
importPaths,
importCache,
importContext,
allowHttp,
trustedHosts,
requestTimeout
Expand Down Expand Up @@ -728,8 +743,7 @@ function compile(arg1, arg2, arg3) {
lib,
reader,
lang,
importPaths,
requestOptions
importOptions
});
txt = expandMacros(txt, macros);

Expand Down Expand Up @@ -765,26 +779,29 @@ function compile(arg1, arg2, arg3) {
}
var klass = compilers[lang];
var compiler = new klass(asc);
var result = compiler.compile({ imports });
var { imports, result } = result;
var { imports, result } = compiler.compile({ imports });
var targ = result;
logCallback(targ);
imports = imports || [];
imports = Array.from(new Set(imports));
logCallback("Loading imports", imports);
for (var i = 0; i < imports.length; i++) {
var isrc;
var isrc, entry;
if (imports[i] in lib[lang]) {
isrc = lib[lang][imports[i]];
} else if (imports[i] in lib) {
isrc = lib[imports[i]];
} else {
isrc = reader(imports[i], importPaths, requestOptions);
const file = reader(imports[i], importOptions);
isrc = file.src;
entry = file.entry;
}
targ =
mwrapper(
imports[i],
compile(isrc, {
...options,
entryFilepath: entry,
resetVarCnt: false,
strict: false
})
Expand Down
85 changes: 53 additions & 32 deletions src/reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,52 @@ function fetchTextSync(url, timeout) {
throw new URIError(xmlHttp.responseText);
}

function defaultImportReader(
moduleName,
importPaths = [],
requestOptions = {}
) {
function fetchSync(uri, cache, requestTimeout) {
if (cache[uri]) return cache[uri];

const data = isHttpURL(uri)
? fetchTextSync(uri, requestTimeout)
: eval("require")("fs").readFileSync(uri, "utf-8");

cache[uri] = data;

return data;
}

function defaultImportReader(moduleName, requestOptions = {}) {
const {
allowHttp = false,
entryFilepath,
importPaths = [],
importCache = {},
importContext = {},
trustedHosts = [],
requestTimeout = 2000
} = requestOptions;

if (typeof importPaths === "string") importPaths = [importPaths];
if (importContext[moduleName]) return { src: importContext[moduleName] };

const pathes = [];

for (dir of importPaths) {
if (typeof importPaths === "string") {
pathes.push(importPaths);
} else {
pathes.push(...importPaths);
}

if (entryFilepath)
pathes.push(
entryFilepath
.replace(/\\/g, "/")
.split("/")
.slice(0, -1)
.join("/")
);

for (dir of pathes) {
let uri = dir;
let entries = [];
let src;

if (uri.endsWith("/")) uri = uri.slice(0, -1);

Expand All @@ -55,33 +86,23 @@ function defaultImportReader(
`You can turn it on by specify the "allowHttp" option.`
);
}

try {
return fetchTextSync(
`${uri}/${encodeURIComponent(moduleName)}.wy`,
requestTimeout
);
} catch (e) {}
try {
return fetchTextSync(
`${uri}/${encodeURIComponent(moduleName)}/${encodeURIComponent(
INDEX_FILENAME
)}.wy`,
requestTimeout
);
} catch (e) {}
entries = [
`${uri}/${encodeURIComponent(moduleName)}.wy`,
`${uri}/${encodeURIComponent(moduleName)}/${encodeURIComponent(
INDEX_FILENAME
)}.wy`
];
} else {
entries = [
`${uri}/${moduleName}.wy`,
`${uri}/${moduleName}/${INDEX_FILENAME}.wy`
];
}

for (const entry of entries) {
try {
return eval("require")("fs").readFileSync(
`${dir}/${moduleName}.wy`,
"utf-8"
);
} catch (e) {}
try {
return eval("require")("fs").readFileSync(
`${dir}/${moduleName}/${INDEX_FILENAME}.wy`,
"utf-8"
);
src = fetchSync(entry, importCache, requestTimeout);
return { src, entry };
} catch (e) {}
}
}
Expand Down
2 changes: 1 addition & 1 deletion static/ide.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function main() {
romanizeIdentifiers: selr.value,
resetVarCnt: true,
errorCallback: (...args) => (outdiv.innerText += args.join(" ") + "\n"),
reader: x => Examples.examples[x]
importContext: Examples.examples,
});

var showcode = hidestd.checked ? hideImportedModules(code) : code;
Expand Down
16 changes: 14 additions & 2 deletions static/ide2.html
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,18 @@
hidestd.onchange = crun;
outputHanzi.onchange = crun;

function getImportContext(){
let context = {
...Examples.examples,
}

for(const key of Object.keys(state.files)){
context[key] = state.files[key].code
}

return context
}

function compile(){
document.getElementById("out").innerText = "";
var log = ""
Expand All @@ -706,7 +718,7 @@
romanizeIdentifiers: selr.value,
resetVarCnt: true,
errorCallback: (...args) => (outdiv.innerText += args.join(" ") + "\n"),
reader: x => Examples.examples[x],
importContext: getImportContext(),
logCallback:(x)=>{log+=x+"\n"},
strict:true
});
Expand All @@ -733,7 +745,7 @@
romanizeIdentifiers: selr.value,
resetVarCnt: true,
errorCallback: (...args) => (outdiv.innerText += args.join(" ") + "\n"),
reader: x => Examples.examples[x]
importContext: getImportContext(),
});

var showcode = hidestd.checked ? hideImportedModules(code) : code;
Expand Down
3 changes: 3 additions & 0 deletions test/fixture/nested-import/四庫全書/序.wy
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
吾嘗觀「「本草綱目」」之書。方悟「草部」之義。

今有一元。曰「草部」。名之曰「草部」。
3 changes: 3 additions & 0 deletions test/fixture/nested-import/四庫全書/本草綱目/序.wy
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
吾嘗觀「「草部」」之書。方悟「草部」之義。

今有一元。曰「草部」。名之曰「草部」。
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
今有一言。曰「「甘草。黄芪。人参。」」。名之曰「草部」。
18 changes: 18 additions & 0 deletions test/import.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { createTestUtil } = require("./utils");

const { expectOutput } = createTestUtil({
prefix: "吾嘗觀「「四庫全書」」之書。",
suffix: "書之",
compileOptions: {
importPaths: "./test/fixture/nested-import"
}
});

describe("import", () => {
it("nested import", () => {
expectOutput(
"方悟「草部」之義。今有一元。曰「草部」。",
"甘草。黄芪。人参。"
);
});
});
Loading