lean4-htt/src/Lean/Data/Lsp/LanguageFeatures.lean
Markus Himmel b28daa6d60
chore: rename String.endPos -> String.rawEndPos (#10853)
This PR renames `String.endPos` to `String.rawEndPos`, as in a future
release the name `String.endPos` will be taken by the function that is
currently called `String.endValidPos`.
2025-10-21 11:25:30 +00:00

727 lines
20 KiB
Text

/-
Copyright (c) 2020 Wojciech Nawrocki. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Wojciech Nawrocki
-/
module
prelude
public import Lean.Data.Lsp.Basic
meta import Lean.Data.Json
public import Lean.Expr
public section
namespace Lean
namespace Lsp
open Json
structure CompletionOptions where
triggerCharacters? : Option (Array String) := none
allCommitCharacters? : Option (Array String) := none
resolveProvider : Bool := false
deriving FromJson, ToJson
inductive CompletionItemKind where
| text | method | function | constructor | field
| variable | class | interface | module | property
| unit | value | enum | keyword | snippet
| color | file | reference | folder | enumMember
| constant | struct | event | operator | typeParameter
deriving Inhabited, DecidableEq, Repr, Hashable
instance : ToJson CompletionItemKind where
toJson a := toJson (a.ctorIdx + 1)
instance : FromJson CompletionItemKind where
fromJson? v := do
let i : Nat ← fromJson? v
return CompletionItemKind.ofNat (i-1)
structure InsertReplaceEdit where
newText : String
insert : Range
replace : Range
deriving FromJson, ToJson, BEq, Hashable
inductive CompletionItemTag where
| deprecated
deriving Inhabited, DecidableEq, Repr, Hashable
instance : ToJson CompletionItemTag where
toJson t := toJson (t.ctorIdx + 1)
instance : FromJson CompletionItemTag where
fromJson? v := do
let i : Nat ← fromJson? v
return CompletionItemTag.ofNat (i-1)
structure CompletionItem where
-- When adjusting this type, make sure to adjust `ResolvableCompletionList.compressFast`
-- as well, which is our `(toJson l).compress` fast path.
-- (Completion downstream of Mathlib can output gigantic JSON,
-- so we want to avoid all redundant allocs)
label : String
detail? : Option String := none
documentation? : Option MarkupContent := none
kind? : Option CompletionItemKind := none
textEdit? : Option InsertReplaceEdit := none
sortText? : Option String := none
data? : Option Json := none
tags? : Option (Array CompletionItemTag) := none
/-
deprecated? : boolean
preselect? : boolean
filterText? : string
insertText? : string
insertTextFormat? : InsertTextFormat
insertTextMode? : InsertTextMode
additionalTextEdits? : TextEdit[]
commitCharacters? : string[]
command? : Command
-/
deriving FromJson, ToJson, Inhabited, BEq, Hashable
structure CompletionList where
isIncomplete : Bool
items : Array CompletionItem
deriving FromJson, ToJson
/--
Identifier that is sent from the server to the client as part of the `CompletionItem.data?` field.
Needed to resolve the `CompletionItem` when the client sends a `completionItem/resolve` request
for that item, again containing the `data?` field provided by the server.
-/
inductive CompletionIdentifier where
| const (declName : Name)
| fvar (id : Lean.FVarId)
deriving BEq, Hashable
instance : ToJson CompletionIdentifier where
toJson
| .const declName =>
.str s!"c{toString declName}"
| .fvar id =>
.str s!"f{toString id.name}"
instance : FromJson CompletionIdentifier where
fromJson?
| .str s =>
let c := s.front
if c == 'c' then
let declName := String.Pos.Raw.extract s ⟨1⟩ s.rawEndPos |>.toName
.ok <| .const declName
else if c == 'f' then
let id := ⟨String.Pos.Raw.extract s ⟨1⟩ s.rawEndPos |>.toName⟩
.ok <| .fvar id
else
.error "Expected string with prefix `c` or `f` in `FromJson` instance of `CompletionIdentifier`."
| _ => .error "Expected string in `FromJson` instance of `CompletionIdentifier`."
structure ResolvableCompletionItemData where
mod : Name
pos : Position
/-- Position of the completion info that this completion item was created from. -/
cPos? : Option Nat := none
id? : Option CompletionIdentifier := none
deriving BEq, Hashable
instance : ToJson ResolvableCompletionItemData where
toJson d := Id.run do
let mut arr : Array Json := #[
toJson d.mod,
d.pos.line,
d.pos.character,
]
if let some cPos := d.cPos? then
arr := arr.push <| toJson cPos
if let some id := d.id? then
arr := arr.push <| toJson id
Json.arr arr
instance : FromJson ResolvableCompletionItemData where
fromJson?
| .arr elems => do
if elems.size < 3 then
.error "Expected array of size 3 in `FromJson` instance of `ResolvableCompletionItemData"
let mod : Name ← fromJson? elems[0]!
let line : Nat ← fromJson? elems[1]!
let character : Nat ← fromJson? elems[2]!
let mut cPos? : Option Nat := none
let mut id? : Option CompletionIdentifier := none
if let .ok (some cPos) := elems[3]?.mapM fromJson? then
cPos? := some cPos
if let .ok (some id) := elems[3]?.mapM fromJson? then
id? := some id
if let .ok (some cPos) := elems[4]?.mapM fromJson? then
cPos? := some cPos
if let .ok (some id) := elems[4]?.mapM fromJson? then
id? := some id
let pos := { line, character }
return {
mod
pos
cPos?
id?
}
| _ => .error "Expected array in `FromJson` instance of `ResolvableCompletionItemData`"
structure ResolvableCompletionItem where
label : String
detail? : Option String := none
documentation? : Option MarkupContent := none
kind? : Option CompletionItemKind := none
textEdit? : Option InsertReplaceEdit := none
sortText? : Option String := none
data? : Option ResolvableCompletionItemData := none
tags? : Option (Array CompletionItemTag) := none
/-
deprecated? : boolean
preselect? : boolean
filterText? : string
insertText? : string
insertTextFormat? : InsertTextFormat
insertTextMode? : InsertTextMode
additionalTextEdits? : TextEdit[]
commitCharacters? : string[]
command? : Command
-/
deriving FromJson, ToJson, Inhabited, BEq, Hashable
structure ResolvableCompletionList where
isIncomplete : Bool
items : Array ResolvableCompletionItem
deriving FromJson, ToJson
structure CompletionParams extends TextDocumentPositionParams where
-- context? : CompletionContext
deriving FromJson, ToJson
structure Hover where
/- NOTE we should also accept MarkedString/MarkedString[] here
but they are deprecated, so maybe can get away without. -/
contents : MarkupContent
range? : Option Range := none
deriving ToJson, FromJson
structure HoverParams extends TextDocumentPositionParams
deriving FromJson, ToJson
structure DeclarationParams extends TextDocumentPositionParams
deriving FromJson, ToJson
structure DefinitionParams extends TextDocumentPositionParams
deriving FromJson, ToJson
structure TypeDefinitionParams extends TextDocumentPositionParams
deriving FromJson, ToJson
structure ReferenceContext where
includeDeclaration : Bool
deriving FromJson, ToJson
structure ReferenceParams extends TextDocumentPositionParams where
context : ReferenceContext
deriving FromJson, ToJson
structure WorkspaceSymbolParams where
query : String
deriving FromJson, ToJson
structure DocumentHighlightParams extends TextDocumentPositionParams
deriving FromJson, ToJson
inductive DocumentHighlightKind where
| text
| read
| write
instance : ToJson DocumentHighlightKind where
toJson
| DocumentHighlightKind.text => 1
| DocumentHighlightKind.read => 2
| DocumentHighlightKind.write => 3
structure DocumentHighlight where
range : Range
kind? : Option DocumentHighlightKind := none
deriving ToJson
abbrev DocumentHighlightResult := Array DocumentHighlight
structure DocumentSymbolParams where
textDocument : TextDocumentIdentifier
deriving FromJson, ToJson
inductive SymbolKind where
| file
| module
| namespace
| package
| class
| method
| property
| field
| constructor
| enum
| interface
| function
| variable
| constant
| string
| number
| boolean
| array
| object
| key
| null
| enumMember
| struct
| event
| operator
| typeParameter
deriving BEq, Hashable, Inhabited
instance : FromJson SymbolKind where
fromJson?
| 1 => .ok .file
| 2 => .ok .module
| 3 => .ok .namespace
| 4 => .ok .package
| 5 => .ok .class
| 6 => .ok .method
| 7 => .ok .property
| 8 => .ok .field
| 9 => .ok .constructor
| 10 => .ok .enum
| 11 => .ok .interface
| 12 => .ok .function
| 13 => .ok .variable
| 14 => .ok .constant
| 15 => .ok .string
| 16 => .ok .number
| 17 => .ok .boolean
| 18 => .ok .array
| 19 => .ok .object
| 20 => .ok .key
| 21 => .ok .null
| 22 => .ok .enumMember
| 23 => .ok .struct
| 24 => .ok .event
| 25 => .ok .operator
| 26 => .ok .typeParameter
| j => .error s!"invalid symbol kind {j}"
instance : ToJson SymbolKind where
toJson
| .file => 1
| .module => 2
| .namespace => 3
| .package => 4
| .class => 5
| .method => 6
| .property => 7
| .field => 8
| .constructor => 9
| .enum => 10
| .interface => 11
| .function => 12
| .variable => 13
| .constant => 14
| .string => 15
| .number => 16
| .boolean => 17
| .array => 18
| .object => 19
| .key => 20
| .null => 21
| .enumMember => 22
| .struct => 23
| .event => 24
| .operator => 25
| .typeParameter => 26
structure DocumentSymbolAux (Self : Type) where
name : String
detail? : Option String := none
kind : SymbolKind
-- tags? : Array SymbolTag
range : Range
selectionRange : Range
children? : Option (Array Self) := none
deriving FromJson, ToJson
inductive DocumentSymbol where
| mk (sym : DocumentSymbolAux DocumentSymbol)
partial instance : ToJson DocumentSymbol where
toJson :=
let rec go
| DocumentSymbol.mk sym =>
have : ToJson DocumentSymbol := ⟨go⟩
toJson sym
go
structure DocumentSymbolResult where
syms : Array DocumentSymbol
instance : ToJson DocumentSymbolResult where
toJson dsr := toJson dsr.syms
inductive SymbolTag where
| deprecated
deriving BEq, Hashable, Inhabited
instance : FromJson SymbolTag where
fromJson?
| 1 => .ok .deprecated
| j => .error s!"unknown symbol tag {j}"
instance : ToJson SymbolTag where
toJson
| .deprecated => 1
structure SymbolInformation where
name : String
kind : SymbolKind
tags : Array SymbolTag := #[]
location : Location
containerName? : Option String := none
deriving FromJson, ToJson
structure CallHierarchyPrepareParams extends TextDocumentPositionParams
deriving FromJson, ToJson
structure CallHierarchyItem where
name : String
kind : SymbolKind
tags? : Option (Array SymbolTag) := none
detail? : Option String := none
uri : DocumentUri
range : Range
selectionRange : Range
data? : Option Json := none
deriving FromJson, ToJson, BEq, Hashable, Inhabited
structure CallHierarchyIncomingCallsParams where
item : CallHierarchyItem
deriving FromJson, ToJson
structure CallHierarchyIncomingCall where
«from» : CallHierarchyItem
fromRanges : Array Range
deriving FromJson, ToJson, Inhabited
structure CallHierarchyOutgoingCallsParams where
item : CallHierarchyItem
deriving FromJson, ToJson
structure CallHierarchyOutgoingCall where
to : CallHierarchyItem
fromRanges : Array Range
deriving FromJson, ToJson, Inhabited
inductive SemanticTokenType where
-- Used by Lean
| keyword
| variable
| property
| function
/- Other types included by default in the LSP specification.
Not used by the Lean core, but useful to users extending the Lean server. -/
| namespace
| type
| class
| enum
| interface
| struct
| typeParameter
| parameter
| enumMember
| event
| method
| macro
| modifier
| comment
| string
| number
| regexp
| operator
| decorator
-- Extensions
| leanSorryLike
deriving ToJson, FromJson, BEq, Hashable
-- must be in the same order as the constructors
def SemanticTokenType.names : Array String :=
#["keyword", "variable", "property", "function", "namespace", "type", "class",
"enum", "interface", "struct", "typeParameter", "parameter", "enumMember",
"event", "method", "macro", "modifier", "comment", "string", "number",
"regexp", "operator", "decorator", "leanSorryLike"]
def SemanticTokenType.toNat (tokenType : SemanticTokenType) : Nat :=
tokenType.ctorIdx
-- sanity check
example {v : SemanticTokenType} : open SemanticTokenType in
names[v.toNat]?.map (toString <| toJson ·) = some (toString <| toJson v) := by
cases v <;> native_decide
/--
The semantic token modifiers included by default in the LSP specification.
Not used by the Lean core, but implementing them here allows them to be
utilized by users extending the Lean server.
-/
inductive SemanticTokenModifier where
| declaration
| definition
| readonly
| static
| deprecated
| abstract
| async
| modification
| documentation
| defaultLibrary
deriving ToJson, FromJson
-- must be in the same order as the constructors
def SemanticTokenModifier.names : Array String :=
#["declaration", "definition", "readonly", "static", "deprecated", "abstract",
"async", "modification", "documentation", "defaultLibrary"]
def SemanticTokenModifier.toNat (modifier : SemanticTokenModifier) : Nat :=
modifier.ctorIdx
-- sanity check
example {v : SemanticTokenModifier} : open SemanticTokenModifier in
names[v.toNat]?.map (toString <| toJson ·) = some (toString <| toJson v) := by
cases v <;> native_decide
structure SemanticTokensLegend where
tokenTypes : Array String
tokenModifiers : Array String
deriving FromJson, ToJson
structure SemanticTokensOptions where
legend : SemanticTokensLegend
range : Bool
full : Bool /- | {
delta?: boolean;
} -/
deriving FromJson, ToJson
structure SemanticTokensParams where
textDocument : TextDocumentIdentifier
deriving FromJson, ToJson
structure SemanticTokensRangeParams where
textDocument : TextDocumentIdentifier
range : Range
deriving FromJson, ToJson
structure SemanticTokens where
resultId? : Option String := none
data : Array Nat
deriving FromJson, ToJson
structure FoldingRangeParams where
textDocument : TextDocumentIdentifier
deriving FromJson, ToJson
inductive FoldingRangeKind where
| comment
| imports
| region
instance : ToJson FoldingRangeKind where
toJson
| FoldingRangeKind.comment => "comment"
| FoldingRangeKind.imports => "imports"
| FoldingRangeKind.region => "region"
structure FoldingRange where
startLine : Nat
endLine : Nat
kind? : Option FoldingRangeKind := none
deriving ToJson
structure RenameOptions where
prepareProvider : Bool := false
deriving FromJson, ToJson
structure RenameParams extends TextDocumentPositionParams where
newName : String
deriving FromJson, ToJson
structure PrepareRenameParams extends TextDocumentPositionParams
deriving FromJson, ToJson
structure InlayHintParams extends WorkDoneProgressParams where
textDocument : TextDocumentIdentifier
range : Range
deriving FromJson, ToJson
inductive InlayHintTooltip
| plaintext (text : String)
| markdown (markup : MarkupContent)
instance : FromJson InlayHintTooltip where
fromJson?
| .str s => .ok <| .plaintext s
| j@(.obj _) => do return .markdown (← fromJson? j)
| j => .error s!"invalid inlay hint tooltip {j}"
instance : ToJson InlayHintTooltip where
toJson
| .plaintext text => toJson text
| .markdown markup => toJson markup
structure InlayHintLabelPart where
value : String
tooltip? : Option InlayHintTooltip := none
location? : Option Location := none
command? : Option Command := none
deriving FromJson, ToJson
inductive InlayHintLabel
| name (n : String)
| parts (p : Array InlayHintLabelPart)
instance : FromJson InlayHintLabel where
fromJson?
| .str s => .ok <| .name s
| j@(.arr _) => do return .parts (← fromJson? j)
| j => .error s!"invalid inlay hint label {j}"
instance : ToJson InlayHintLabel where
toJson
| .name n => toJson n
| .parts p => toJson p
inductive InlayHintKind where
| type
| parameter
instance : FromJson InlayHintKind where
fromJson?
| 1 => .ok .type
| 2 => .ok .parameter
| j => .error s!"unknown inlay hint kind {j}"
instance : ToJson InlayHintKind where
toJson
| .type => 1
| .parameter => 2
structure InlayHint where
position : Position
label : InlayHintLabel
kind? : Option InlayHintKind := none
textEdits? : Option (Array TextEdit) := none
tooltip? : Option (InlayHintTooltip) := none
paddingLeft? : Option Bool := none
paddingRight? : Option Bool := none
data? : Option Json := none
deriving FromJson, ToJson
structure InlayHintClientCapabilities where
dynamicRegistration? : Option Bool := none
resolveSupport? : Option ResolveSupport := none
deriving FromJson, ToJson
structure InlayHintOptions extends WorkDoneProgressOptions where
resolveProvider? : Option Bool := none
deriving FromJson, ToJson
inductive ParameterInformationLabel
| name (name : String)
| range (startUtf16Offset endUtf16Offset : Nat)
instance : FromJson ParameterInformationLabel where
fromJson?
| .str name => .ok <| .name name
| .arr #[startUtf16OffsetJson, endUtf16OffsetJson] => do
return .range (← fromJson? startUtf16OffsetJson) (← fromJson? endUtf16OffsetJson)
| _ => .error "unexpected JSON for `ParameterInformationLabel`"
instance : ToJson ParameterInformationLabel where
toJson
| .name name => .str name
| .range startUtf16Offset endUtf16Offset => .arr #[startUtf16Offset, endUtf16Offset]
structure ParameterInformation where
label : ParameterInformationLabel
documentation? : Option MarkupContent := none
deriving FromJson, ToJson
structure SignatureInformation where
label : String
documentation? : Option MarkupContent := none
parameters? : Option (Array ParameterInformation) := none
activeParameter? : Option Nat := none
deriving FromJson, ToJson
structure SignatureHelp where
signatures : Array SignatureInformation
activeSignature? : Option Nat := none
activeParameter? : Option Nat := none
deriving FromJson, ToJson
inductive SignatureHelpTriggerKind where
| invoked
| triggerCharacter
| contentChange
instance : FromJson SignatureHelpTriggerKind where
fromJson?
| (1 : Nat) => .ok .invoked
| (2 : Nat) => .ok .triggerCharacter
| (3 : Nat) => .ok .contentChange
| _ => .error "Unexpected JSON in `SignatureHelpTriggerKind`"
instance : ToJson SignatureHelpTriggerKind where
toJson
| .invoked => 1
| .triggerCharacter => 2
| .contentChange => 3
structure SignatureHelpContext where
triggerKind : SignatureHelpTriggerKind
triggerCharacter? : Option String := none
isRetrigger : Bool
activeSignatureHelp? : Option SignatureHelp := none
deriving FromJson, ToJson
structure SignatureHelpParams extends TextDocumentPositionParams, WorkDoneProgressParams where
context? : Option SignatureHelpContext := none
deriving FromJson, ToJson
structure SignatureHelpOptions extends WorkDoneProgressOptions where
triggerCharacters? : Option (Array String) := none
retriggerCharacters? : Option (Array String) := none
deriving FromJson, ToJson
structure DocumentColorParams extends WorkDoneProgressParams, PartialResultParams where
textDocument : TextDocumentIdentifier
deriving FromJson, ToJson
structure Color where
red : Float
green : Float
blue : Float
alpha : Float
deriving FromJson, ToJson
structure ColorInformation where
range : Range
color : Color
deriving FromJson, ToJson
structure DocumentColorOptions extends WorkDoneProgressOptions where
deriving FromJson, ToJson
end Lsp
end Lean