1 Each loadfile() or include() call compiles a source of its own. A compilation 2 records its read position, its line information and its export table in the 3 source. With one source for several calls, the imports of a later compilation 4 resolve to wrong export slots, its error locations are wrong and a leading 5 interpreter line is parsed as code. 6 7 -- Testcase -- 8 import * as fs from 'fs'; 9 10 function run(label, fn) { 11 try { 12 fn(); 13 } 14 catch (e) { 15 let m = match(e.stacktrace[0].context, /`([^`]*)`/); 16 17 printf("%s: %s: %s (line %d: %s)\n", label, e.type, e.message, 18 e.stacktrace[0].line, m ? m[1] : "no source line"); 19 } 20 } 21 22 function repeat(label, count, fn) { 23 for (let i = 1; i <= count; i++) 24 run(`${label} #${i}`, fn); 25 } 26 27 repeat("named loadfile", 3, () => loadfile("files/named.uc")()); 28 repeat("wildcard loadfile", 3, () => loadfile("files/wildcard.uc")()); 29 repeat("default loadfile", 2, () => loadfile("files/default.uc")()); 30 repeat("named include", 2, () => include("files/named.uc")); 31 repeat("wildcard include", 2, () => include("files/wildcard.uc")); 32 33 fs.symlink("named.uc", `${TESTFILES_PATH}/link.uc`); 34 run("symlink #1", () => loadfile("files/link.uc")()); 35 run("symlink #2", () => loadfile("./files/../files/named.uc")()); 36 37 repeat("no import", 2, () => loadfile("files/plain.uc")()); 38 repeat("native import", 2, () => loadfile("files/native.uc")()); 39 run("other file #1", () => loadfile("files/named.uc")()); 40 run("other file #2", () => loadfile("files/named2.uc")()); 41 repeat("loadstring", 2, () => loadstring(fs.readfile("files/plain.uc"))()); 42 43 fs.symlink("dynamic.uc", `${TESTFILES_PATH}/alias.uc`); 44 run("dynamic import #1", () => print("dynamic: ", import("dynamic").own(), "\n")); 45 run("dynamic import #2", () => print("dynamic: ", import("alias").own(), "\n")); 46 47 repeat("error location", 3, () => loadfile("files/error.uc")()); 48 repeat("interpreter line", 2, () => loadfile("files/shebang.uc")()); 49 50 system([ fs.readlink("/proc/self/exe"), "-c", "-o", "files/precompiled.uc", "files/plain.uc" ]); 51 repeat("precompiled", 2, () => loadfile("files/precompiled.uc")()); 52 -- End -- 53 54 -- File mod.uc -- 55 export function first() { return "first"; }; 56 export function second() { return "second"; }; 57 export default "default"; 58 -- End -- 59 60 -- File named.uc -- 61 import { second, first } from "./mod.uc"; 62 63 print("named: ", first(), " ", second(), "\n"); 64 -- End -- 65 66 -- File named2.uc -- 67 import { first } from "./mod.uc"; 68 69 print("named2: ", first(), "\n"); 70 -- End -- 71 72 -- File wildcard.uc -- 73 import * as mod from "./mod.uc"; 74 75 print("wildcard: ", mod.first(), " ", mod.second(), " ", mod.default, "\n"); 76 -- End -- 77 78 -- File default.uc -- 79 import def, { second } from "./mod.uc"; 80 81 print("default: ", def, " ", second(), "\n"); 82 -- End -- 83 84 -- File plain.uc -- 85 print("plain\n"); 86 -- End -- 87 88 -- File native.uc -- 89 import { basename } from "fs"; 90 91 print("native: ", basename("/a/b"), "\n"); 92 -- End -- 93 94 -- File dynamic.uc -- 95 import { first } from "./mod.uc"; 96 97 export function own() { return "own " + first(); }; 98 -- End -- 99 100 -- File error.uc -- 101 let a = 1; 102 let b = 2; 103 null.x = a + b; 104 -- End -- 105 106 -- File shebang.uc -- 107 #!/usr/bin/env ucode 108 print("interpreter line\n"); 109 -- End -- 110 111 -- Args -- 112 -R -L files/ 113 -- End -- 114 115 -- Expect stdout -- 116 named: first second 117 named: first second 118 named: first second 119 wildcard: first second default 120 wildcard: first second default 121 wildcard: first second default 122 default: default second 123 default: default second 124 named: first second 125 named: first second 126 wildcard: first second default 127 wildcard: first second default 128 named: first second 129 named: first second 130 plain 131 plain 132 native: b 133 native: b 134 named: first second 135 named2: first 136 plain 137 plain 138 dynamic: own first 139 dynamic: own first 140 error location #1: Type error: attempt to set property on null value (line 3: null.x = a + b;) 141 error location #2: Type error: attempt to set property on null value (line 3: null.x = a + b;) 142 error location #3: Type error: attempt to set property on null value (line 3: null.x = a + b;) 143 interpreter line 144 interpreter line 145 plain 146 plain 147 -- End --
This page was automatically generated by LXR 0.3.1. • OpenWrt