1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
local nodeMgr = require 'vm.node'
local compiler = require 'vm.compiler'
local globalMgr = require 'vm.global-manager'
---@class vm.type-manager
local m = {}
---@param child vm.node
---@param parent vm.node
---@return boolean
function m.isSubType(child, parent, mark)
if type(parent) == 'string' then
parent = globalMgr.getGlobal('type', parent)
end
if type(child) == 'string' then
child = globalMgr.getGlobal('type', child)
end
if parent.type == 'global' and parent.cate == 'type' and parent.name == 'any' then
return true
end
if child.type == 'doc.type' then
for _, typeUnit in ipairs(child.types) do
if not m.isSubType(typeUnit, parent) then
return false
end
end
return true
end
if child.type == 'doc.type.name' then
child = globalMgr.getGlobal('type', child[1])
end
if child.type == 'global' and child.cate == 'type' then
if parent.type == 'doc.type' then
for _, typeUnit in ipairs(parent.types) do
if m.isSubType(child, typeUnit) then
return true
end
end
end
if parent.type == 'doc.type.name' then
parent = globalMgr.getGlobal('type', parent[1])
end
if parent.type == 'global' and parent.cate == 'type' then
if parent.name == child.name then
return true
end
mark = mark or {}
if mark[child.name] then
return false
end
mark[child.name] = true
for _, set in ipairs(child:getSets()) do
if set.type == 'doc.class' and set.extends then
for _, ext in ipairs(set.extends) do
if m.isSubType(globalMgr.getGlobal('type', ext[1]), parent, mark) then
return true
end
end
end
end
end
end
return false
end
---@param tnode vm.node
---@param knode vm.node
function m.getTableValue(tnode, knode)
local result
for tn in nodeMgr.eachNode(tnode) do
if tn.type == 'doc.type.table' then
for _, field in ipairs(tn.fields) do
if m.isSubType(field.name, knode) then
result = nodeMgr.mergeNode(compiler.compileNode(field.extends), result)
end
end
end
if tn.type == 'doc.type.array' then
if m.isSubType(globalMgr.getGlobal('type', 'integer'), knode) then
result = nodeMgr.mergeNode(compiler.compileNode(tn.node), result)
end
end
end
return result
end
---@param tnode vm.node
---@param vnode vm.node
function m.getTableKey(tnode, vnode)
local result
for tn in nodeMgr.eachNode(tnode) do
if tn.type == 'doc.type.table' then
for _, field in ipairs(tn.fields) do
if m.isSubType(field.extends, vnode) then
result = nodeMgr.mergeNode(compiler.compileNode(field.name), result)
end
end
end
if tn.type == 'doc.type.array' then
if m.isSubType(tn.node, vnode) then
result = nodeMgr.mergeNode(globalMgr.getGlobal('type', 'integer'), result)
end
end
end
return result
end
return m
|