summaryrefslogtreecommitdiff
path: root/script/parser
diff options
context:
space:
mode:
Diffstat (limited to 'script/parser')
-rw-r--r--script/parser/guide.lua42
-rw-r--r--script/parser/luadoc.lua68
-rw-r--r--script/parser/newparser.lua9
3 files changed, 95 insertions, 24 deletions
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index 060c5018..fffba639 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -58,6 +58,10 @@ local type = type
---@field step parser.object
---@field redundant { max: integer, passed: integer }
---@field filter parser.object
+---@field loc string
+---@field keyword integer[]
+---@field casts parser.object[]
+---@field mode? '+' | '-'
---@field hasGoTo? true
---@field hasReturn? true
---@field hasBreak? true
@@ -148,6 +152,8 @@ local childMap = {
['doc.version'] = {'#versions'},
['doc.diagnostic'] = {'#names'},
['doc.as'] = {'as'},
+ ['doc.cast'] = {'loc', '#casts'},
+ ['doc.cast.block'] = {'extends'},
}
---@type table<string, fun(obj: parser.object, list: parser.object[])>
@@ -420,7 +426,7 @@ function m.getUri(obj)
return ''
end
----@return parser.object
+---@return parser.object?
function m.getENV(source, start)
if not start then
start = 1
@@ -454,19 +460,17 @@ function m.getFunctionVarArgs(func)
end
--- 获取指定区块中可见的局部变量
----@param block table
----@param name string {comment = '变量名'}
----@param pos integer {comment = '可见位置'}
-function m.getLocal(block, name, pos)
- block = m.getBlock(block)
- for _ = 1, 10000 do
- if not block then
- return nil
- end
- local locals = block.locals
- local res
+---@param source parser.object
+---@param name string # 变量名
+---@param pos integer # 可见位置
+---@return parser.object?
+function m.getLocal(source, name, pos)
+ local root = m.getRoot(source)
+ local res
+ m.eachSourceContain(root, pos, function (src)
+ local locals = src.locals
if not locals then
- goto CONTINUE
+ return
end
for i = 1, #locals do
local loc = locals[i]
@@ -479,13 +483,8 @@ function m.getLocal(block, name, pos)
end
end
end
- if res then
- return res, res
- end
- ::CONTINUE::
- block = m.getParentBlock(block)
- end
- error('guide.getLocal overstack')
+ end)
+ return res
end
--- 获取指定区块中所有的可见局部变量名称
@@ -610,6 +609,9 @@ local function addChilds(list, obj)
end
--- 遍历所有包含position的source
+---@param ast parser.object
+---@param position integer
+---@param callback fun(src: parser.object)
function m.eachSourceContain(ast, position, callback)
local list = { ast }
local mark = {}
diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua
index 3b50db34..e10ef356 100644
--- a/script/parser/luadoc.lua
+++ b/script/parser/luadoc.lua
@@ -53,6 +53,7 @@ Symbol <- ({} {
/ '...'
/ '['
/ ']'
+ / '-' !'-'
} {})
-> Symbol
]], {
@@ -1205,6 +1206,70 @@ local docSwitch = util.switch()
result.finish = getFinish()
return result
end)
+ : case 'cast'
+ : call(function ()
+ local result = {
+ type = 'doc.cast',
+ start = getFinish(),
+ finish = getFinish(),
+ casts = {},
+ }
+
+ local loc = parseName('doc.cast.name', result)
+ if not loc then
+ pushWarning {
+ type = 'LUADOC_MISS_LOCAL_NAME',
+ start = getFinish(),
+ finish = getFinish(),
+ }
+ return result
+ end
+
+ result.loc = loc
+ result.finish = loc.finish
+
+ while true do
+ local block = {
+ type = 'doc.cast.block',
+ parent = result,
+ start = getFinish(),
+ finish = getFinish(),
+ }
+ result.casts[#result.casts+1] = block
+ if checkToken('symbol', '+', 1) then
+ block.mode = '+'
+ nextToken()
+ block.start = getStart()
+ block.finish = getFinish()
+ elseif checkToken('symbol', '-', 1) then
+ block.mode = '-'
+ nextToken()
+ block.start = getStart()
+ block.finish = getFinish()
+ end
+
+ if checkToken('symbol', '?', 1) then
+ block.optional = true
+ nextToken()
+ block.start = block.start or getStart()
+ block.finish = block.finish
+ else
+ block.extends = parseType(block)
+ if block.extends then
+ block.start = block.start or block.extends.start
+ block.finish = block.extends.finish
+ end
+ end
+
+ if checkToken('symbol', ',', 1) then
+ nextToken()
+ else
+ break
+ end
+ end
+
+ return result
+ end)
local function convertTokens()
local tp, text = nextToken()
@@ -1313,6 +1378,9 @@ local function isNextLine(binded, doc)
return false
end
end
+ if doc.type == 'doc.cast' then
+ return false
+ end
local lastRow = guide.rowColOf(lastDoc.finish)
local newRow = guide.rowColOf(doc.start)
return newRow - lastRow == 1
diff --git a/script/parser/newparser.lua b/script/parser/newparser.lua
index 4c58ead6..630c12c2 100644
--- a/script/parser/newparser.lua
+++ b/script/parser/newparser.lua
@@ -691,9 +691,6 @@ local function parseLocalAttrs()
end
local function createLocal(obj, attrs)
- if not obj then
- return nil
- end
obj.type = 'local'
obj.effect = obj.finish
@@ -2893,7 +2890,11 @@ local function parseLocal()
pushActionIntoCurrentChunk(loc)
skipSpace()
parseMultiVars(loc, parseName, true)
- loc.effect = lastRightPosition()
+ if loc.value then
+ loc.effect = loc.value.finish
+ else
+ loc.effect = loc.finish
+ end
return loc
end