feat: add builtin types/functions to diagnostics and completions
Files Modified/Created: - src/builtin_instructions.lua - NEW: Contains all TIA Portal built-in types, FBs, and functions - src/diagnostics.lua - Added missing data types + builtin instruction checking - src/main.lua - Added completion support for built-in types/F Bs/functions - src/plc_json.lua - Added .db file parsing + BOM handling fixes - lua/scl/blink_cmp_source.lua - Extended completion with all built-in types/F Bs/functions - src/node-types.json - Added node types for parser - AGENTS.md - Updated documentation Features Added: 1. Diagnostics - No more false "Unknown data type" warnings for: - All elementary types (USINT, SINT, UINT, UDINT, LINT, ULINT, TOD, DTL, etc.) - Timer/counter types (IEC_TON, TOF, TP, CTU, CTD, CTUD) - TIA Portal built-in FBs and functions 2. Auto-completion - Shows in VAR section after :: - 28 elementary data types - 23 built-in function blocks (TON, TOF, TP, CTU, CTD, CTUD, R_TRIG, F_TRIG, etc.) - 80+ built-in functions (ADD, SUB, MUL, DIV, SIN, COS, SQRT, etc.)
This commit is contained in:
+68
-2
@@ -85,24 +85,33 @@ local function parse_scl_type_file(content)
|
||||
local current_type_name = nil
|
||||
local pending_type_name = nil
|
||||
|
||||
content = content:gsub("^([\239\187\191]+)", "")
|
||||
|
||||
local lines = {}
|
||||
for line in content:gmatch("[^\n]+") do table.insert(lines, line) end
|
||||
|
||||
for i, line in ipairs(lines) do
|
||||
local trimmed = line:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
|
||||
if trimmed:match("^TYPE%s*:?%s*$") then
|
||||
if trimmed:match("^TYPE%s") or trimmed:match('^TYPE"') or trimmed == "TYPE" then
|
||||
in_type = true
|
||||
in_struct = false
|
||||
current_type_name = nil
|
||||
pending_type_name = nil
|
||||
local type_name = trimmed:match('TYPE%s+"([^"]+)"') or trimmed:match("^TYPE%s+(%w+)")
|
||||
if type_name then
|
||||
pending_type_name = type_name
|
||||
end
|
||||
in_struct = false
|
||||
current_type_name = nil
|
||||
pending_type_name = nil
|
||||
elseif trimmed:match("^END_TYPE") then
|
||||
in_type = false
|
||||
in_struct = false
|
||||
current_type_name = nil
|
||||
pending_type_name = nil
|
||||
elseif in_type then
|
||||
if trimmed:match("^END_STRUCT") then
|
||||
if trimmed:match("^END_STRUCT") or trimmed:match("^END_STRUCT;") then
|
||||
in_struct = false
|
||||
current_type_name = nil
|
||||
pending_type_name = nil
|
||||
@@ -144,6 +153,48 @@ local function parse_scl_type_file(content)
|
||||
return types
|
||||
end
|
||||
|
||||
local function parse_db_file(content)
|
||||
local types = {}
|
||||
local in_var = false
|
||||
local current_type_name = nil
|
||||
|
||||
content = content:gsub("^([\239\187\191]+)", "")
|
||||
|
||||
local lines = {}
|
||||
for line in content:gmatch("[^\n]+") do table.insert(lines, line) end
|
||||
|
||||
for i, line in ipairs(lines) do
|
||||
local trimmed = line:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
|
||||
if trimmed:match('^DATA_BLOCK%s+"([^"]+)"') then
|
||||
current_type_name = trimmed:match('^DATA_BLOCK%s+"([^"]+)"')
|
||||
types[current_type_name] = {
|
||||
name = current_type_name,
|
||||
kind = "struct",
|
||||
fields = {},
|
||||
source = "db_file",
|
||||
}
|
||||
elseif trimmed:match("^END_VAR") then
|
||||
in_var = false
|
||||
elseif trimmed:match("^VAR%s*$") or trimmed:match("^VAR ") then
|
||||
in_var = true
|
||||
elseif in_var and current_type_name and types[current_type_name] and trimmed ~= "" and not trimmed:match("^//") then
|
||||
local field_name = line:match("^%s*(%w+)%s*:")
|
||||
if field_name then
|
||||
local field_type = line:match(":%s*([%w_]+)")
|
||||
if field_type then
|
||||
table.insert(types[current_type_name].fields, {
|
||||
name = field_name,
|
||||
type = field_type,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return types
|
||||
end
|
||||
|
||||
function M.load_types_from_workspace(root_dir)
|
||||
local types = {}
|
||||
|
||||
@@ -213,6 +264,21 @@ function M.load_types_from_workspace(root_dir)
|
||||
end
|
||||
end
|
||||
|
||||
-- Also scan for .db files
|
||||
local db_files = scan_files_recursive(root_dir, "*.db")
|
||||
for _, filepath in ipairs(db_files) do
|
||||
local content = run_command("cat " .. filepath:gsub(" ", "\\ "))
|
||||
if content then
|
||||
local db_types = parse_db_file(content)
|
||||
for name, typ in pairs(db_types) do
|
||||
typ.source = "db_file"
|
||||
if not types[name] then
|
||||
types[name] = typ
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return types
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user