File: OptionDocument.swift

package info (click to toggle)
swiftlang 6.1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 2,791,532 kB
  • sloc: cpp: 9,901,743; ansic: 2,201,431; asm: 1,091,827; python: 308,252; objc: 82,166; f90: 80,126; lisp: 38,358; pascal: 25,559; sh: 20,429; ml: 5,058; perl: 4,745; makefile: 4,484; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (107 lines) | stat: -rw-r--r-- 4,187 bytes parent folder | download | duplicates (2)
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
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2024 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
//
//===----------------------------------------------------------------------===//

/// Generates a markdown document for the configuration file based on the schema.
struct OptionDocumentBuilder {
  static let preamble = """
    <!-- DO NOT EDIT THIS FILE. This file is generated by \(#fileID). -->

    # Configuration File

    `.sourcekit-lsp/config.json` configuration files can be used to modify the behavior of SourceKit-LSP in various ways. The following locations are checked. Settings in later configuration files override settings in earlier configuration files
    - `~/.sourcekit-lsp/config.json`
    - On macOS: `~/Library/Application Support/org.swift.sourcekit-lsp/config.json` from the various `Library` folders on the system
    - If the `XDG_CONFIG_HOME` environment variable is set: `$XDG_CONFIG_HOME/sourcekit-lsp/config.json`
    - Initialization options passed in the initialize request
    - A `.sourcekit-lsp/config.json` file in a workspace’s root

    The structure of the file is currently not guaranteed to be stable. Options may be removed or renamed.

    ## Structure

    `config.json` is a JSON file with the following structure. All keys are optional and unknown keys are ignored.

    """

  let context: OptionSchemaContext

  /// Builds a markdown document for the configuration file based on the schema.
  func build(from schema: OptionTypeSchama) throws -> String {
    var doc = Self.preamble

    func appendProperty(_ property: OptionTypeSchama.Property, indentLevel: Int) throws {
      let indent = String(repeating: "  ", count: indentLevel)
      let name = property.name
      doc += "\(indent)- `\(name)"
      let type = property.type
      let typeDescription: String?
      switch type.kind {
      case .struct:
        // Skip struct type as we describe its properties in the next level
        typeDescription = nil
      default:
        typeDescription = Self.typeToDisplay(type)
      }
      if let typeDescription {
        doc += ": \(typeDescription)`:"
      } else {
        doc += "`:"
      }
      if let description = property.description {
        doc += " " + description.split(separator: "\n").joined(separator: "\n\(indent)  ")
      }
      doc += "\n"
      switch type.kind {
      case .struct(let schema):
        for property in schema.properties {
          try appendProperty(property, indentLevel: indentLevel + 1)
        }
      case .enum(let schema):
        for caseInfo in schema.cases {
          // Add detailed description for each case if available
          guard let description = caseInfo.description else {
            continue
          }
          doc += "\(indent)  - `\(caseInfo.name)`"
          doc += ": " + description.split(separator: "\n").joined(separator: "\n\(indent)    ")
          doc += "\n"
        }
      default: break
      }
    }
    guard case .struct(let schema) = schema.kind else {
      throw ConfigSchemaGenError("Root schema must be a struct")
    }
    for property in schema.properties {
      try appendProperty(property, indentLevel: 0)
    }
    return doc
  }

  static func typeToDisplay(_ type: OptionTypeSchama, shouldWrap: Bool = false) -> String {
    switch type.kind {
    case .boolean: return "boolean"
    case .integer: return "integer"
    case .number: return "number"
    case .string: return "string"
    case .array(let value):
      return "\(typeToDisplay(value, shouldWrap: true))[]"
    case .dictionary(let value):
      return "[string: \(typeToDisplay(value))]"
    case .struct(let structInfo):
      return structInfo.name
    case .enum(let enumInfo):
      let cases = enumInfo.cases.map { "\"\($0.name)\"" }.joined(separator: "|")
      return shouldWrap ? "(\(cases))" : cases
    }
  }
}