Files
sourcekit-lsp/SourceKitLSPDevUtils/Sources/ConfigSchemaGen/OptionDocument.swift
2024-12-09 02:12:19 +09:00

109 lines
4.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//===----------------------------------------------------------------------===//
//
// 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 workspaces 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
}
}
}