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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
local files = require 'files'
local guide = require 'parser.guide'
local await = require 'await'
local conv = require 'proto.converter'
local getRef = require 'core.reference'
---@class parser.state
---@field package _codeLens codeLens
---@class codeLens.resolving
---@field mode 'reference'
---@field source parser.object
---@class codeLens.result
---@field position integer
---@field uri uri
---@field id integer
---@class codeLens
local mt = {}
mt.__index = mt
mt.type = 'codeLens'
mt.id = 0
---@param uri uri
---@return boolean
function mt:init(uri)
self.state = files.getState(uri)
if not self.state then
return false
end
---@type uri
self.uri = uri
---@type codeLens.result[]
self.results = {}
---@type table<integer, codeLens.resolving>
self.resolving = {}
return true
end
---@param pos integer
---@param resolving codeLens.resolving
function mt:addResult(pos, resolving)
self.id = self.id + 1
self.results[#self.results+1] = {
position = pos,
id = self.id,
}
self.resolving[self.id] = resolving
end
---@async
---@param id integer
---@return proto.command?
function mt:resolve(id)
local resolving = self.resolving[id]
if not resolving then
return nil
end
if resolving.mode == 'reference' then
return self:resolveReference(resolving.source)
end
end
---@async
function mt:collectReferences()
await.delay()
---@async
guide.eachSourceType(self.state.ast, 'function', function (src)
local parent = src.parent
if guide.isSet(parent) then
src = parent
elseif parent.type == 'return' then
else
return
end
await.delay()
self:addResult(src.start, {
mode = 'reference',
source = src,
})
end)
end
---@async
---@param source parser.object
---@return proto.command?
function mt:resolveReference(source)
local refs = getRef(self.uri, source.finish, false)
local count = refs and #refs or 0
local command = conv.command(
('%d个引用'):format(count),
'',
{}
)
return command
end
---@async
---@param uri uri
---@return codeLens.result[]?
local function getCodeLens(uri)
local state = files.getState(uri)
if not state then
return nil
end
local codeLens = setmetatable({}, mt)
local suc = codeLens:init(uri)
if not suc then
return nil
end
state._codeLens = codeLens
codeLens:collectReferences()
if #codeLens.results == 0 then
return nil
end
return codeLens.results
end
---@async
---@param id integer
---@return proto.command?
local function resolve(uri, id)
local state = files.getState(uri)
if not state then
return nil
end
local codeLens = state._codeLens
if not codeLens then
return nil
end
local command = codeLens:resolve(id)
return command
end
return {
codeLens = getCodeLens,
resolve = resolve,
}
|