Skip to content

Commit 6456802

Browse files
committed
first step for code lens
1 parent 67ccea8 commit 6456802

File tree

5 files changed

+193
-3
lines changed

5 files changed

+193
-3
lines changed

script/core/code-lens.lua

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
local files = require 'files'
2+
local guide = require 'parser.guide'
3+
local await = require 'await'
4+
local conv = require 'proto.converter'
5+
local getRef = require 'core.reference'
6+
7+
---@type codeLens
8+
local latestCodeLens
9+
10+
---@class codeLens.resolving
11+
---@field mode 'reference'
12+
---@field source parser.object
13+
14+
---@class codeLens.result
15+
---@field position integer
16+
---@field id integer
17+
18+
---@class codeLens
19+
local mt = {}
20+
mt.__index = mt
21+
mt.type = 'codeLens'
22+
mt.id = 0
23+
24+
---@param uri uri
25+
---@return boolean
26+
function mt:init(uri)
27+
self.state = files.getState(uri)
28+
if not self.state then
29+
return false
30+
end
31+
---@type uri
32+
self.uri = uri
33+
---@type codeLens.result[]
34+
self.results = {}
35+
---@type table<integer, codeLens.resolving>
36+
self.resolving = {}
37+
return true
38+
end
39+
40+
---@param pos integer
41+
---@param resolving codeLens.resolving
42+
function mt:addResult(pos, resolving)
43+
self.id = self.id + 1
44+
self.results[#self.results+1] = {
45+
position = pos,
46+
id = self.id,
47+
}
48+
self.resolving[self.id] = resolving
49+
end
50+
51+
---@async
52+
---@param id integer
53+
---@return proto.command?
54+
function mt:resolve(id)
55+
local resolving = self.resolving[id]
56+
if not resolving then
57+
return nil
58+
end
59+
if resolving.mode == 'reference' then
60+
return self:resolveReference(resolving.source)
61+
end
62+
end
63+
64+
---@async
65+
function mt:collectReferences()
66+
await.delay()
67+
guide.eachSourceType(self.state.ast, 'function', function (src)
68+
local assign = src.parent
69+
if not guide.isSet(assign) then
70+
return
71+
end
72+
self:addResult(src.start, {
73+
mode = 'reference',
74+
source = assign,
75+
})
76+
end)
77+
end
78+
79+
---@async
80+
---@param source parser.object
81+
---@return proto.command?
82+
function mt:resolveReference(source)
83+
local refs = getRef(self.uri, source.start, false)
84+
local count = refs and #refs or 0
85+
local command = conv.command(
86+
('%d个引用'):format(count),
87+
'editor.action.showReferences',
88+
{
89+
self.uri,
90+
conv.packPosition(self.state, source.start),
91+
}
92+
)
93+
return command
94+
end
95+
96+
---@async
97+
---@param uri uri
98+
---@return codeLens.result[]?
99+
local function codeLens(uri)
100+
latestCodeLens = setmetatable({}, mt)
101+
local suc = latestCodeLens:init(uri)
102+
if not suc then
103+
return nil
104+
end
105+
106+
latestCodeLens:collectReferences()
107+
108+
if #latestCodeLens.results == 0 then
109+
return nil
110+
end
111+
112+
return latestCodeLens.results
113+
end
114+
115+
---@async
116+
---@param id integer
117+
---@return proto.command?
118+
local function resolve(id)
119+
if not latestCodeLens then
120+
return nil
121+
end
122+
local command = latestCodeLens:resolve(id)
123+
return command
124+
end
125+
126+
return {
127+
codeLens = codeLens,
128+
resolve = resolve,
129+
}

script/core/reference.lua

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,11 @@ return function (uri, position, includeDeclaration)
8585
if src.type == 'self' then
8686
goto CONTINUE
8787
end
88-
if not includeDeclaration and guide.isSet(src) then
89-
goto CONTINUE
88+
if not includeDeclaration then
89+
if guide.isSet(src)
90+
or guide.isLiteral(src) then
91+
goto CONTINUE
92+
end
9093
end
9194
src = src.field or src.method or src
9295
if src.type == 'getindex'

script/proto/converter.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ local encoder = require 'encoder'
44

55
local offsetEncoding = 'utf16'
66

7+
---@class converter
78
local m = {}
89

910
---@alias position {line: integer, character: integer}
@@ -206,4 +207,21 @@ function m.setOffsetEncoding(encoding)
206207
offsetEncoding = encoding:lower():gsub('%-', '')
207208
end
208209

210+
---@class proto.command
211+
---@field title string
212+
---@field command string
213+
---@field arguments any[]
214+
215+
---@param title string
216+
---@param command string
217+
---@param arguments any[]
218+
---@return proto.command
219+
function m.command(title, command, arguments)
220+
return {
221+
title = title,
222+
command = command,
223+
arguments = arguments,
224+
}
225+
end
226+
209227
return m

script/provider/provider.lua

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,46 @@ m.register 'textDocument/codeAction' {
918918
end
919919
}
920920

921+
m.register 'textDocument/codeLens' {
922+
capability = {
923+
codeLensProvider = {
924+
resolveProvider = true,
925+
}
926+
},
927+
---@async
928+
function (params)
929+
local uri = files.getRealUri(params.textDocument.uri)
930+
workspace.awaitReady(uri)
931+
local state = files.getState(uri)
932+
if not state then
933+
return nil
934+
end
935+
local core = require 'core.code-lens'
936+
local results = core.codeLens(uri)
937+
if not results then
938+
return nil
939+
end
940+
local codeLens = {}
941+
for _, result in ipairs(results) do
942+
codeLens[#codeLens+1] = {
943+
range = converter.packRange(state, result.position, result.position),
944+
data = result.id,
945+
}
946+
end
947+
return codeLens
948+
end
949+
}
950+
951+
m.register 'codeLens/resolve' {
952+
---@async
953+
function (codeLen)
954+
local core = require 'core.code-lens'
955+
local command = core.resolve(codeLen.data)
956+
codeLen.command = command
957+
return codeLen
958+
end
959+
}
960+
921961
m.register 'workspace/executeCommand' {
922962
capability = {
923963
executeCommandProvider = {

script/vm/tracer.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ function mt:lookIntoChild(action, topNode, outNode)
202202
end
203203
end
204204
elseif action.type == 'function' then
205-
self:lookIntoBlock(action, action.args.finish, topNode:copy())
205+
self:lookIntoBlock(action, action.bstart, topNode:copy())
206206
elseif action.type == 'unary' then
207207
if not action[1] then
208208
goto RETURN

0 commit comments

Comments
 (0)