summaryrefslogtreecommitdiff
path: root/script/vm
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-10-24 20:17:04 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-10-24 20:17:04 +0800
commitb53089f637e5f4e77f2cfd938f254dc983bb5fb4 (patch)
tree838b267e8b442e09861d0e1fffb695f68feec2da /script/vm
parent5e41989b246954c44d377c96572046be339fea18 (diff)
downloadlua-language-server-b53089f637e5f4e77f2cfd938f254dc983bb5fb4.zip
supports `private`, `protected` and `public`
#1316
Diffstat (limited to 'script/vm')
-rw-r--r--script/vm/global.lua6
-rw-r--r--script/vm/init.lua2
-rw-r--r--script/vm/visible.lua79
3 files changed, 87 insertions, 0 deletions
diff --git a/script/vm/global.lua b/script/vm/global.lua
index 29474b57..93316901 100644
--- a/script/vm/global.lua
+++ b/script/vm/global.lua
@@ -534,6 +534,12 @@ function compileObject(source)
end
---@param source parser.object
+---@return vm.global?
+function vm.getGlobalNode(source)
+ return source._globalNode or nil
+end
+
+---@param source parser.object
local function compileSelf(source)
if source.parent.type ~= 'funcargs' then
return
diff --git a/script/vm/init.lua b/script/vm/init.lua
index 87c046f0..7b69a7eb 100644
--- a/script/vm/init.lua
+++ b/script/vm/init.lua
@@ -19,4 +19,6 @@ require 'vm.local-id'
require 'vm.global'
require 'vm.function'
require 'vm.operator'
+require 'vm.visible'
+
return vm
diff --git a/script/vm/visible.lua b/script/vm/visible.lua
new file mode 100644
index 00000000..ec538f24
--- /dev/null
+++ b/script/vm/visible.lua
@@ -0,0 +1,79 @@
+---@class vm
+local vm = require 'vm.vm'
+local guide = require 'parser.guide'
+
+---@param source parser.object
+---@return 'public' | 'protected' | 'private'
+function vm.getVisibleType(source)
+ if source.type == 'doc.field' then
+ return source.visible or 'public'
+ end
+ return 'public'
+end
+
+---@param source parser.object
+---@return vm.global?
+function vm.getParentClass(source)
+ if source.type == 'doc.field' then
+ return vm.getGlobalNode(source.class)
+ end
+ return nil
+end
+
+---@param suri uri
+---@param source parser.object
+---@return vm.global?
+function vm.getDefinedClass(suri, source)
+ local sets = vm.getLocalSourcesSets(source)
+ if sets then
+ for _, set in ipairs(sets) do
+ if set.bindDocs then
+ for _, doc in ipairs(set.bindDocs) do
+ if doc.type == 'doc.class' then
+ return vm.getGlobalNode(doc)
+ end
+ end
+ end
+ end
+ end
+ local global = vm.getGlobalNode(source)
+ if global then
+ for _, set in ipairs(global:getSets(suri)) do
+ if set.bindDocs then
+ for _, doc in ipairs(set.bindDocs) do
+ if doc.type == 'doc.class' then
+ return vm.getGlobalNode(doc)
+ end
+ end
+ end
+ end
+ end
+ return nil
+end
+
+---@param parent parser.object
+---@param field parser.object
+function vm.isVisible(parent, field)
+ local visible = vm.getVisibleType(field)
+ if visible == 'public' then
+ return true
+ end
+ local class = vm.getParentClass(field)
+ if not class then
+ return true
+ end
+ local suri = guide.getUri(parent)
+ local myClass = vm.getDefinedClass(suri, parent)
+ if not myClass then
+ return false
+ end
+ if myClass == class then
+ return true
+ end
+ if visible == 'protected' then
+ if vm.isSubType(suri, myClass, class) then
+ return true
+ end
+ end
+ return false
+end