From a69a12d1e1e5ee0bfab299350e5d707ff7b2e744 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Sat, 14 Dec 2024 11:06:09 -0300 Subject: [PATCH] Cleanup references when analyzing multiple times (for LSPs) --- lualib/nelua/analyzer.lua | 19 +++++++++++++++++++ lualib/nelua/astnode.lua | 5 +++++ lualib/nelua/cdefs.lua | 16 ++++++++-------- lualib/nelua/utils/tabler.lua | 22 +++++++++++++++++----- 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/lualib/nelua/analyzer.lua b/lualib/nelua/analyzer.lua index b3c482bb..33928552 100644 --- a/lualib/nelua/analyzer.lua +++ b/lualib/nelua/analyzer.lua @@ -20,6 +20,12 @@ local analyzer = {} local luatype = type local primtypes = typedefs.primtypes +local builtin_attrs = typedefs.builtin_attrs +local orig_primtypes = {} +local orig_builtin_attrs = {} +tabler.updatecopymt(orig_primtypes, primtypes) +tabler.updatecopymt(orig_builtin_attrs, builtin_attrs) + local visitors = {} analyzer.visitors = visitors @@ -3392,6 +3398,19 @@ function visitors.BinaryOp(context, node, opts) end function analyzer.analyze(context) + -- this is necessary to support calling analyzer multiple times (eg in LSPs), + -- previous analyzer may have filled references in builtin symbols and primtypes + -- so we cleanup before + for k,v in pairs(orig_primtypes) do + local primtype = tabler.mirror(primtypes[k], v) + if primtype.metafields then + tabler.clear(primtype.metafields) + end + end + for k,v in pairs(orig_builtin_attrs) do + tabler.mirror(builtin_attrs[k], v) + end + -- save current analyzing context local old_current_context = analyzer.current_context analyzer.current_context = context diff --git a/lualib/nelua/astnode.lua b/lualib/nelua/astnode.lua index caf8bba2..ac806b25 100644 --- a/lualib/nelua/astnode.lua +++ b/lualib/nelua/astnode.lua @@ -93,6 +93,11 @@ function ASTNode._create(mt, ...) }, mt) end +-- Creates unique id counter of AST nodes. +function ASTNode.reset_uid_counter() + uid = 0 +end + -- Allows calling ASTNode to create a new node. getmetatable(ASTNode).__call = ASTNode._create diff --git a/lualib/nelua/cdefs.lua b/lualib/nelua/cdefs.lua index 9d156d9e..70b56e39 100644 --- a/lualib/nelua/cdefs.lua +++ b/lualib/nelua/cdefs.lua @@ -91,7 +91,7 @@ compilers_flags.cc = { ext = '.c', } -- GCC -compilers_flags.gcc = tabler.updatecopy(compilers_flags.cc, { +compilers_flags.gcc = tabler.copyupdate(compilers_flags.cc, { cflags_base = "-fwrapv -fno-strict-aliasing", cflags_sanitize = "-Wall -Wextra -fsanitize=address,undefined", cflags_devel = "-g", @@ -107,42 +107,42 @@ compilers_flags.gcc = tabler.updatecopy(compilers_flags.cc, { cmd_defines = '$(cc) -E -dM -x c "$(cfile)" -x none $(cflags)', }) -- Emscripten CC -compilers_flags.emcc = tabler.updatecopy(compilers_flags.gcc, { +compilers_flags.emcc = tabler.copyupdate(compilers_flags.gcc, { cflags_release = "-Oz -DNDEBUG", cflags_maximum_performance = "-O3 -ffast-math -DNDEBUG -fno-plt -flto", }) -- Clang -compilers_flags.clang = tabler.updatecopy(compilers_flags.gcc, { +compilers_flags.clang = tabler.copyupdate(compilers_flags.gcc, { cmd_compile = '$(cc) -x c "$(cfile)" -x none -Wno-unused-command-line-argument $(cflags) -o "$(binfile)"', cmd_info = '$(cc) -E -x c "$(cfile)" -x none -Wno-unused-command-line-argument $(cflags)', cmd_defines = '$(cc) -E -dM -x c "$(cfile)" -x none -Wno-unused-command-line-argument $(cflags)', }) -- TCC -compilers_flags.tcc = tabler.updatecopy(compilers_flags.cc, { +compilers_flags.tcc = tabler.copyupdate(compilers_flags.cc, { cflags_base = "-w", cflags_devel = "-g", cflags_debug = "-g", }) -- C2M -compilers_flags.c2m = tabler.updatecopy(compilers_flags.cc, { +compilers_flags.c2m = tabler.copyupdate(compilers_flags.cc, { cflags_base = "-w", cflags_shared_lib = "-c", }) -- GCC (C++) -compilers_flags['g++'] = tabler.updatecopy(compilers_flags.gcc, { +compilers_flags['g++'] = tabler.copyupdate(compilers_flags.gcc, { cmd_compile = '$(cc) -x c++ "$(cfile)" -x none $(cflags) -o "$(binfile)"', cmd_info = '$(cc) -E -x c++ "$(cfile)" -x none $(cflags)', cmd_defines = '$(cc) -E -dM -x c++ "$(cfile)" -x none $(cflags)', ext = '.cpp', }) -- Clang (C++) -compilers_flags['clang++'] = tabler.updatecopy(compilers_flags['g++'], { +compilers_flags['clang++'] = tabler.copyupdate(compilers_flags['g++'], { cmd_compile = '$(cc) -x c++ "$(cfile)" -x none -Wno-unused-command-line-argument $(cflags) -o "$(binfile)"', cmd_info = '$(cc) -E -x c++ "$(cfile)" -x none -Wno-unused-command-line-argument $(cflags)', cmd_defines = '$(cc) -E -dM -x c++ "$(cfile)" -x none -Wno-unused-command-line-argument $(cflags)', }) -- NVCC (CUDA C++) -compilers_flags['nvcc'] = tabler.updatecopy(compilers_flags.gcc, { +compilers_flags['nvcc'] = tabler.copyupdate(compilers_flags.gcc, { cflags_base = "", cmd_compile = '$(cc) -x cu "$(cfile)" $(cflags) -o "$(binfile)"', cmd_info = '$(cc) -E -x cu "$(cfile)" $(cflags)', diff --git a/lualib/nelua/utils/tabler.lua b/lualib/nelua/utils/tabler.lua index 42813f03..e7f7fd42 100644 --- a/lualib/nelua/utils/tabler.lua +++ b/lualib/nelua/utils/tabler.lua @@ -60,8 +60,23 @@ function tabler.copy(t) return ot end +-- Shallow copy for table (including metatables). +function tabler.copymt(t) + local ot = {} + for i,v in next,t do + ot[i] = v + end + return setmetatable(ot, getmetatable(t)) +end + +-- Update a table with shallow copy of children (including metatables). +function tabler.updatecopymt(dest, src) + for k,v in pairs(src) do dest[k] = tabler.copymt(v) end + return dest +end + -- Shallow copy a table and update its elements. -function tabler.updatecopy(s,t) +function tabler.copyupdate(s, t) return tabler.update(tabler.copy(s), t) end @@ -113,10 +128,7 @@ function tabler.mirror(dst, src) if rawequal(dst, src) then return end - setmetatable(dst, nil) - tabler.clear(dst) - tabler.update(dst, src) - setmetatable(dst, getmetatable(src)) + return setmetatable(tabler.update(tabler.clear(setmetatable(dst, nil)), src), getmetatable(src)) end return tabler