fix: UDT type parsing and member access hover
- Fix UDT TYPE parsing: don't clear pending_type_name on VERSION/TITLE lines - Fix UDT field type extraction: handle attribute blocks before colon - Add comment capture for UDT type definitions - Add better error messages when member resolution fails - Handle quoted type names in field declarations
This commit is contained in:
+26
-9
@@ -84,6 +84,7 @@ local function parse_scl_type_file(content)
|
|||||||
local in_struct = false
|
local in_struct = false
|
||||||
local current_type_name = nil
|
local current_type_name = nil
|
||||||
local pending_type_name = nil
|
local pending_type_name = nil
|
||||||
|
local pending_type_comment = nil
|
||||||
|
|
||||||
local in_fb = false
|
local in_fb = false
|
||||||
local fb_name = nil
|
local fb_name = nil
|
||||||
@@ -132,7 +133,7 @@ local function parse_scl_type_file(content)
|
|||||||
current_fb_section = "output"
|
current_fb_section = "output"
|
||||||
elseif trimmed:match("^VAR_IN_OUT") then
|
elseif trimmed:match("^VAR_IN_OUT") then
|
||||||
current_fb_section = "inout"
|
current_fb_section = "inout"
|
||||||
elseif trimmed:match("^VAR%s") or trimmed:match("^VAR%s*$") then
|
elseif trimmed:match("^VAR%s") or trimmed:match("^VAR%s$") then
|
||||||
current_fb_section = nil
|
current_fb_section = nil
|
||||||
elseif trimmed:match("^VAR_TEMP") then
|
elseif trimmed:match("^VAR_TEMP") then
|
||||||
current_fb_section = nil
|
current_fb_section = nil
|
||||||
@@ -169,33 +170,42 @@ local function parse_scl_type_file(content)
|
|||||||
in_struct = false
|
in_struct = false
|
||||||
current_type_name = nil
|
current_type_name = nil
|
||||||
pending_type_name = nil
|
pending_type_name = nil
|
||||||
|
pending_type_comment = nil
|
||||||
local type_name = trimmed:match('TYPE%s+"([^"]+)"') or trimmed:match("^TYPE%s+(%w+)")
|
local type_name = trimmed:match('TYPE%s+"([^"]+)"') or trimmed:match("^TYPE%s+(%w+)")
|
||||||
if type_name then
|
if type_name then
|
||||||
pending_type_name = type_name
|
pending_type_name = type_name
|
||||||
end
|
end
|
||||||
in_struct = false
|
|
||||||
current_type_name = nil
|
|
||||||
pending_type_name = nil
|
|
||||||
elseif trimmed:match("^END_TYPE") then
|
elseif trimmed:match("^END_TYPE") then
|
||||||
in_type = false
|
in_type = false
|
||||||
in_struct = false
|
in_struct = false
|
||||||
current_type_name = nil
|
current_type_name = nil
|
||||||
pending_type_name = nil
|
pending_type_name = nil
|
||||||
|
pending_type_comment = nil
|
||||||
elseif in_type then
|
elseif in_type then
|
||||||
if trimmed:match("^END_STRUCT") or trimmed:match("^END_STRUCT;") then
|
-- Capture comments before STRUCT
|
||||||
|
if trimmed:match("^//") then
|
||||||
|
local comment = trimmed:match("^//%s*(.+)$")
|
||||||
|
if comment and pending_type_name then
|
||||||
|
pending_type_comment = comment
|
||||||
|
end
|
||||||
|
elseif trimmed:match("^END_STRUCT") or trimmed:match("^END_STRUCT;") then
|
||||||
in_struct = false
|
in_struct = false
|
||||||
current_type_name = nil
|
current_type_name = nil
|
||||||
pending_type_name = nil
|
pending_type_name = nil
|
||||||
|
pending_type_comment = nil
|
||||||
elseif trimmed:match("^STRUCT") then
|
elseif trimmed:match("^STRUCT") then
|
||||||
if pending_type_name then
|
if pending_type_name then
|
||||||
current_type_name = pending_type_name
|
current_type_name = pending_type_name
|
||||||
in_struct = true
|
in_struct = true
|
||||||
types[pending_type_name] = { name = pending_type_name, kind = "struct", fields = {}, source = "data_types_folder" }
|
types[pending_type_name] = { name = pending_type_name, kind = "struct", fields = {}, source = "data_types_folder", comment = pending_type_comment }
|
||||||
pending_type_name = nil
|
pending_type_name = nil
|
||||||
|
pending_type_comment = nil
|
||||||
end
|
end
|
||||||
elseif not in_struct and trimmed:match("^%w+%s*:") and not trimmed:match("^STRUCT") then
|
elseif not in_struct and trimmed:match("^%w+%s*:") and not trimmed:match("^STRUCT") then
|
||||||
|
-- This is an alias type declaration (TypeName : BaseType;)
|
||||||
|
-- NOT VERSION, TITLE, etc.
|
||||||
local type_name = trimmed:match("^(%w+)%s*:")
|
local type_name = trimmed:match("^(%w+)%s*:")
|
||||||
if type_name then
|
if type_name and type_name ~= "VERSION" and type_name ~= "TITLE" then
|
||||||
local next_line = lines[i + 1]
|
local next_line = lines[i + 1]
|
||||||
local next_trimmed = next_line and next_line:gsub("^%s+", ""):gsub("%s+$", "")
|
local next_trimmed = next_line and next_line:gsub("^%s+", ""):gsub("%s+$", "")
|
||||||
if next_trimmed and next_trimmed:match("^STRUCT") then
|
if next_trimmed and next_trimmed:match("^STRUCT") then
|
||||||
@@ -209,9 +219,16 @@ local function parse_scl_type_file(content)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif in_struct and current_type_name and types[current_type_name] then
|
elseif in_struct and current_type_name and types[current_type_name] then
|
||||||
local field_name = line:match("^%s*(%w+)%s*:")
|
local field_name = line:match("^%s*(%w+)%s*{") or line:match("^%s*(%w+)%s*:")
|
||||||
if field_name and field_name ~= "END_STRUCT" then
|
if field_name and field_name ~= "END_STRUCT" then
|
||||||
local field_type = line:match(":%s*([%w_]+)")
|
-- Remove attribute blocks before extracting type
|
||||||
|
local clean_line = line:gsub("%b{}", "")
|
||||||
|
-- Extract field type - handle both quoted and unquoted types
|
||||||
|
local field_type = clean_line:match(':%s*"([^"]+)"') or clean_line:match(":%s*([%w_]+)")
|
||||||
|
-- Also handle array types
|
||||||
|
if not field_type then
|
||||||
|
field_type = clean_line:match(":%s*(ARRAY.+)")
|
||||||
|
end
|
||||||
local field_comment = line:match("//%s*(.+)$") or line:match("%(%*(.-)%*%)")
|
local field_comment = line:match("//%s*(.+)$") or line:match("%(%*(.-)%*%)")
|
||||||
table.insert(types[current_type_name].fields, {
|
table.insert(types[current_type_name].fields, {
|
||||||
name = field_name,
|
name = field_name,
|
||||||
|
|||||||
Reference in New Issue
Block a user