fix(parser): add support for .udt and .db file parsing and goto declaration
- extract_variables: Parse STRUCT fields in TYPE sections for .udt files - extract_types: Handle quoted type names and multiple type definitions - declaration handler: Extract quoted type names for goto declaration - Add filetype detection for .udt and .db files in nvim config
This commit is contained in:
+1
-1
@@ -558,7 +558,7 @@ function handlers.textDocument_declaration(params)
|
||||
local var_type = doc.variables[word].data_type
|
||||
if var_type then
|
||||
var_type = var_type:gsub("%s*;.*$", ""):gsub("%s*:=.*$", ""):gsub("^%s+", ""):gsub("%s+$", "")
|
||||
local type_name = var_type:match("([%w_]+)")
|
||||
local type_name = var_type:match('"([^"]+)"') or var_type:match("([%w_]+)")
|
||||
if type_name and type_name ~= word then
|
||||
table.insert(search_names, type_name)
|
||||
end
|
||||
|
||||
+94
-45
@@ -11,6 +11,7 @@ function M.extract_variables(content)
|
||||
end
|
||||
|
||||
local in_var_section = false
|
||||
local in_struct_section = false
|
||||
local var_type = "unknown"
|
||||
local current_block = nil
|
||||
|
||||
@@ -22,6 +23,7 @@ function M.extract_variables(content)
|
||||
if fb_name then
|
||||
current_block = { name = fb_name, kind = "function_block" }
|
||||
in_var_section = false
|
||||
in_struct_section = false
|
||||
return
|
||||
end
|
||||
|
||||
@@ -29,6 +31,7 @@ function M.extract_variables(content)
|
||||
if ob_name then
|
||||
current_block = { name = ob_name, kind = "organization_block" }
|
||||
in_var_section = false
|
||||
in_struct_section = false
|
||||
return
|
||||
end
|
||||
|
||||
@@ -36,6 +39,7 @@ function M.extract_variables(content)
|
||||
if fn_name then
|
||||
current_block = { name = fn_name, kind = "function" }
|
||||
in_var_section = false
|
||||
in_struct_section = false
|
||||
return
|
||||
end
|
||||
|
||||
@@ -44,6 +48,19 @@ function M.extract_variables(content)
|
||||
trimmed:match("^END_FUNCTION") then
|
||||
current_block = nil
|
||||
in_var_section = false
|
||||
in_struct_section = false
|
||||
return
|
||||
end
|
||||
|
||||
-- Handle TYPE sections (for .udt files with STRUCT)
|
||||
if trimmed:match("^TYPE") and (trimmed:match("^TYPE%s") or trimmed:match('^TYPE"') or trimmed == "TYPE") then
|
||||
in_struct_section = true
|
||||
var_type = "STRUCT_FIELD"
|
||||
return
|
||||
end
|
||||
|
||||
if trimmed:match("^END_TYPE") then
|
||||
in_struct_section = false
|
||||
return
|
||||
end
|
||||
|
||||
@@ -56,6 +73,7 @@ function M.extract_variables(content)
|
||||
trimmed:match("^VAR[_ ]*RETAIN%s*$") or
|
||||
trimmed:match("^VAR[_ ]*NON_RETAIN%s*$") then
|
||||
in_var_section = true
|
||||
in_struct_section = false
|
||||
if trimmed:match("INPUT") then var_type = "VAR_INPUT"
|
||||
elseif trimmed:match("OUTPUT") then var_type = "VAR_OUTPUT"
|
||||
elseif trimmed:match("IN_OUT") then var_type = "VAR_IN_OUT"
|
||||
@@ -72,7 +90,18 @@ function M.extract_variables(content)
|
||||
return
|
||||
end
|
||||
|
||||
if not in_var_section then return end
|
||||
if trimmed:match("^STRUCT%s*$") then
|
||||
in_struct_section = true
|
||||
var_type = "STRUCT_FIELD"
|
||||
return
|
||||
end
|
||||
|
||||
if trimmed:match("^END_STRUCT%s*$") then
|
||||
in_struct_section = false
|
||||
return
|
||||
end
|
||||
|
||||
if not in_var_section and not in_struct_section then return end
|
||||
|
||||
if trimmed:match("^%(%*") or trimmed:match("^%s*//") then
|
||||
return
|
||||
@@ -96,7 +125,7 @@ function M.extract_variables(content)
|
||||
brace_depth = brace_depth - 1
|
||||
elseif c == ":" and brace_depth == 0 then
|
||||
type_start = i
|
||||
break -- Only take the first : outside braces
|
||||
break
|
||||
end
|
||||
end
|
||||
local var_data_type = "unknown"
|
||||
@@ -141,70 +170,90 @@ function M.extract_types(content)
|
||||
local in_type_section = false
|
||||
local current_type = nil
|
||||
local brace_depth = 0
|
||||
local in_struct = false
|
||||
local pending_type_name = nil
|
||||
|
||||
local function extract_type_name(after_colon)
|
||||
if not after_colon then return nil end
|
||||
local quoted = after_colon:match('^%s*"([^"]+)"')
|
||||
if quoted then return quoted end
|
||||
return after_colon:match("^%s*(%w+)")
|
||||
end
|
||||
|
||||
for i, line in ipairs(lines) do
|
||||
local trimmed = line:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
|
||||
if trimmed:match("^TYPE$") or trimmed:match("^TYPE%s+:=") then
|
||||
local is_type_line = trimmed:match("^TYPE") and (trimmed:match("^TYPE%s") or trimmed:match('^TYPE"') or trimmed == "TYPE")
|
||||
|
||||
if is_type_line then
|
||||
in_type_section = true
|
||||
in_struct = false
|
||||
brace_depth = 0
|
||||
pending_type_name = trimmed:match('^TYPE%s+"([^"]+)') or trimmed:match("^TYPE%s+(%w+)")
|
||||
elseif in_type_section and trimmed:match("^END_TYPE") then
|
||||
in_type_section = false
|
||||
in_struct = false
|
||||
current_type = nil
|
||||
pending_type_name = nil
|
||||
elseif in_type_section then
|
||||
local type_name = trimmed:match("^(%w+):")
|
||||
if type_name then
|
||||
local struct_start = trimmed:find("{")
|
||||
local array_match = trimmed:find("ARRAY")
|
||||
|
||||
if struct_start then
|
||||
local type_name_with_struct = trimmed:match("^(%w+)%s+.-:%s+STRUCT")
|
||||
if type_name_with_struct then
|
||||
current_type = {
|
||||
name = type_name_with_struct,
|
||||
kind = "struct",
|
||||
fields = {},
|
||||
start_line = i - 1,
|
||||
}
|
||||
types[type_name_with_struct] = current_type
|
||||
in_struct = true
|
||||
pending_type_name = nil
|
||||
elseif trimmed:match("^STRUCT%s*$") then
|
||||
if pending_type_name then
|
||||
current_type = {
|
||||
name = type_name,
|
||||
name = pending_type_name,
|
||||
kind = "struct",
|
||||
fields = {},
|
||||
start_line = i - 1,
|
||||
}
|
||||
types[type_name] = current_type
|
||||
elseif array_match then
|
||||
local of_type = trimmed:match("OF%s+(%w+)")
|
||||
if of_type then
|
||||
current_type = {
|
||||
name = type_name,
|
||||
kind = "array",
|
||||
element_type = of_type,
|
||||
start_line = i - 1,
|
||||
}
|
||||
types[type_name] = current_type
|
||||
end
|
||||
else
|
||||
local field_type = trimmed:match(":%s*(%w+)")
|
||||
if field_type then
|
||||
current_type = {
|
||||
name = type_name,
|
||||
kind = "alias",
|
||||
base_type = field_type,
|
||||
start_line = i - 1,
|
||||
}
|
||||
types[type_name] = current_type
|
||||
end
|
||||
types[pending_type_name] = current_type
|
||||
pending_type_name = nil
|
||||
end
|
||||
end
|
||||
|
||||
if current_type and current_type.kind == "struct" then
|
||||
for open in line:gmatch("{") do brace_depth = brace_depth + 1 end
|
||||
for close in line:gmatch("}") do brace_depth = brace_depth - 1 end
|
||||
|
||||
local field_name = line:match("^%s*(%w+):")
|
||||
if field_name and field_name ~= current_type.name then
|
||||
local field_type = line:match(":%s*(%w+)")
|
||||
in_struct = true
|
||||
elseif trimmed:match("^END_STRUCT%s*$") then
|
||||
in_struct = false
|
||||
elseif in_struct and current_type and current_type.fields then
|
||||
local field_name = line:match("^%s*(%w+)%s*:%s*")
|
||||
if field_name then
|
||||
local after_colon = line:match(":%s*(.+)")
|
||||
local field_type = after_colon and extract_type_name(after_colon)
|
||||
table.insert(current_type.fields, {
|
||||
name = field_name,
|
||||
type = field_type or "unknown",
|
||||
})
|
||||
end
|
||||
|
||||
if brace_depth == 0 then
|
||||
current_type = nil
|
||||
elseif not in_struct and not pending_type_name then
|
||||
local array_match = trimmed:match("^(%w+)%s+:%s+ARRAY")
|
||||
if array_match then
|
||||
local of_type = trimmed:match("OF%s+(%w+)")
|
||||
current_type = {
|
||||
name = array_match,
|
||||
kind = "array",
|
||||
element_type = of_type,
|
||||
start_line = i - 1,
|
||||
}
|
||||
types[array_match] = current_type
|
||||
else
|
||||
local alias_match = trimmed:match("^(%w+)%s+:%s+(%w+)")
|
||||
if alias_match then
|
||||
local base_type = extract_type_name(trimmed:match(":%s+(.+)$"))
|
||||
current_type = {
|
||||
name = alias_match,
|
||||
kind = "alias",
|
||||
base_type = base_type,
|
||||
start_line = i - 1,
|
||||
}
|
||||
types[alias_match] = current_type
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user