Guest User

Untitled

a guest
Aug 31st, 2024
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.49 KB | None | 0 0
  1. ---@class SignatureParserState
  2. ---@field valid boolean
  3. ---@field params string[]
  4. ---@field returnType string
  5.  
  6. ---@return SignatureParserState
  7. local function getState()
  8.     return {
  9.         valid = false,
  10.         params = {},
  11.         returnType = "nil",
  12.     }
  13. end
  14.  
  15. local function split(text, sep)
  16.     sep = sep or ":"
  17.     local fields = {}
  18.     local pattern = string.format("([^%s]+)", sep)
  19.     ---@diagnostic disable-next-line: no-unknown
  20.     local _ = text:gsub(pattern, function(c)
  21.         table.insert(fields, c)
  22.     end)
  23.     return fields
  24. end
  25.  
  26. ---@param str string
  27. ---@return string
  28. local function trim(str)
  29.     return str:match("^%s*(.-)%s*$")
  30. end
  31.  
  32. ---@param input string
  33. ---@return diff[]
  34. local function injectFunctionDefinitions(input)
  35.     local diffs = {}
  36.     local cursor = 0
  37.     local state = getState()
  38.     local lastClass = "global"
  39.     local lastParentClass = "global"
  40.  
  41.     ---@type integer[]?
  42.     local override
  43.  
  44.     for line in string.gmatch(input .. "\n", "(.-)\n") do
  45.         local commentStart = line:find("---")
  46.         if commentStart and #line:sub(1, commentStart - 1):gsub(" ", ""):gsub("\t", "") == 0 then
  47.             local trimmedLine = line:sub(commentStart)
  48.             if trimmedLine:sub(1, 9) == "---@param" then
  49.                 state.valid = true
  50.  
  51.                 local param = trimmedLine:sub(11)
  52.                 ---@type string, string
  53.                 local name, typeStr
  54.                 if param:find("{") or param:find("<") or param:find(":") then
  55.                     name = param:match("^([^%s]*)")
  56.                     typeStr = "any"
  57.                 else
  58.                     name, typeStr = param:match("^([^%s]*)%s*([^%s]*)%s*(.*)")
  59.                 end
  60.  
  61.                 table.insert(state.params, {
  62.                     name or ("arg" .. #state.params),
  63.                     typeStr or "any",
  64.                 })
  65.             elseif trimmedLine:sub(1, 10) == "---@return" then
  66.                 state.valid = true
  67.                 local f = split(trimmedLine, " ")
  68.                 state.returnType = f[2] or "nil"
  69.             elseif trimmedLine:sub(1, 9) == "---@class" then
  70.                 local c = split(trimmedLine:sub(11):gsub("%(exact%) ", ""), ":")
  71.                 lastClass = trim(c[1] or "global")
  72.                 lastParentClass = trim(c[2] or "global")
  73.             elseif trimmedLine:sub(1) == "---@override" then
  74.                 override = { cursor + commentStart, cursor + #line }
  75.             elseif trimmedLine:sub(1, 3) == "---" then
  76.                 state.valid = true
  77.             end
  78.         elseif line:find("function") and line:find(":") then
  79.             local method = line:sub(
  80.                 (line:find(":") or 0) + 1,
  81.                 (line:find("%(") or 0) - 1
  82.             )
  83.  
  84.             if override then
  85.                 if lastParentClass ~= "global" then
  86.                     local text = "---@type def." .. lastParentClass .. "." .. method
  87.                     local textSee = "---@see " .. lastParentClass .. "." .. method
  88.                     table.insert(diffs, {
  89.                         start  = override[1],
  90.                         finish = override[2],
  91.                         text   = textSee .. "\n" .. text,
  92.                     })
  93.                     override = nil
  94.                 end
  95.             elseif state.valid and lastClass ~= "global" then
  96.                 local parts = {}
  97.                 for _, var in ipairs(state.params) do
  98.                     table.insert(parts, var[1] .. " : " .. var[2])
  99.                 end
  100.                 local text = "---@alias def." ..
  101.                     lastClass .. "." .. method .. " " ..
  102.                     "fun(self: " .. lastClass .. ", " .. table.concat(parts, ", ") .. ") : " .. state.returnType
  103.                 table.insert(diffs, {
  104.                     start  = cursor,
  105.                     finish = cursor - 1,
  106.                     text   = "\n" .. text,
  107.                 })
  108.             end
  109.         elseif state.valid then
  110.             state = getState()
  111.         end
  112.  
  113.         ---@type integer
  114.         cursor = cursor + #line + 1
  115.     end
  116.  
  117.     return diffs
  118. end
  119.  
  120. ---@class diff
  121. ---@field start  integer # The number of bytes at the beginning of the replacement
  122. ---@field finish integer # The number of bytes at the end of the replacement
  123. ---@field text   string  # What to replace
  124.  
  125. ---@param  uri  string # The uri of file
  126. ---@param  text string # The content of file
  127. ---@return nil|diff[]
  128. function OnSetText(uri, text)
  129.     return injectFunctionDefinitions(text)
  130. end
  131.  
Advertisement
Add Comment
Please, Sign In to add comment