@@ -10,6 +10,7 @@ prelude
1010public import Lean.Expr
1111public import Lean.Data.Lsp.Basic
1212public import Lean.Data.JsonRpc
13+ public import Lean.Data.DeclarationRange
1314
1415public section
1516
@@ -98,27 +99,129 @@ instance : ToJson RefIdent where
9899
99100end RefIdent
100101
101- /-- Information about the declaration surrounding a reference. -/
102- structure RefInfo.ParentDecl where
103- /-- Name of the declaration surrounding a reference. -/
104- name : String
105- /-- Range of the declaration surrounding a reference. -/
106- range : Lsp.Range
107- /-- Selection range of the declaration surrounding a reference. -/
108- selectionRange : Lsp.Range
109- deriving ToJson
102+ /-- Position information for a declaration. Inlined to reduce memory consumption. -/
103+ structure DeclInfo where
104+ /-- Start line of range. -/
105+ rangeStartPosLine : Nat
106+ /-- Start character of range. -/
107+ rangeStartPosCharacter : Nat
108+ /-- End line of range. -/
109+ rangeEndPosLine : Nat
110+ /-- End character of range. -/
111+ rangeEndPosCharacter : Nat
112+ /-- Start line of selection range. -/
113+ selectionRangeStartPosLine : Nat
114+ /-- Start character of selection range. -/
115+ selectionRangeStartPosCharacter : Nat
116+ /-- End line of selection range. -/
117+ selectionRangeEndPosLine : Nat
118+ /-- End character of selection range. -/
119+ selectionRangeEndPosCharacter : Nat
120+
121+ /-- Converts a set of `DeclarationRanges` to a `DeclInfo`. -/
122+ def DeclInfo.ofDeclarationRanges (r : DeclarationRanges) : DeclInfo where
123+ rangeStartPosLine := r.range.pos.line - 1
124+ rangeStartPosCharacter := r.range.charUtf16
125+ rangeEndPosLine := r.range.endPos.line - 1
126+ rangeEndPosCharacter := r.range.endCharUtf16
127+ selectionRangeStartPosLine := r.selectionRange.pos.line - 1
128+ selectionRangeStartPosCharacter := r.selectionRange.charUtf16
129+ selectionRangeEndPosLine := r.selectionRange.endPos.line - 1
130+ selectionRangeEndPosCharacter := r.selectionRange.endCharUtf16
131+
132+ /-- Range of this parent decl. -/
133+ def DeclInfo.range (i : DeclInfo) : Lsp.Range :=
134+ ⟨⟨i.rangeStartPosLine, i.rangeStartPosCharacter⟩, ⟨i.rangeEndPosLine, i.rangeEndPosCharacter⟩⟩
135+
136+ /-- Selection range of this parent decl. -/
137+ def DeclInfo.selectionRange (i : DeclInfo) : Lsp.Range :=
138+ ⟨⟨i.selectionRangeStartPosLine, i.selectionRangeStartPosCharacter⟩,
139+ ⟨i.selectionRangeEndPosLine, i.selectionRangeEndPosCharacter⟩⟩
140+
141+ instance : ToJson DeclInfo where
142+ toJson i :=
143+ Json.arr #[
144+ i.rangeStartPosLine,
145+ i.rangeStartPosCharacter,
146+ i.rangeEndPosLine,
147+ i.rangeEndPosCharacter,
148+ i.selectionRangeStartPosLine,
149+ i.selectionRangeStartPosCharacter,
150+ i.selectionRangeEndPosLine,
151+ i.selectionRangeEndPosCharacter
152+ ]
153+
154+ instance : FromJson DeclInfo where
155+ fromJson?
156+ | .arr xs => do
157+ if xs.size != 8 then
158+ throw s! "Expected list of length 8, not length { xs.size} "
159+ return {
160+ rangeStartPosLine := ← fromJson? xs[0 ]!
161+ rangeStartPosCharacter := ← fromJson? xs[1 ]!
162+ rangeEndPosLine := ← fromJson? xs[2 ]!
163+ rangeEndPosCharacter := ← fromJson? xs[3 ]!
164+ selectionRangeStartPosLine := ← fromJson? xs[4 ]!
165+ selectionRangeStartPosCharacter := ← fromJson? xs[5 ]!
166+ selectionRangeEndPosLine := ← fromJson? xs[6 ]!
167+ selectionRangeEndPosCharacter := ← fromJson? xs[7 ]!
168+ }
169+ | _ => throw "Expected list"
170+
171+ /-- Declarations of a file with associated position information. -/
172+ @[expose] def Decls := Std.TreeMap String DeclInfo
173+ deriving EmptyCollection, ForIn Id
174+
175+ instance : ToJson Decls where
176+ toJson m := Json.mkObj <| m.toList.map fun (declName, info) => (declName, toJson info)
177+
178+ instance : FromJson Decls where
179+ fromJson? j := do
180+ let node ← j.getObj?
181+ node.foldlM (init := ∅) fun m k v =>
182+ return m.insert k (← fromJson? v)
110183
111184/--
112185Denotes the range of a reference, as well as the parent declaration of the reference.
113186If the reference is itself a declaration, then it contains no parent declaration.
187+ The position information is inlined to reduce memory consumption.
114188-/
115189structure RefInfo.Location where
116- /-- Range of the reference. -/
117- range : Lsp.Range
118- /-- Parent declaration of the reference. `none` if the reference is itself a declaration. -/
119- parentDecl? : Option RefInfo.ParentDecl
190+ mk' ::
191+ /-- Start line of the range of this location. -/
192+ startPosLine : Nat
193+ /-- Start character of the range of this location. -/
194+ startPosCharacter : Nat
195+ /-- End line of the range of this location. -/
196+ endPosLine : Nat
197+ /-- End character of the range of this location. -/
198+ endPosCharacter : Nat
199+ /--
200+ Parent declaration of the reference. Empty string if the reference is itself a declaration.
201+ We do not use `Option` for memory consumption reasons.
202+ -/
203+ parentDecl : String
120204deriving Inhabited
121205
206+ /-- Creates a `RefInfo.Location`. -/
207+ def RefInfo.Location.mk (range : Lsp.Range) (parentDecl? : Option String) : RefInfo.Location where
208+ startPosLine := range.start.line
209+ startPosCharacter := range.start.character
210+ endPosLine := range.end.line
211+ endPosCharacter := range.end.character
212+ parentDecl := parentDecl?.getD ""
213+
214+ /-- Range of this location. -/
215+ def RefInfo.Location.range (l : RefInfo.Location) : Lsp.Range :=
216+ ⟨⟨l.startPosLine, l.startPosCharacter⟩, ⟨l.endPosLine, l.endPosCharacter⟩⟩
217+
218+ /-- Name of the parent declaration of this location. -/
219+ def RefInfo.Location.parentDecl? (l : RefInfo.Location) : Option String :=
220+ if l.parentDecl.isEmpty then
221+ none
222+ else
223+ some l.parentDecl
224+
122225/-- Definition site and usage sites of a reference. Obtained from `Lean.Server.RefInfo`. -/
123226structure RefInfo where
124227 /-- Definition site of the reference. May be `none` when we cannot find a definition site. -/
@@ -128,16 +231,9 @@ structure RefInfo where
128231
129232instance : ToJson RefInfo where
130233 toJson i :=
131- let rangeToList (r : Lsp.Range) : List Nat :=
132- [r.start.line, r.start.character, r.end.line, r.end.character]
133- let parentDeclToList (d : RefInfo.ParentDecl) : List Json :=
134- let name := d.name |> toJson
135- let range := rangeToList d.range |>.map toJson
136- let selectionRange := rangeToList d.selectionRange |>.map toJson
137- [name] ++ range ++ selectionRange
138234 let locationToList (l : RefInfo.Location) : List Json :=
139- let range := rangeToList l.range |> .map toJson
140- let parentDecl := l.parentDecl?.map parentDeclToList |>.getD []
235+ let range := [l.startPosLine, l.startPosCharacter, l.endPosLine, l.endPosCharacter] .map toJson
236+ let parentDecl := l.parentDecl?.map ([toJson ·]) |>.getD []
141237 range ++ parentDecl
142238 Json.mkObj [
143239 ("definition" , toJson $ i.definition?.map locationToList),
@@ -147,35 +243,30 @@ instance : ToJson RefInfo where
147243instance : FromJson RefInfo where
148244 -- This implementation is optimized to prevent redundant intermediate allocations.
149245 fromJson? j := do
150- let toRange (a : Array Json) (i : Nat) : Except String Lsp.Range :=
151- if h : a.size < i + 4 then
152- throw s! "Expected list of length 4, not { a.size} "
246+ let toLocation (a : Array Json) : Except String RefInfo.Location := do
247+ if h : a.size ≠ 4 ∧ a.size ≠ 5 then
248+ .error s! "Expected list of length 4 or 5 , not { a.size} "
153249 else
154- return {
155- start := {
156- line := ← fromJson? a[i]
157- character := ← fromJson? a[i+1 ]
250+ let startPosLine ← fromJson? a[0 ]
251+ let startPosCharacter ← fromJson? a[1 ]
252+ let endPosLine ← fromJson? a[2 ]
253+ let endPosCharacter ← fromJson? a[3 ]
254+ if h' : a.size = 5 then
255+ return {
256+ startPosLine
257+ startPosCharacter
258+ endPosLine
259+ endPosCharacter
260+ parentDecl := ← fromJson? a[4 ]
158261 }
159- «end » := {
160- line := ← fromJson? a[i+2 ]
161- character := ← fromJson? a[i+3 ]
262+ else
263+ return {
264+ startPosLine
265+ startPosCharacter
266+ endPosLine
267+ endPosCharacter
268+ parentDecl := ""
162269 }
163- }
164- let toParentDecl (a : Array Json) (i : Nat) : Except String RefInfo.ParentDecl := do
165- let name ← fromJson? a[i]!
166- let range ← toRange a (i + 1 )
167- let selectionRange ← toRange a (i + 5 )
168- return ⟨name, range, selectionRange⟩
169- let toLocation (a : Array Json) : Except String RefInfo.Location := do
170- if a.size != 4 && a.size != 13 then
171- .error "Expected list of length 4 or 13, not {l.size}"
172- let range ← toRange a 0
173- if a.size == 13 then
174- let parentDecl ← toParentDecl a 4
175- return ⟨range, parentDecl⟩
176- else
177- return ⟨range, none⟩
178-
179270 let definition? ← j.getObjValAs? (Option $ Array Json) "definition"
180271 let definition? ← match definition? with
181272 | none => pure none
@@ -213,15 +304,28 @@ structure LeanILeanHeaderInfoParams where
213304 directImports : Array ImportInfo
214305 deriving FromJson, ToJson
215306
307+ /--
308+ Used in the `$/lean/ileanHeaderSetupInfo` watchdog <- worker notifications.
309+ Contains status information about `lake setup-file`.
310+ -/
311+ structure LeanILeanHeaderSetupInfoParams where
312+ /-- Version of the file these imports are from. -/
313+ version : Nat
314+ /-- Whether setting up the header using `lake setup-file` has failed. -/
315+ isSetupFailure : Bool
316+ deriving FromJson, ToJson
317+
216318/--
217319Used in the `$/lean/ileanInfoUpdate` and `$/lean/ileanInfoFinal` watchdog <- worker notifications.
218320Contains the definitions and references of the file managed by a worker.
219321-/
220322structure LeanIleanInfoParams where
221323 /-- Version of the file these references are from. -/
222- version : Nat
324+ version : Nat
223325 /-- All references for the file. -/
224- references : ModuleRefs
326+ references : ModuleRefs
327+ /-- All decls for the file. -/
328+ decls : Decls
225329 deriving FromJson, ToJson
226330
227331/--
0 commit comments