File: CompletionRequest.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (204 lines) | stat: -rw-r--r-- 7,556 bytes parent folder | download
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

/// Request for code-completion items at the given document location.
///
/// The server may - or may not - filter and sort the results before returning them. If the server
/// performs server-side filtering, it should set the `isIncomplete` flag on the result. However,
/// since there are no particular rules specified for server-side filtering, the client likely will
/// want to perform its own filtering as well.
///
/// Servers that provide document highlights should set the `completionProvider` server capability.
///
/// - Parameters:
///   - textDocument: The document to perform completion in.
///   - position: The location to perform completion at.
///   - context: Optional code-completion context.
///
/// - Returns: A list of completion items to complete the code at the given position.
public struct CompletionRequest: TextDocumentRequest, Hashable {
  public static let method: String = "textDocument/completion"
  public typealias Response = CompletionList

  public var textDocument: TextDocumentIdentifier

  public var position: Position

  public var context: CompletionContext?

  public init(
    textDocument: TextDocumentIdentifier,
    position: Position,
    context: CompletionContext? = nil
  ) {
    self.textDocument = textDocument
    self.position = position
    self.context = context
  }
}

/// How a completion was triggered
public struct CompletionTriggerKind: RawRepresentable, Codable, Hashable, Sendable {
  /// Completion was triggered by typing an identifier (24x7 code complete), manual invocation (e.g Ctrl+Space) or via API.
  public static let invoked = CompletionTriggerKind(rawValue: 1)

  /// Completion was triggered by a trigger character specified by the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
  public static let triggerCharacter = CompletionTriggerKind(rawValue: 2)

  /// Completion was re-triggered as the current completion list is incomplete.
  public static let triggerFromIncompleteCompletions = CompletionTriggerKind(rawValue: 3)

  public let rawValue: Int
  public init(rawValue: Int) {
    self.rawValue = rawValue
  }
}

/// Contains additional information about the context in which a completion request is triggered.
public struct CompletionContext: Codable, Hashable, Sendable {
  /// How the completion was triggered.
  public var triggerKind: CompletionTriggerKind

  /// The trigger character (a single character) that has trigger code complete. Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
  public var triggerCharacter: String?

  public init(triggerKind: CompletionTriggerKind, triggerCharacter: String? = nil) {
    self.triggerKind = triggerKind
    self.triggerCharacter = triggerCharacter
  }
}

/// List of completion items. If this list has been filtered already, the `isIncomplete` flag
/// indicates that the client should re-query code-completions if the filter text changes.
public struct CompletionList: ResponseType, Hashable {
  public struct InsertReplaceRanges: Codable, Hashable, Sendable {
    @CustomCodable<PositionRange>
    var insert: Range<Position>

    @CustomCodable<PositionRange>
    var replace: Range<Position>

    public init(insert: Range<Position>, replace: Range<Position>) {
      self.insert = insert
      self.replace = replace
    }
  }

  public enum ItemDefaultsEditRange: Codable, Hashable, Sendable {
    case range(Range<Position>)
    case insertReplaceRanges(InsertReplaceRanges)

    public init(from decoder: Decoder) throws {
      if let range = try? PositionRange(from: decoder).wrappedValue {
        self = .range(range)
      } else if let insertReplaceRange = try? InsertReplaceRanges(from: decoder) {
        self = .insertReplaceRanges(insertReplaceRange)
      } else {
        let context = DecodingError.Context(
          codingPath: decoder.codingPath,
          debugDescription: "Expected Range or InsertReplaceRanges"
        )
        throw DecodingError.dataCorrupted(context)
      }
    }

    public func encode(to encoder: Encoder) throws {
      switch self {
      case .range(let range):
        try PositionRange(wrappedValue: range).encode(to: encoder)
      case .insertReplaceRanges(let insertReplaceRanges):
        try insertReplaceRanges.encode(to: encoder)
      }
    }
  }

  public struct ItemDefaults: Codable, Hashable, Sendable {
    /// A default commit character set.
    public var commitCharacters: [String]?

    /// A default edit range
    public var editRange: ItemDefaultsEditRange?

    /// A default insert text format
    public var insertTextFormat: InsertTextFormat?

    /// A default insert text mode
    public var insertTextMode: InsertTextMode?

    /// A default data value.
    public var data: LSPAny?

    public init(
      commitCharacters: [String]? = nil,
      editRange: ItemDefaultsEditRange? = nil,
      insertTextFormat: InsertTextFormat? = nil,
      insertTextMode: InsertTextMode? = nil,
      data: LSPAny? = nil
    ) {
      self.commitCharacters = commitCharacters
      self.editRange = editRange
      self.insertTextFormat = insertTextFormat
      self.insertTextMode = insertTextMode
      self.data = data
    }
  }

  /// Whether the list of completions is "complete" or not.
  ///
  /// When this value is `true`, the client should re-query the server when doing further filtering.
  public var isIncomplete: Bool

  /// In many cases the items of an actual completion result share the same
  /// value for properties like `commitCharacters` or the range of a text
  /// edit. A completion list can therefore define item defaults which will
  /// be used if a completion item itself doesn't specify the value.
  ///
  /// If a completion list specifies a default value and a completion item
  /// also specifies a corresponding value the one from the item is used.
  ///
  /// Servers are only allowed to return default values if the client
  /// signals support for this via the `completionList.itemDefaults`
  /// capability.
  public var itemDefaults: ItemDefaults?

  /// The resulting completions.
  public var items: [CompletionItem]

  public init(isIncomplete: Bool, itemDefaults: ItemDefaults? = nil, items: [CompletionItem]) {
    self.isIncomplete = isIncomplete
    self.itemDefaults = itemDefaults
    self.items = items
  }

  public init(from decoder: Decoder) throws {
    // Try decoding as CompletionList
    do {
      let container = try decoder.container(keyedBy: CodingKeys.self)
      self.isIncomplete = try container.decode(Bool.self, forKey: .isIncomplete)
      self.items = try container.decode([CompletionItem].self, forKey: .items)
      return
    } catch {}

    // Try decoding as [CompletionItem]
    do {
      self.items = try [CompletionItem](from: decoder)
      self.isIncomplete = false
      return
    } catch {}

    let context = DecodingError.Context(
      codingPath: decoder.codingPath,
      debugDescription: "Expected CompletionList or [CompletionItem]"
    )
    throw DecodingError.dataCorrupted(context)
  }
}