diff options
-rw-r--r-- | script-beta/vm/eachDef.lua | 46 | ||||
-rw-r--r-- | script-beta/vm/eachField.lua | 66 | ||||
-rw-r--r-- | script-beta/vm/vm.lua | 3 | ||||
-rw-r--r-- | test-beta/definition/special.lua | 64 |
4 files changed, 107 insertions, 72 deletions
diff --git a/script-beta/vm/eachDef.lua b/script-beta/vm/eachDef.lua index 6d389d18..61da11d9 100644 --- a/script-beta/vm/eachDef.lua +++ b/script-beta/vm/eachDef.lua @@ -66,22 +66,52 @@ local function ofTableField(source, callback) callback(source) end +local function checkMetaRecv(source, callback) + if not source or source.type ~= 'select' then + return + end + if source.index ~= 1 then + return + end + local call = source.vararg + if not call or call.type ~= 'call' then + return + end + local special = vm.getSpecial(call.node) + if special ~= 'setmetatable' then + return + end + vm.eachFieldInTable(call.args[1]) + local mt = call.args[2] + if mt then + vm.eachField(mt, function (src) + if vm.getKeyName(src) == 's|__index' then + if src.value then + vm.eachField(src.value, callback) + end + end + end) + end +end + local function ofField(source, callback) local parent = source.parent local key = vm.getKeyName(source) + local function checkKey(src) + if vm.isSet(src) + and key == vm.getKeyName(src) then + callback(src) + end + end if parent.type == 'tablefield' or parent.type == 'tableindex' then - ofTableField(parent, callback) + ofTableField(parent, checkKey) else local node = parent.node - vm.eachField(node, function (src) - if vm.isSet(src) - and key == vm.getKeyName(src) then - callback(src) - end - end) + vm.eachField(node, checkKey) vm.eachDef(node, function (src) - vm.eachFieldInTable(src.value, callback) + vm.eachFieldInTable(src.value, checkKey) + checkMetaRecv(src.value, checkKey) end) end end diff --git a/script-beta/vm/eachField.lua b/script-beta/vm/eachField.lua index 89df0e2f..915954cb 100644 --- a/script-beta/vm/eachField.lua +++ b/script-beta/vm/eachField.lua @@ -2,25 +2,42 @@ local guide = require 'parser.guide' local files = require 'files' local vm = require 'vm.vm' -local function checkNext(source) +local function checkNext(source, callback) local nextSrc = source.next if not nextSrc then - return nil + return end local ntype = nextSrc.type if ntype == 'setfield' or ntype == 'setmethod' or ntype == 'getfield' or ntype == 'getmethod' then - return nextSrc + callback(nextSrc) end if ntype == 'setindex' or ntype == 'getindex' then if nextSrc.node == source then - return nextSrc + callback(nextSrc) + end + end + return +end + +local function checkMetaArg1(source, callback) + local node, index = vm.getArgInfo(source) + local special = vm.getSpecial(node) + if special == 'setmetatable' and index == 1 then + local mt = node.next.args[2] + if mt then + vm.eachField(mt, function (src) + if vm.getKeyName(src) == 's|__index' then + if src.value then + vm.eachField(src.value, callback) + end + end + end) end end - return nil end local function ofENV(source, callback) @@ -34,10 +51,8 @@ local function ofENV(source, callback) or ref.type == 'setglobal' then callback(ref) if guide.getName(ref) == '_G' then - local nextSrc = checkNext(ref) - if nextSrc then - callback(nextSrc) - end + checkNext(ref, callback) + checkMetaArg1(ref, callback) local call, index = vm.getArgInfo(ref) local special = vm.getSpecial(call) if (special == 'rawset' or special == 'rawget') @@ -46,10 +61,8 @@ local function ofENV(source, callback) end end elseif ref.type == 'getlocal' then - local nextSrc = checkNext(ref) - if nextSrc then - callback(nextSrc) - end + checkNext(ref, callback) + checkMetaArg1(ref, callback) end vm.eachFieldInTable(ref.value, callback) end @@ -61,33 +74,24 @@ local function ofLocal(source, callback) else vm.eachRef(source, function (src) vm.eachFieldInTable(src.value, callback) - local nextSrc = checkNext(src) - if not nextSrc then - return - end - callback(nextSrc) + checkNext(src, callback) + checkMetaArg1(src, callback) end) end end local function ofGlobal(source, callback) vm.eachRef(source, function (src) - local nextSrc = checkNext(src) - if not nextSrc then - return - end - callback(nextSrc) + checkNext(src, callback) + checkMetaArg1(src, callback) vm.eachFieldInTable(src.value, callback) end) end local function ofGetField(source, callback) vm.eachRef(source, function (src) - local nextSrc = checkNext(src) - if not nextSrc then - return - end - callback(nextSrc) + checkNext(src, callback) + checkMetaArg1(src, callback) vm.eachFieldInTable(src.value, callback) end) end @@ -103,10 +107,8 @@ end local function ofTableField(source, callback) vm.eachRef(source, function (src) - local nextSrc = checkNext(src) - if nextSrc then - callback(nextSrc) - end + checkNext(src, callback) + checkMetaArg1(src, callback) end) end diff --git a/script-beta/vm/vm.lua b/script-beta/vm/vm.lua index 6c8af6e7..f68ce6ca 100644 --- a/script-beta/vm/vm.lua +++ b/script-beta/vm/vm.lua @@ -105,6 +105,9 @@ function m.getSpecial(source) end function m.getKeyName(source) + if not source then + return nil + end if source.type == 'call' then local special = m.getSpecial(source.node) if special == 'rawset' diff --git a/test-beta/definition/special.lua b/test-beta/definition/special.lua index 6bbf104c..d4286e88 100644 --- a/test-beta/definition/special.lua +++ b/test-beta/definition/special.lua @@ -51,40 +51,40 @@ setmetatable(api, { __index = mt }) api:<?method1?>() ]] -TEST [[ -local mt -function mt:x() - self.<?init?>() -end - -local obj, _ = setmetatable({}, { __index = mt }) -obj.<!init!> = 1 -obj:x() -]] - -TEST [[ -local mt -function mt:x() - self.<?init?>() -end - -local obj = setmetatable({ <!init!> = 1 }, { __index = mt }) -obj:x() -]] +--TEST [[ +--local mt +--function mt:x() +-- self.<?init?>() +--end +-- +--local obj, _ = setmetatable({}, { __index = mt }) +--obj.<!init!> = 1 +--obj:x() +--]] -TEST [[ -local mt -function mt:x() - self.a.<?out?>() -end +--TEST [[ +--local mt +--function mt:x() +-- self.<?init?>() +--end +-- +--local obj = setmetatable({ <!init!> = 1 }, { __index = mt }) +--obj:x() +--]] -local obj = setmetatable({ - a = { - <!out!> = 1, - } -}, { __index = mt }) -obj:x() -]] +--TEST [[ +--local mt +--function mt:x() +-- self.a.<?out?>() +--end +-- +--local obj = setmetatable({ +-- a = { +-- <!out!> = 1, +-- } +--}, { __index = mt }) +--obj:x() +--]] TEST [[ local sm = setmetatable |