summaryrefslogtreecommitdiff
path: root/script/parser
diff options
context:
space:
mode:
Diffstat (limited to 'script/parser')
-rw-r--r--script/parser/ast.lua18
-rw-r--r--script/parser/guide.lua158
-rw-r--r--script/parser/luadoc.lua15
3 files changed, 135 insertions, 56 deletions
diff --git a/script/parser/ast.lua b/script/parser/ast.lua
index 127bb08c..68fd59d7 100644
--- a/script/parser/ast.lua
+++ b/script/parser/ast.lua
@@ -333,10 +333,11 @@ local Defs = {
}
}
end
- return {
- type = 'nonstandardSymbol.comment',
- start = start1,
- finish = finish2 - 1,
+ PushComment {
+ start = start1,
+ finish = finish2 - 1,
+ semantic = true,
+ text = '',
}
end,
CCommentPrefix = function (start, finish, commentFinish)
@@ -356,10 +357,11 @@ local Defs = {
}
}
end
- return {
- type = 'nonstandardSymbol.comment',
- start = start,
- finish = commentFinish - 1,
+ PushComment {
+ start = start,
+ finish = commentFinish - 1,
+ semantic = true,
+ text = '',
}
end,
String = function (start, quote, str, finish)
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index 7a5be591..fed3577f 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -27,6 +27,8 @@ local function logWarn(...)
log.warn(...)
end
+---@class guide
+---@field debugMode boolean
local m = {}
m.ANY = {"<ANY>"}
@@ -1236,6 +1238,7 @@ function m.status(parentStatus, interface, deep)
searchDeep= parentStatus and parentStatus.searchDeep or deep or -999,
interface = parentStatus and parentStatus.interface or {},
deep = parentStatus and parentStatus.deep,
+ clock = parentStatus and parentStatus.clock or osClock(),
results = {},
}
if interface then
@@ -1365,6 +1368,10 @@ function m.getCallValue(source)
else
return
end
+ if call.node.special == 'pcall'
+ or call.node.special == 'xpcall' then
+ return call.args[1], call.args, index - 1
+ end
return call.node, call.args, index
end
@@ -1478,6 +1485,9 @@ function m.checkSameSimpleInValueOfSetMetaTable(status, func, start, pushQueue)
end
local call = func.parent
local args = call.args
+ if not args then
+ return
+ end
local obj = args[1]
local mt = args[2]
if obj then
@@ -1653,6 +1663,20 @@ function m.checkSameSimpleOfRefByDocSource(status, obj, start, pushQueue, mode)
end
end
+local function getArrayLevel(obj)
+ local level = 0
+ while true do
+ local parent = obj.parent
+ if parent.type == 'doc.type.array' then
+ level = level + 1
+ else
+ break
+ end
+ obj = parent
+ end
+ return level
+end
+
function m.checkSameSimpleByDoc(status, obj, start, pushQueue, mode)
if obj.type == 'doc.class.name'
or obj.type == 'doc.class' then
@@ -1705,7 +1729,7 @@ function m.checkSameSimpleByDoc(status, obj, start, pushQueue, mode)
if not parentDocTypeTable then
local state = m.getDocState(obj)
if state.type == 'doc.type' and mode == 'ref' then
- m.checkSameSimpleOfRefByDocSource(status, state, start, pushQueue, mode)
+ m.checkSameSimpleOfRefByDocSource(status, state, start - getArrayLevel(obj), pushQueue, mode)
end
end
return true
@@ -1833,6 +1857,7 @@ function m.searchSameFieldsCrossMethod(status, ref, start, pushQueue)
end
local function checkSameSimpleAndMergeFunctionReturnsByDoc(status, results, source, index, args)
+ source = m.getObjectValue(source) or source
if not source or source.type ~= 'function' then
return
end
@@ -1922,13 +1947,13 @@ function m.checkSameSimpleInCall(status, ref, start, pushQueue, mode)
return
end
status.share.crossCallCount = status.share.crossCallCount or 0
- if status.share.crossCallCount >= 5 then
- return
- end
- status.share.crossCallCount = status.share.crossCallCount + 1
-- 检查赋值是 semetatable() 的情况
m.checkSameSimpleInValueOfSetMetaTable(status, func, start, pushQueue)
-- 检查赋值是 func() 的情况
+ if status.share.crossCallCount >= 2 then
+ return
+ end
+ status.share.crossCallCount = status.share.crossCallCount + 1
local objs = m.checkSameSimpleInCallInSameFile(status, func, args, index)
if status.interface.call then
local cobjs = status.interface.call(func, args, index)
@@ -1941,15 +1966,22 @@ function m.checkSameSimpleInCall(status, ref, start, pushQueue, mode)
end
end
m.cleanResults(objs)
- local newStatus = m.status(status)
+ local mark = {}
for _, obj in ipairs(objs) do
+ if mark[obj] then
+ goto CONTINUE
+ end
+ local newStatus = m.status(status)
m.searchRefs(newStatus, obj, mode)
pushQueue(obj, start, true)
+ mark[obj] = true
+ for _, obj in ipairs(newStatus.results) do
+ pushQueue(obj, start, true)
+ mark[obj] = true
+ end
+ ::CONTINUE::
end
status.share.crossCallCount = status.share.crossCallCount - 1
- for _, obj in ipairs(newStatus.results) do
- pushQueue(obj, start, true)
- end
end
local function searchRawset(ref, results)
@@ -2320,6 +2352,7 @@ function m.pushResult(status, mode, ref, simple)
results[#results+1] = ref
elseif ref.type == 'doc.type.function'
or ref.type == 'doc.class.name'
+ or ref.type == 'doc.alias.name'
or ref.type == 'doc.field' then
results[#results+1] = ref
end
@@ -2362,6 +2395,7 @@ function m.pushResult(status, mode, ref, simple)
end
elseif ref.type == 'doc.type.function'
or ref.type == 'doc.class.name'
+ or ref.type == 'doc.alias.name'
or ref.type == 'doc.field' then
results[#results+1] = ref
end
@@ -2369,6 +2403,7 @@ function m.pushResult(status, mode, ref, simple)
results[#results+1] = ref
end
if m.isLiteral(ref)
+ and ref.parent
and ref.parent.type == 'callargs'
and ref ~= simple.node then
results[#results+1] = ref
@@ -2392,18 +2427,12 @@ function m.pushResult(status, mode, ref, simple)
elseif ref.type == 'setglobal'
or ref.type == 'getglobal' then
results[#results+1] = ref
- elseif ref.type == 'function' then
- results[#results+1] = ref
- elseif ref.type == 'table' then
- results[#results+1] = ref
elseif ref.type == 'call' then
if ref.node.special == 'rawset'
or ref.node.special == 'rawget' then
results[#results+1] = ref
end
- elseif ref.type == 'doc.type.function'
- or ref.type == 'doc.class.name'
- or ref.type == 'doc.field' then
+ elseif ref.type == 'doc.field' then
results[#results+1] = ref
end
elseif mode == 'deffield' then
@@ -2417,17 +2446,11 @@ function m.pushResult(status, mode, ref, simple)
results[#results+1] = ref
elseif ref.type == 'setglobal' then
results[#results+1] = ref
- elseif ref.type == 'function' then
- results[#results+1] = ref
- elseif ref.type == 'table' then
- results[#results+1] = ref
elseif ref.type == 'call' then
if ref.node.special == 'rawset' then
results[#results+1] = ref
end
- elseif ref.type == 'doc.type.function'
- or ref.type == 'doc.class.name'
- or ref.type == 'doc.field' then
+ elseif ref.type == 'doc.field' then
results[#results+1] = ref
end
end
@@ -2438,10 +2461,6 @@ function m.checkSameSimpleName(ref, sm)
return true
end
- if sm == m.ANY_DEF and m.isSet(ref) then
- return true
- end
-
if m.getSimpleName(ref) == sm then
return true
end
@@ -2567,6 +2586,9 @@ function m.searchSameFields(status, simple, mode)
local obj = queues[queueLen]
local start = starts[queueLen]
local force = forces[queueLen]
+ queues[queueLen] = nil
+ starts[queueLen] = nil
+ forces[queueLen] = nil
queueLen = queueLen - 1
local lock = locks[start]
if not lock then
@@ -2577,6 +2599,18 @@ function m.searchSameFields(status, simple, mode)
lock[obj] = true
max = max + 1
status.share.count = status.share.count + 1
+ if status.share.count % 10000 == 0 then
+ if TEST then
+ print('####', status.share.count, osClock() - status.clock)
+ end
+ if status.interface and status.interface.pulse then
+ status.interface.pulse()
+ end
+ end
+ --if status.share.count >= 100000 then
+ -- logWarn('Count too large!')
+ -- break
+ --end
m.checkSameSimple(status, simple, obj, start, force, mode, pushQueue)
if max >= 10000 then
logWarn('Queue too large!')
@@ -2584,7 +2618,7 @@ function m.searchSameFields(status, simple, mode)
end
end
end
- deallocQueue(queues, starts, forces)
+ --deallocQueue(queues, starts, forces)
end
function m.getCallerInSameFile(status, func)
@@ -2741,12 +2775,9 @@ end
--end
function m.getRefCache(status, obj, mode)
- local cache, globalCache
- if status.depth == 1
- and status.deep then
- globalCache = status.interface.cache and status.interface.cache() or {}
- end
- cache = status.share.refCache or {}
+ local isDeep = status.deep and status.depth == 1
+ local cache = status.share.refCache or {}
+ local deepCache = status.interface.cache and status.interface.cache() or {}
status.share.refCache = cache
if m.isGlobal(obj) then
obj = m.getKeyName(obj)
@@ -2754,22 +2785,42 @@ function m.getRefCache(status, obj, mode)
if not cache[mode] then
cache[mode] = {}
end
- if globalCache and not globalCache[mode] then
- globalCache[mode] = {}
+ if not deepCache[mode] then
+ deepCache[mode] = {}
+ end
+ local sourceCache
+ if isDeep then
+ sourceCache = deepCache[mode][obj]
+ else
+ sourceCache = cache[mode][obj]
end
- local sourceCache = globalCache and globalCache[mode][obj] or cache[mode][obj]
if sourceCache then
return sourceCache
end
sourceCache = {}
cache[mode][obj] = sourceCache
- if globalCache then
- globalCache[mode][obj] = sourceCache
+ if isDeep then
+ deepCache[mode][obj] = sourceCache
end
return nil, function (results)
for i = 1, #results do
sourceCache[i] = results[i]
end
+ if not isDeep then
+ return
+ end
+ if mode == 'ref'
+ or mode == 'def' then
+ for i = 1, #results do
+ local res = results[i]
+ if not deepCache[mode][res] then
+ cache[mode][res] = sourceCache
+ if isDeep then
+ deepCache[mode][res] = sourceCache
+ end
+ end
+ end
+ end
end
end
@@ -3230,6 +3281,13 @@ function m.inferCheckDoc(status, source)
end
return true
end
+ if source.type == 'doc.alias.name' then
+ local results = m.getDocTypeNames(status, m.getDocState(source).extends)
+ for _, res in ipairs(results) do
+ status.results[#status.results+1] = res
+ end
+ return true
+ end
end
function m.getVarargDocType(status, source)
@@ -3766,10 +3824,18 @@ function m.inferByDef(status, obj)
for _, src in ipairs(newStatus.results) do
local inferStatus = m.status(newStatus)
m.searchInfer(inferStatus, src)
- for _, infer in ipairs(inferStatus.results) do
- if not mark[infer.source] then
- mark[infer.source] = true
- status.results[#status.results+1] = infer
+ if #inferStatus.results == 0 then
+ status.results[#status.results+1] = {
+ type = 'any',
+ source = src,
+ level = 0,
+ }
+ else
+ for _, infer in ipairs(inferStatus.results) do
+ if not mark[infer.source] then
+ mark[infer.source] = true
+ status.results[#status.results+1] = infer
+ end
end
end
end
@@ -3797,7 +3863,7 @@ local function inferBySetOfLocal(status, source)
end
end
-function m.inferBySet(status, source)
+function m.inferByLocalRef(status, source)
if #status.results ~= 0 then
return
end
@@ -4183,18 +4249,16 @@ function m.searchInfer(status, obj)
return
end
+ m.inferByLocalRef(status, obj)
if status.deep then
tracy.ZoneBeginN('inferByDef')
m.inferByDef(status, obj)
tracy.ZoneEnd()
end
- m.inferBySet(status, obj)
m.inferByCall(status, obj)
m.inferByGetTable(status, obj)
m.inferByUnary(status, obj)
m.inferByBinary(status, obj)
- m.inferByCallReturn(status, obj)
- m.inferByPCallReturn(status, obj)
m.cleanInfers(status.results, obj)
if makeCache then
makeCache(status.results)
diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua
index 9ea674f4..47248ba4 100644
--- a/script/parser/luadoc.lua
+++ b/script/parser/luadoc.lua
@@ -257,6 +257,7 @@ local function parseTypeUnitArray(node)
finish = getFinish(),
node = node,
}
+ node.parent = result
return result
end
@@ -920,6 +921,7 @@ local function buildLuaDoc(comment)
type = 'doc.comment',
start = comment.start,
finish = comment.finish,
+ range = comment.finish,
comment = comment,
}
end
@@ -929,6 +931,7 @@ local function buildLuaDoc(comment)
parseTokens(doc, comment.start + startPos - 1)
local result = convertTokens()
if result then
+ result.range = comment.finish
local cstart = text:find('%S', result.finish - comment.start + 2)
if cstart and cstart < comment.finish then
result.comment = {
@@ -940,7 +943,17 @@ local function buildLuaDoc(comment)
end
end
- return result
+ if result then
+ return result
+ end
+
+ return {
+ type = 'doc.comment',
+ start = comment.start,
+ finish = comment.finish,
+ range = comment.finish,
+ comment = comment,
+ }
end
---当前行在注释doc前是否有代码