diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-07-17 18:01:08 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-07-17 18:01:08 +0100 |
commit | 71eacf913d42c2c26435316de98a1c924fb7f185 (patch) | |
tree | c696f912ba072ac781d41798d3197e0a7e05d4d4 | |
parent | 141e868d75c56ede9165d361bcdc84e162443753 (diff) | |
download | lace-71eacf913d42c2c26435316de98a1c924fb7f185.tar.gz |
LACE: Ensure errors are rendered properly and exposed during compilation
-rw-r--r-- | lib/lace/compiler.lua | 34 | ||||
-rw-r--r-- | lib/lace/error.lua | 1 | ||||
-rw-r--r-- | test/test-lace.compile-errorindefine.rules | 5 | ||||
-rw-r--r-- | test/test-lace.compiler.lua | 36 | ||||
-rw-r--r-- | test/test-lace.error.lua | 3 |
5 files changed, 74 insertions, 5 deletions
diff --git a/lib/lace/compiler.lua b/lib/lace/compiler.lua index 1b0b21a..8100ff3 100644 --- a/lib/lace/compiler.lua +++ b/lib/lace/compiler.lua @@ -75,7 +75,13 @@ local function internal_compile_ruleset(compcontext, sourcename, content, suppre -- No content supplied, try and load it. sourcename, content = _loader(compcontext)(compcontext, sourcename) if type(sourcename) ~= "string" then - return false, content + if not suppress_default then + -- We're not suppressing default which implies we're + -- the first out of the gate, so we need + -- to offset to account for the implicit include + err.offset(content, 1) + end + return false, err.augment(content, compcontext._lace.source, compcontext._lace.linenr) end end @@ -105,7 +111,7 @@ local function internal_compile_ruleset(compcontext, sourcename, content, suppre _setposition(compcontext, ruleset, i) local rule, msg = compile_one_line(compcontext, line) if type(rule) ~= "table" then - return rule, msg + return rule, err.augment(msg, ruleset.content, i) end rule.linenr = i ruleset.rules[#ruleset.rules+1] = rule @@ -124,7 +130,8 @@ local function internal_compile_ruleset(compcontext, sourcename, content, suppre -- There's no unconditional result and no default, fake up a default and -- then use it. if not suppress_default and not uncond and not result then - return err.error("No result set whatsoever") + local _, nores = err.error("No result set whatsoever", {}) + return false, err.augment(nores, ruleset.content, #ruleset.content.lines + 1) end if not suppress_default and not uncond then @@ -142,6 +149,25 @@ local function internal_compile_ruleset(compcontext, sourcename, content, suppre end local function compile_ruleset(ctx, src, cnt) + -- Augment the compiler context with a false + -- source so that we can be sure the expect early errors to stand a chance + if ctx and src and not cnt then + if type(ctx._lace) ~= "table" then + return nil, "Compilation context must contain a _lace table" + end + ctx._lace.source = { + source = "Implicit inclusion of " .. src, + lines = { { + original = "include " .. src, + content = { + { spos = 1, epos = 7, content = "include" }, + { spos = 9, epos = 8 + #src, content = src } + } + } + } + } + ctx._lace.linenr = 1 + end local ok, ret, msg = xpcall(function() return internal_compile_ruleset(ctx, src, cnt) end, debug.traceback) @@ -153,7 +179,7 @@ local function compile_ruleset(ctx, src, cnt) if type(msg) == "table" then assert(type(msg.msg) == "string", "No error message") - msg = msg.msg + msg = err.render(msg) end return ret, msg diff --git a/lib/lace/error.lua b/lib/lace/error.lua index d71d21d..29683e4 100644 --- a/lib/lace/error.lua +++ b/lib/lace/error.lua @@ -28,6 +28,7 @@ end local function _augment(err, source, linenr) err.source = source err.linenr = linenr + return err end local function _render(err) diff --git a/test/test-lace.compile-errorindefine.rules b/test/test-lace.compile-errorindefine.rules new file mode 100644 index 0000000..44a757a --- /dev/null +++ b/test/test-lace.compile-errorindefine.rules @@ -0,0 +1,5 @@ +-- Error in define, expect an error on line 3 word 3 + +define fish does_not_exist + +allow "anyway" diff --git a/test/test-lace.compiler.lua b/test/test-lace.compiler.lua index c8a41ae..106223b 100644 --- a/test/test-lace.compiler.lua +++ b/test/test-lace.compiler.lua @@ -188,6 +188,42 @@ function suite.load_file_with_one_command() assert(type(rule.args) == "table", "Rules should have arguments") end +-- The various error paths must now be tested for location veracity + +function suite.error_does_not_exist() + local result, msg = compiler.compile(comp_context, "does-not-exist") + assert(result == false, "Errors compiling should return false") + assert(type(msg) == "string", "Compilation errors should be strings") + assert(msg:find("\n"), "Compilation errors are multiline") + -- This error should be in the implicit includes + local line1, line2, line3, line4 = msg:match("^([^\n]*)\n([^\n]*)\n([^\n]*)\n([^\n]*)$") + assert(line1, "There is a line 1") + assert(line2, "There is a line 2") + assert(line3, "There is a line 3") + assert(line4, "There is a line 4") + assert(line1:find("does%-not%-exist"), "The first line must mention the error") + assert(line2 == "Implicit inclusion of does-not-exist :: 1", "The second line is where the error happened") + assert(line3 == "include does-not-exist", "The third line is the original line") + assert(line4 == " ^^^^^^^^^^^^^^", "The fourth line highlights relevant words") +end + +function suite.error_in_define() + local result, msg = compiler.compile(comp_context, "errorindefine") + assert(result == false, "Errors compiling should return false") + assert(type(msg) == "string", "Compilation errors should be strings") + assert(msg:find("\n"), "Compilation errors are multiline") + -- This error should be on line 3 word 3 of 'errorindefine' + local line1, line2, line3, line4 = msg:match("^([^\n]*)\n([^\n]*)\n([^\n]*)\n([^\n]*)$") + assert(line1, "There is a line 1") + assert(line2, "There is a line 2") + assert(line3, "There is a line 3") + assert(line4, "There is a line 4") + assert(line1:find("does_not_exist"), "The first line must mention the error") + assert(line2 == "real-errorindefine :: 3", "The second line is where the error happened") + assert(line3 == "define fish does_not_exist", "The third line is the original line") + assert(line4 == " ^^^^^^^^^^^^^^", "The fourth line highlights relevant words") +end + local count_ok = 0 for _, testname in ipairs(testnames) do -- print("Run: " .. testname) diff --git a/test/test-lace.error.lua b/test/test-lace.error.lua index 471935b..e50d0a9 100644 --- a/test/test-lace.error.lua +++ b/test/test-lace.error.lua @@ -50,7 +50,8 @@ end function suite.error_augmentation() local f, err = error.error("msg") local src = {} - error.augment(err, src, 10) + local aug = error.augment(err, src, 10) + assert(aug == err, "Augmentation should return the error") assert(err.source == src, "Augmented errors should contain their source data") assert(err.linenr == 10, "Augmented errors should contain their error line") end |