diff options
| author | OpportunityLiu <[email protected]> | 2019-07-27 17:08:06 +0800 |
|---|---|---|
| committer | OpportunityLiu <[email protected]> | 2019-07-28 14:45:01 +0800 |
| commit | 72f398835b6846c62a0d8a2a3d442689bf232df4 (patch) | |
| tree | e9c47a7d3783f044877f2d3f3eef2ebb51973cc5 /xmake/core/base/serialize.lua | |
| parent | 5f72124406a72da23a816b73c5fa0bd5ec404e57 (diff) | |
use table as stub
Diffstat (limited to 'xmake/core/base/serialize.lua')
| -rw-r--r-- | xmake/core/base/serialize.lua | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/xmake/core/base/serialize.lua b/xmake/core/base/serialize.lua index f41b1de2f..9faf1079c 100644 --- a/xmake/core/base/serialize.lua +++ b/xmake/core/base/serialize.lua @@ -20,7 +20,11 @@ -- -- define module: serialize -local serialize = serialize or {} +local serialize = serialize or {} +local stub = serialize._stub or {} +stub.isstub = setmetatable({}, { __tostring = function() return "stub indentifier" end }) +stub.__index = stub +serialize._stub = stub -- load modules local math = require("base/math") @@ -194,12 +198,15 @@ end function serialize._resolveref(root, fenv, ...) local pos = root - for i, v in ipairs({...}) do + local path = table.pack(...) + for i = 1, path.n do + local v = path[i] if type(v) ~= "string" and type(v) ~= "number" then return nil, "path segments in ref should be string or number" end if type(pos) ~= "table" then - return nil, "unable to resolve path: <root>." .. table.concat(path, ".", 1, i - 1) .. " is " .. tostring(pos) + table.insert(path, 1, "<root>") + return nil, "unable to resolve path: " .. table.concat(path, ".", 1, i) .. " is " .. tostring(pos) end pos = pos[v] end @@ -307,14 +314,23 @@ function serialize.save(object, opt) return (#dump < #result) and dump or result end +function stub:__call(root, fenv) + return self.resolver(root, fenv, table.unpack(self.params, 1, self.params.n)) +end + +function stub:__tostring() + local fparams = {} + for i = 1, self.params.n do + fparams[i] = serialize._make(self.params[i]) + end + return string.format("%s(%s)", self.name, table.concat(fparams, ", ")) +end + -- called by functions in deserialize environment -- create a function (called stub) to finish deserialization -function serialize._createstub(resolver, env, ...) +function serialize._createstub(name, resolver, env, ...) env.has_stub = true - local params = table.pack(...) - return function(root, fenv) - return resolver(root, fenv, table.unpack(params, 1, params.n)) - end + return setmetatable({ name = name, resolver = resolver, params = table.pack(...)}, stub) end -- after deserialization by load() @@ -324,16 +340,17 @@ end -- root root object -- fenv fenv of deserialzer caller function serialize._resolvestub(object, root, fenv) - if type(object) == "function" then + if type(object) ~= "table" then + return object + end + + if object.isstub == stub.isstub then local ok, result, errors = pcall(object, root, fenv) 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, fenv) @@ -354,13 +371,13 @@ function serialize._createenv() -- resolve reference function env.ref(...) -- load ref - return serialize._createstub(serialize._resolveref, env, ...) + return serialize._createstub("ref", serialize._resolveref, env, ...) end -- load function function env.func(...) -- load func - return serialize._createstub(serialize._resolvefunction, env, ...) + return serialize._createstub("func", serialize._resolvefunction, env, ...) end -- return new env |
