File: IndexedRenameRequest.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 (104 lines) | stat: -rw-r--r-- 3,879 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
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 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
//
//===----------------------------------------------------------------------===//

/// Rename all occurrences of a symbol named `oldName` to `newName` at the
/// given `positions`.
///
/// The use case of this method is for when the positions to rename are already
/// known, eg. from an index lookup outside of clangd's built-in index. In
/// particular, it determines the edits necessary to rename multi-piece
/// Objective-C selector names.
///
/// `textDocument` is used to determine the language options for the symbol to
/// rename, eg. to decide whether `oldName` and `newName` are Objective-C
/// selectors or normal identifiers.
///
/// This is a clangd extension.
public struct IndexedRenameRequest: TextDocumentRequest, Hashable {
  public static let method: String = "workspace/indexedRename"
  public typealias Response = WorkspaceEdit?

  /// The document in which the declaration to rename is declared. Its compiler
  /// arguments are used to infer language settings for the rename.
  public var textDocument: TextDocumentIdentifier

  /// The old name of the symbol.
  public var oldName: String

  /// The new name of the symbol.
  public var newName: String

  /// The positions at which the symbol is known to appear and that should be
  /// renamed. The key is a document URI
  public var positions: [DocumentURI: [Position]]

  public init(
    textDocument: TextDocumentIdentifier,
    oldName: String,
    newName: String,
    positions: [DocumentURI: [Position]]
  ) {
    self.textDocument = textDocument
    self.oldName = oldName
    self.newName = newName
    self.positions = positions
  }
}

// Workaround for Codable not correctly encoding dictionaries whose keys aren't strings.
extension IndexedRenameRequest: Codable {
  private enum CodingKeys: CodingKey {
    case textDocument
    case oldName
    case newName
    case positions
  }

  public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)

    self.textDocument = try container.decode(
      TextDocumentIdentifier.self,
      forKey: IndexedRenameRequest.CodingKeys.textDocument
    )
    self.oldName = try container.decode(String.self, forKey: IndexedRenameRequest.CodingKeys.oldName)
    self.newName = try container.decode(String.self, forKey: IndexedRenameRequest.CodingKeys.newName)
    self.positions = try container.decode([String: [Position]].self, forKey: .positions).compactMapKeys {
      try? DocumentURI(string: $0)
    }
  }

  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)

    try container.encode(self.textDocument, forKey: IndexedRenameRequest.CodingKeys.textDocument)
    try container.encode(self.oldName, forKey: IndexedRenameRequest.CodingKeys.oldName)
    try container.encode(self.newName, forKey: IndexedRenameRequest.CodingKeys.newName)
    try container.encode(
      self.positions.compactMapKeys { $0.stringValue },
      forKey: IndexedRenameRequest.CodingKeys.positions
    )

  }
}

fileprivate extension Dictionary {
  func compactMapKeys<NewKeyType: Hashable>(_ transform: (Key) -> NewKeyType?) -> [NewKeyType: Value] {
    let newKeysAndValues = self.compactMap { (key, value) -> (NewKeyType, Value)? in
      guard let newKey = transform(key) else {
        return nil
      }
      return (newKey, value)
    }
    return [NewKeyType: Value](uniqueKeysWithValues: newKeysAndValues)
  }
}