summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2012-07-17 18:01:08 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2012-07-17 18:01:08 +0100
commit71eacf913d42c2c26435316de98a1c924fb7f185 (patch)
treec696f912ba072ac781d41798d3197e0a7e05d4d4
parent141e868d75c56ede9165d361bcdc84e162443753 (diff)
downloadlace-71eacf913d42c2c26435316de98a1c924fb7f185.tar.gz
LACE: Ensure errors are rendered properly and exposed during compilation
-rw-r--r--lib/lace/compiler.lua34
-rw-r--r--lib/lace/error.lua1
-rw-r--r--test/test-lace.compile-errorindefine.rules5
-rw-r--r--test/test-lace.compiler.lua36
-rw-r--r--test/test-lace.error.lua3
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