SourceKitten

一个可爱的小框架和命令行工具,用于与 SourceKit 交互。

SourceKitten 连接并与 sourcekitd.framework 通信,以解析 Swift AST,提取 Swift 或 Objective-C 项目的注释文档,获取 Swift 文件的语法数据等等!

SwiftPM

安装

构建 SourceKitten 需要 Xcode 13.3 或更高版本,或者 Swift 5.6 工具链或更高版本以及 Swift Package Manager。

SourceKitten 通常支持 SourceKit 的先前版本。

Homebrew

运行 brew install sourcekitten

Swift Package Manager

在此项目的根目录下运行 swift build

Bazel

将以下内容添加到您的 WORKSPACE 文件

SOURCEKITTEN_VERSION = "SOME_VERSION"
SOURCEKITTEN_SHA = "SOME_SHA"
http_archive(
    name = "com_github_jpsim_sourcekitten",
    url = "https://github.com/jpsim/SourceKitten/archive/refs/tags/%s.tar.gz" % (SOURCEKITTEN_VERSION),
    sha256 = SOURCEKITTEN_SHA,
    strip_prefix = "SourceKitten-%s" % SOURCEKITTEN_VERSION
)

然后运行:bazel run @com_github_jpsim_sourcekitten//:sourcekitten -- -h

Xcode (通过 Make)

在此项目的根目录下运行 make install

Package

发布标签 下载并打开 SourceKitten.pkg。

命令行用法

安装 SourceKitten 后,您可以从命令行使用它。

$ sourcekitten help
OVERVIEW: An adorable little command line tool for interacting with SourceKit

USAGE: sourcekitten <subcommand>

OPTIONS:
  --version               Show the version.
  -h, --help              Show help information.

SUBCOMMANDS:
  complete                Generate code completion options
  doc                     Print Swift or Objective-C docs as JSON
  format                  Format Swift file
  index                   Index Swift file and print as JSON
  module-info             Obtain information about a Swift module and print as JSON
  request                 Run a raw SourceKit request
  structure               Print Swift structure information as JSON
  syntax                  Print Swift syntax information as JSON
  version                 Display the current version of SourceKitten

  See 'sourcekitten help <subcommand>' for detailed help.

SourceKit 是如何解析的?

SourceKitten 按以下顺序搜索 SourceKit

在 Linux 上,SourceKit 预计位于 /usr/lib/libsourcekitdInProc.so 中,或者由 LINUX_SOURCEKIT_LIB_PATH 环境变量指定。

使用 SourceKitten 构建的项目

查看更多

Complete

运行 sourcekitten complete --file file.swift --offset 123sourcekitten complete --text "0." --offset 2 将为提供的文件/文本中的偏移量打印出代码补全选项

[{
  "descriptionKey" : "advancedBy(n: Distance)",
  "associatedUSRs" : "s:FSi10advancedByFSiFSiSi s:FPSs21RandomAccessIndexType10advancedByuRq_S__Fq_Fqq_Ss16ForwardIndexType8Distanceq_ s:FPSs16ForwardIndexType10advancedByuRq_S__Fq_Fqq_S_8Distanceq_ s:FPSs10Strideable10advancedByuRq_S__Fq_Fqq_S_6Strideq_ s:FPSs11_Strideable10advancedByuRq_S__Fq_Fqq_S_6Strideq_",
  "kind" : "source.lang.swift.decl.function.method.instance",
  "sourcetext" : "advancedBy(<#T##n: Distance##Distance#>)",
  "context" : "source.codecompletion.context.thisclass",
  "typeName" : "Int",
  "moduleName" : "Swift",
  "name" : "advancedBy(n: Distance)"
},
{
  "descriptionKey" : "advancedBy(n: Self.Distance, limit: Self)",
  "associatedUSRs" : "s:FeRq_Ss21RandomAccessIndexType_SsS_10advancedByuRq_S__Fq_FTqq_Ss16ForwardIndexType8Distance5limitq__q_",
  "kind" : "source.lang.swift.decl.function.method.instance",
  "sourcetext" : "advancedBy(<#T##n: Self.Distance##Self.Distance#>, limit: <#T##Self#>)",
  "context" : "source.codecompletion.context.superclass",
  "typeName" : "Self",
  "moduleName" : "Swift",
  "name" : "advancedBy(n: Self.Distance, limit: Self)"
},
...
]

要使用 iOS SDK,请传递以 -- 开头的 -sdk-target 参数

sourcekitten complete --text "import UIKit ; UIColor." --offset 22 -- -target arm64-apple-ios9.0 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk

Doc

运行 sourcekitten doc 会将解析后的所有参数传递给 xcodebuild(或直接传递给编译器 SourceKit/clang,在 --single-file 模式下)。

用法示例

  1. sourcekitten doc -- -workspace SourceKitten.xcworkspace -scheme SourceKittenFramework
  2. sourcekitten doc --single-file file.swift -- -j4 file.swift
  3. sourcekitten doc --module-name Alamofire -- -project Alamofire.xcodeproj
  4. sourcekitten doc -- -workspace Haneke.xcworkspace -scheme Haneke
  5. sourcekitten doc --objc Realm/Realm.h -- -x objective-c -isysroot $(xcrun --show-sdk-path) -I $(pwd)

Structure

运行 sourcekitten structure --file file.swiftsourcekitten structure --text "struct A { func b() {} }" 将返回一个结构信息的 JSON 数组

{
  "key.substructure" : [
    {
      "key.kind" : "source.lang.swift.decl.struct",
      "key.offset" : 0,
      "key.nameoffset" : 7,
      "key.namelength" : 1,
      "key.bodyoffset" : 10,
      "key.bodylength" : 13,
      "key.length" : 24,
      "key.substructure" : [
        {
          "key.kind" : "source.lang.swift.decl.function.method.instance",
          "key.offset" : 11,
          "key.nameoffset" : 16,
          "key.namelength" : 3,
          "key.bodyoffset" : 21,
          "key.bodylength" : 0,
          "key.length" : 11,
          "key.substructure" : [

          ],
          "key.name" : "b()"
        }
      ],
      "key.name" : "A"
    }
  ],
  "key.offset" : 0,
  "key.diagnostic_stage" : "source.diagnostic.stage.swift.parse",
  "key.length" : 24
}

Syntax

运行 sourcekitten syntax --file file.swiftsourcekitten syntax --text "import Foundation // Hello World" 将返回一个语法高亮信息的 JSON 数组

[
  {
    "offset" : 0,
    "length" : 6,
    "type" : "source.lang.swift.syntaxtype.keyword"
  },
  {
    "offset" : 7,
    "length" : 10,
    "type" : "source.lang.swift.syntaxtype.identifier"
  },
  {
    "offset" : 18,
    "length" : 14,
    "type" : "source.lang.swift.syntaxtype.comment"
  }
]

Request

运行 sourcekitten request --yaml [FILE|TEXT] 将使用给定的 yaml 执行 sourcekit 请求。例如

key.request: source.request.cursorinfo
key.sourcefile: "/tmp/foo.swift"
key.offset: 8
key.compilerargs:
  - "/tmp/foo.swift"

SourceKittenFramework

sourcekitten 命令行工具的大部分功能实际上封装在一个名为 SourceKittenFramework 的框架中。

如果您有兴趣将 SourceKitten 用作另一个工具的一部分,或者扩展其功能,请查看 SourceKittenFramework 源代码,看看 API 是否满足您的需求。

注意:SourceKitten 完全用 Swift 编写,SourceKittenFramework API 不适用于与 Objective-C 交互。

License

MIT 许可。