summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpportunityLiu <[email protected]>2019-07-26 13:27:28 +0800
committerOpportunityLiu <[email protected]>2019-07-28 14:45:01 +0800
commitd0216ee6b330bfa8fe894210f8d6bc1517d7e42d (patch)
tree7a4cb9fbd7359ec93d52e0ff8ffa46271487539c
parent55b29ab3799917fa04b55ac5c8273eadb6045b39 (diff)
add stub
-rw-r--r--xmake/core/base/serialize.lua42
1 files changed, 41 insertions, 1 deletions
diff --git a/xmake/core/base/serialize.lua b/xmake/core/base/serialize.lua
index 252a223cc..8e57661ce 100644
--- a/xmake/core/base/serialize.lua
+++ b/xmake/core/base/serialize.lua
@@ -25,6 +25,7 @@ local _ENV = serialize._ENV or {}
-- load modules
local math = require("base/math")
+local table = require("base/table")
-- save original interfaces
serialize._dump = serialize._dump or string._dump or string.dump
@@ -33,6 +34,36 @@ serialize._dump = serialize._dump or string._dump or string.dump
_ENV.nan = math.nan
_ENV.inf = math.huge
+function serialize._createstub(resolver, ...)
+ _ENV.has_stub = true
+ local params = table.pack(...)
+ return function(root, env)
+ return resolver(root, env, table.unpack(params, 1, params.n))
+ end
+end
+
+function serialize._resolvestub(object, root, env)
+ if type(object) == "function" then
+ local ok, result, errors = pcall(object, root, env)
+ if ok and errors == nil then
+ return result
+ end
+ return nil, errors or result or "unspecified error"
+ end
+ if type(object) ~= "table" then
+ return object
+ end
+
+ for k, v in pairs(object) do
+ local result, errors = serialize._resolvestub(v, root, env)
+ if errors ~= nil then
+ return nil, errors
+ end
+ object[k] = result
+ end
+ return object
+end
+
function serialize._makestring(str, opt, level)
return string.format("%q", str)
end
@@ -133,12 +164,16 @@ function serialize._makefunction(func, opt, level)
return string.format("func%q", funccode)
end
+function serialize._resolvefunction(root, env, funccode)
+ return load(funccode, "=(deserialized code)", "b", env)
+end
+
-- load function
function _ENV.func(funccode)
-- type guard
assert(type(funccode) == "string", "func should called with a string")
-- load func
- return loadstring(funccode, "=(deserialized code)")
+ return serialize._createstub(serialize._resolvefunction, funccode)
end
-- make string with the level
@@ -253,6 +288,11 @@ function serialize._load(str)
local ok, object = pcall(script)
if ok then
result = object
+ if _ENV.has_stub then
+ _ENV.has_stub = false
+ local env = debug.getfenv(debug.getinfo(3, "f").func)
+ result, errors = serialize._resolvestub(result, result, env)
+ end
else
-- error
errors = tostring(object)