← 返回列表
未验证
一个用于 Swift 的 SCIP 索引器。它通过读取与 Xcode 自身的“跳转到定义”和…
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/21 · 已提供中文文档
综合分
28
GitHub 分
28
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add jarvis-intelligence/scip-swift该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/17(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
scip-swift
一个用于 Swift 的 SCIP 索引器。它通过读取与 Xcode 自身的“跳转到定义”和 SourceKit-LSP 所依赖的同一个 IndexStoreDB 索引,将 Swift 仓库的构建索引转换为真正的 scip.proto 输出——真实的 protobuf Index/Document/Symbol/Occurrence 消息,可被任何标准 SCIP 工具(scip CLI、codeintel、Sourcegraph、编辑器插件)使用。
工作原理
1. scip-swift 在启用构建时索引的情况下构建你的仓库:
- SwiftPM 仓库:swift build --enable-index-store
- Xcode 项目仓库:xcodebuild ... COMPILER_INDEX_STORE_ENABLE=YES
2. 它通过 IndexStoreDB 的 SymbolOccurrence 查询 API 读取生成的 IndexStore。
3. 它将每个 occurrence 映射为 SCIP 的 Occurrence/SymbolInformation——包括符号关系(重写)、角色位和最小签名——并生成一个 .scip 文件。
架构
scip-swift 系统架构
逐组件的详细说明请参见 docs/system-architecture.md。
安装
需要 macOS 14(Sonoma)或更高版本。
Homebrew:
brew install phuongddx/scip-swift/scip-swift
或者从源码构建(需要与 .swift-version 中固定版本匹配的 Swift 工具链):
git clone https://github.com/jarvis-intelligence/scip-swift.git
cd scip-swift
swift build -c release
cp .build/release/scip-swift /usr/local/bin/
预构建的通用二进制文件(arm64 + x86_64)附在每个
GitHub release 中。
用法
scip-swift /path/to/your/swift/repo
writes /path/to/your/swift/repo/index.scip
index 子命令是等价的——对于总是传入显式子命令名称的工具很有用(index 也是 scip-swift 的 defaultSubcommand,因此上面的裸形式会分发到它):
scip-swift index /path/to/your/swift/repo --output /path/to/output.scip
选项:
| 标志 | 含义 |
|---|---|
| --output | 写入 .scip 文件的位置(默认:/index.scip) |
| --build-tool swiftpm\|xcodebuild | 覆盖自动检测(Package.swift → swiftpm,.xcodeproj/.xcworkspace → xcodebuild) |
| --configuration debug\|release | 转发给底层构建工具(默认:debug) |
| --scheme | 要构建的 Xcode scheme(仅用于 xcodebuild;如果项目只有一个 scheme,则自动检测) |
| --cache-dir | 增量索引缓存的目录(默认:/.scip-cache)。传入此标志会启用持久缓存 |
| --index-only | 跳过构建步骤,直接读取现有 IndexStore(从缓存目录) |
| --version | 打印转换器版本及其构建所针对的 Swift 工具链版本 |
索引多个仓库
index-many 独立索引两个或多个仓库,为每个仓库写入一个 .scip 文件,或将它们合并为单个索引:
one .scip per repo, written to --output-dir (default: current directory)
scip-swift index-many /path/to/repoA /path/to/repoB --output-dir out/
merge into a single index (default: ./merged.scip)
scip-swift index-many /path/to/repoA /path/to/repoB --merge --merged-output combined.scip
index-many 同样支持 --configuration 和 --cache-dir。
增量索引
传入 --cache-dir(或 --index-only)会将流水线从一次性的临时目录切换为持久化缓存:
- 未更改的文件会复用其先前计算出的 Scip_Document(以文件的相对路径与其 SHA256 内容哈希的组合为键),因此在小型编辑后重新索引时只会重新处理发生更改的内容。
- 当 Swift 工具链版本、scip-swift 版本、indexstore-db 修订版本、构建后端或所输出的符号格式版本(symbolFormatVersion,当前为 5 —— 格式 1 是原始 USR 时代,格式 2 是规范描述符链方案,格式 3 是复合路径+内容哈希缓存键,格式 4 是导入出现 + Test 位,格式 5 是关系字节:类型级 is_implementation 边、关系目标外部符号,以及 stdlib 协议规范形式)发生变化时,缓存会被整体失效(记录在 manifest.json 中)。无法解码的清单——例如由缺少当前字段的旧引擎写入的清单——会被视为没有清单:缓存被整体丢弃,因此旧格式缓存永远不会与新格式输出混合。
- 索引构建器还会对重载表进行指纹计算(对每个重载组的标识及其按源顺序排列的成员 USR 计算 SHA-256),作为全局缓存验证键:重载索引 (+N) 依赖于整个仓库中的每个组成员,因此任何位置的重载更改——即使是在自身内容未更改的文件中——都会使缓存文档失效。这种粒度是刻意保守的(任何重载编辑都会使一切失效);按组精确细化是已记录的 v2 后续工作。
- 每个缓存文档都伴随一个 docs/.usrmap,即用于原始 USR 回退符号的 canonicalSymbol → USR 侧映射,因此外部显示名称在全新运行和缓存命中运行时能够以相同方式解码。它与其 .scipdoc 使用相同的复合(relativePath、内容哈希)键,并与之原子性地一起失效。.scipdoc/.usrmap 键在设计上就是复合的——对 relativePath || 0x00 || contentHash 计算 SHA-256——因此两个字节完全相同的文件永远不会共享同一个缓存条目,而重命名的文件会自然地未命中并重建;格式升级(例如升级到当前的 symbolFormatVersion 3)会通过清单门控整体使旧缓存失效。
- --index-only 会复用缓存目录下已构建的 IndexStore(它不会重新构建),因此如果不存在先前已索引的构建,它会以 indexStoreNotFoundForIndexOnly 失败
在那里。
确定性
对同一存储进行两次索引会得到字节级完全相同的结果,无论缓存状态如何:
- 出现项按 SCIP 的规范规则排序(先按范围起始位置升序,再按范围结束位置升序,最后按符号字符串排序),并按(符号、范围、角色)去重;文档按相对路径升序排列,文档符号按符号字符串升序排列。
- ToolInfo 元数据从不嵌入原始命令行参数(两次使用不同 --output 路径的 CLI 运行之间它们会不同,而且它们会把本地路径泄漏到共享产物中)。它确实携带的一个合成条目是常量 scip-cli-version=(输出所依据的 scip CLI 版本)。
scip CLI 门禁
每个生成的 fixture 索引都由来自
scip-code/scip 的真实 scip CLI 验证——即消费者运行的同一工具——通过
ScipCLIGate 测试套件(Tests/scip-swiftTests/ScipCLIGateTests.swift)进行:
- 对 MiniSwiftPackage、SchemeFixture 和 HierarchiesFixture 索引运行 scip lint 必须以退出码 0 结束,且没有任何 error: 发现。
- SchemeFixture 和 HierarchiesFixture 索引的 scip snapshot --strict=false 输出会与
Tests/scip-swiftTests/SchemeFixtureGoldens/ 和
Tests/scip-swiftTests/HierarchiesFixtureGoldens/ 中提交的黄金文件进行 diff(CLI 没有 verify 模式;目录 diff 由测试框架负责)。
- 门禁二进制文件的版本会与 ScipSwiftVersion.scipCliVersion 交叉核对——CI pin 与引擎常量之间的漂移会导致该套件失败。
门禁可识别的环境变量:
| 变量 | 效果 |
| --- | --- |
| SCIP_BIN | scip 二进制文件的路径(CI 会将其设置为经过校验和验证的固定下载;没有它时,二进制文件必须位于 PATH 上)。当两者都无法解析时,门禁测试会以安装指引 FAIL——它们绝不会静默跳过。 |
| UPDATE_GOLDENS=1 | 重新生成已提交的快照黄金文件,而不是进行 diff(在有意更改输出后使用)。 |
| UPDATE_ROLE_TABLE=1 | 重新生成 Fixtures/SchemeFixture/role-table.json,即由 RoleParity 套件进行 diff 的已提交角色期望表(见下文)。 |
| UPDATE_SYMBOL_TABLE=1 | 重新生成 Fixtures/SchemeFixture/symbol-table.json(见下文的跨仓库一致性检查)。 |
| UPDATE_RELATIONSHIP_TABLE=1 | 重新生成 Fixtures/HierarchiesFixture/relationship-table.json,即由 RelationshipParity 套件进行 diff 的已提交关系期望表(见下文)。 |
CI 通过 HTTPS 从 scip-code/scip GitHub release 下载固定的 CLI tarball,
根据 release 发布的 .sha256 sidecar 进行验证(不匹配会导致作业失败),并以 SCIP_CLI_VERSION 为键进行缓存,因此未更改的 pin 会跳过下载。SCIP_CLI_VERSION
(位于 .github/workflows/ci.yml)是唯一的 pin,并且必须与 ScipSwiftVersion.scipCliVersion 匹配。
CI 还会在固定的 Swift 工具链下进行构建和测试——该工具链通过 XCODE_PIN 选择并验证
工作流的 select 步骤以及套件内的 ToolchainDriftGuard 测试会大声失败。
角色位预言机(RoleParity,NAV-01)
scip snapshot 的插入符输出只渲染四个角色词——definition、
forward_definition、synthetic_definition、reference——因此它永远无法显示
ReadAccess/WriteAccess 位。因此,RoleParity 套件
(Tests/scip-swiftTests/RoleParityTests.swift)是冻结访问位契约的编程式预言机
(write > read/reference > 无访问位;调用点不贡献任何内容):它在进程内重建 SchemeFixture 索引,并断言每个
出现族的角色位——属性写入(在十一个写入点上双向)、
属性/参数/下标读取、两条符号路径上的参数(干净的 local n 符号和
原始 USR 回退 Term)、枚举 case/类型/函数引用、包括 willSet 在内的访问器,
以及定义不变量——对照已提交的期望表
Fixtures/SchemeFixture/role-table.json。仅使用固定工具链,通过
UPDATE_ROLE_TABLE=1 swift test --filter RoleParity 重新生成该表(与
快照黄金文件相同的纪律:角色行是对工具链敏感的数据)。
大纲预言机(DocumentOutline,NAV-02)
documentSymbols 的正确性通过结构方式把关,而不是从字节完全一致的
黄金文件推断:DocumentOutline 套件(Tests/scip-swiftTests/DocumentOutlineTests.swift)
在进程内重建 SchemeFixture 索引,并 (1) 扫描每个文档,以验证
穷尽不变量:每个非空的 enclosing_symbol 都解析为同一文档中的符号(只有 local n 符号携带该字段),(2) 固定局部符号的
封闭目标,(3) 通过按描述符后缀拆分 document.symbols 的规范字符串,
推导出每个文件的嵌套树,并断言它等于手写的期望大纲——对于
库文件(包括 #if 包裹的声明和同文件扩展成员)、扩展文件
(声明作为文件级条目,成员位于被扩展类型下,按冻结方案跨模块),
以及深层嵌套部分(Lattice#Cell#Core#Phase#…,四个容器层级)。可接受的大纲形状
被显式断言,而不是假定——参见 Known limitations 下的大纲要点。
关系预言机(RelationshipParity,REL-01)
关系边像角色一样被把关:在代码中、双向、对照已提交的
黄金文件。RelationshipParity 套件
(Tests/scip-swiftTests/RelationshipParityTests.swift)在进程内重建
Fixtures/HierarchiesFixture 索引(两个模块,HierCore + HierExt——SC4 内容类:协议继承、直接声明和扩展声明的遵循
(对 LOCAL 和 Swift 模块协议——Rect: HierShape, Equatable,
CustomStringConvertible,一个追溯性的 extension Circle: CustomStringConvertible)、
一个条件遵循、一个带有被重写
初始化器/属性/方法的 2 级子类链、一个默认实现、一个以 emoji 命名的遵循类型,以及一个
ObjC 根的子类,以及对本地协议的跨模块追溯性一致性)
并针对引擎当前发出的每一种关系断言两个方向:每一个预期的见证边(.overrideOf → is_reference +
is_implementation,字节稳定的 04-01 基线)以及每一个类型级子句边
(04-02 收获:baseOf/extendedBy 子句引用 → 仅 is_implementation,
scip.proto 的 Find-implementations 语义)都被发出,并且每一个发出的边都是
预期的。04-02 的发出接缝:(a) 子句关系收获将类型级
边附加到该类型在其定义文档中的 SymbolInformation;(b) 追溯性
扩展声明的一致性通过一个针对该类型规范字符串的载体
SymbolInformation 搭载在 EXTENSION 文档上(D-23);(c) 从未作为出现项出现的关系目标会生成到 external_symbols 中(新生成和缓存提供的
文档对称);(d) 关系在发出前已预规范化(升序
目标排序 + 标志 OR 合并,Go CanonicalizeRelationships 的移植);(e) 外部
协议(Equatable、CustomStringConvertible、……)通过 stdlib 协议 USR 解析器
规则解析为冻结的 Swift 模块形式(scip-swift swift Swift Equatable#),
系统性来自解析结果。该测试套件还固定了非边(一致性声明行处的隐式
默认实现出现项不贡献任何
关系)以及语料库不变量(标志、升序目标顺序、每个
符号/目标对一行),并与已提交的预期表
Fixtures/HierarchiesFixture/relationship-table.json 对照。使用
UPDATE_RELATIONSHIP_TABLE=1 swift test --filter RelationshipParity 重新生成该表,且仅在固定
工具链下进行(与快照黄金文件相同的纪律:关系行是
工具链敏感数据)。
层级可回答性预言(CallHierarchy/TypeHierarchy,REL-02/REL-03)
调用层级和类型层级由消费者模拟预言把关,这些预言证明
消费者提出的问题仅凭发出的索引即可回答(两个套件
都在进程内重建 Fixtures/HierarchiesFixture 索引,使用与
RelationshipParity 相同的脚手架,并搭乘同一个 swift test CI 步骤):
- CallHierarchyAnswerability(Tests/scip-swiftTests/CallHierarchyAnswerabilityTests.swift,
REL-02):scip.proto 的 SymbolRole 恰好有八个值,且没有 Call 位,而
Relationship 只有这四个标志——不存在用于合成
调用边的协议表面,而滥用这些标志作为调用通道会破坏 Find References。因此,
索引将每个调用点作为具有精确位置
和访问位的引用出现项携带,而该套件模拟消费者推导:一个符号在其 SymbolInformation 种类为 constructor/function/getter/method/
setter 时属于函数族(这保留了原始 USR 回退 Term 函数——条件一致性见证,
默认实现——可见)或其规范描述符以 ). 结尾(铸造的
外部符号,如 Swift String#init().);按文档,出现位置按位置属性归属于最近的
前置函数定义,并以携带访问位为门控条件(role-0 隐式可用性行会被跳过,与 def 门控的
关系发射完全一致)。对于每个 fixture 函数,outgoing/incoming 集合都会在双向断言——
完整的跨模块链(extCallerOfCaller → extCaller →
coreDriver → Circle init + drawAll)、动态派发(存在类型、类虚方法和
泛型约束位置)通过访问位 + 位置断言,以及语料库范围的
归属不变量(恰好一次、无幻影归属、叶子为空)。已记录的
v1 形态:仅出现回退-Term 调用位置(Double(spokes)、数组字面量)
无法按名称回答,并且 extCallerOfCaller 规范字符串带有一个
词替换误解析(extCallerOf. ——显示名称保持真实)按原样固定;
两者都记录为观察项,而非发射契约。
- TypeHierarchyAnswerability(Tests/scip-swiftTests/TypeHierarchyAnswerabilityTests.swift,
REL-03):supertypes(T) = 每个 SymbolInformation 上的 is_implementation 目标,
其符号为 T(scip.proto 的 Dog/Animal Find-implementations 语义);subtypes
和 protocolImplementations(T) = 对 ALL 文档符号加上
external_symbols 的反向扫描(stdlib 协议遵循者是一等答案)。扩展
声明的遵循关系通过 TYPE 的规范字符串解析,无论载体
文档是什么——D-23 载体将类型的 SymbolInformation 发射到扩展
文档中,因此 Wheel# 会以 HierShape# 和 Glowable# 回答,而 Circle#
会以 HierShape# 和 Swift 的 CustomStringConvertible# 回答。穷尽不变量
断言每条发射的边都可正向 AND 反向回答,且没有幻影结果,
并且类型级期望与 relationship-table.json 的
isReference=false 行(RelationshipParity 黄金文件)一致。
这些消费者派生语义就是 Phase-6 端到端验证
(jarvis callHierarchy/typeHierarchy 查询)所检查的可回答性定义:
incoming/outgoing 调用派生自调用出现 + 最近前置
函数定义;supertypes/implementations 派生自正向 is_implementation 读取
和反向关系扫描,包括外部符号。
导入出现(ImportOccurrence, SYM-04)
每个写出的 import / @testable import 语句都恰好发射一个具有
Import 角色(0x2)的出现——锚定在模块名 token 上(越过任何 @testable
属性)——解析到模块的规范符号,REPLACING 同一锚点处旧的
带回退-Term 的引用行。模块符号形式遵循
冻结的 Phase-1 方案(模块描述符以 / 结尾,绝不以 # 结尾):
- 仓库本地目标模块:scip-swift swiftpm . /
- 外部/系统模块:scip-swift swift /
管理器的选择来自对仓库 Package.swift 的软失败 SwiftSyntax 解析
(PackageTargetMap):在目标列表中命名的模块是仓库本地的;其他所有内容
(Foundation、Testing、SDK 模块)使用 swift 管理器加上固定的工具链
版本。模块符号落在 external_symbols 中,以模块自身的名称作为
显示名称。隐式模块出现——Swift Testing 的宏展开用 c:@M@Testing 引用淹没每个
#expect/@Suite 位置——会被过滤
(!roles.contains(.implicit)):它们仍会作为对模块符号的引用发出,但
从不携带 Import 角色。ImportOccurrence 测试套件
(Tests/scip-swiftTests/ImportOccurrenceTests.swift)在整个语料库范围内证明了这一切:
每个导入恰好一次,锚点精确到列,隐式或
非导入位置零 Import 角色,语料库 Import 计数 == 已写入导入计数,并且两种管理器形式通过引擎自带的格式化器进行字节完全一致的
往返转换。
测试目标标记(TestTargetMarking,NAV-03)
测试目标文档中的出现携带 Test 位,并与其其他角色组合
(definition|test 0x21、read|test 0x28、write|test 0x24、import|test 0x22)——
即“为某个符号定位测试”的查询;库目标文档
(Sources/)中的任何出现都从不携带它。检测由 Package.swift 驱动(同一个
PackageTargetMap):PRIMARY = 文档的 relativePath 落在某个 .testTarget 声明的(或默认 Tests/)路径下;SECONDARY = 文档的存储
location.moduleName 命名了一个测试目标。SymbolRoleMapping 中存储的 SymbolProperty.unitTest 属性
路径被保留作为保险:对于 SwiftPM + Swift
Testing 目标它从不触发(经验上如此),但对于 XCTest 形态的目标它确实会触发(类 +
方法出现会携带它),因此无论哪种方式标记都保持正确。
TestTargetMarking 测试套件(Tests/scip-swiftTests/TestTargetMarkingTests.swift)证明了
两个方向,并在具体位置固定了组合后的位值。
干净运行器可复现性(CleanRunner,PROJ-01)
在符号
格式 4 下写入的缓存会被下一次运行整体失效(清单门控;当前
发出的字节格式版本是 5——参见
Sources/scip-swift/Caching/IndexManifest.swift 中的 SymbolFormatVersion)。
在冷缓存上运行 scip-swift index 会复现字节完全一致的输出。CLI 默认
路径(不带 --cache-dir/--index-only)在构造上就是冷的——暂存区、索引数据库和
缓存都落在新的临时目录中。CleanRunner 测试套件
(Tests/scip-swiftTests/CleanRunnerTests.swift)将证明作为测试接入每次推送:
使用持久缓存目录进行两次冷运行,该目录在两次运行之间被删除(加上
默认路径的双次运行),必须序列化出字节完全一致且文档非空的索引,
按文档的符号和出现次数,以及高于阈值的定义/引用承载计数——绝不是一个空但 lint 干净的索引。构建失败会以可操作的方式暴露:在 fixture COPY 中注入的语法错误会抛出 BuildError.buildFailed,其消息会指明 swift build 并携带完整的编译器输出。以符号格式 3 写入的缓存会被下一次运行整体失效(清单门控;当前发出的字节格式版本为 4——参见 Sources/scip-swift/Caching/IndexManifest.swift 中的 SymbolFormatVersion)。
macOS 主机要求
对任何导入了仅限 Apple 平台框架(UIKit、WatchKit、WidgetKit)的仓库进行索引,都需要一台装有 Xcode 和相关 SDK 的 macOS 主机——Apple 不提供适用于 Linux 的 iOS SDK。不包含这些导入的纯 Swift 包代码可以在 Linux 上构建(并被索引),但对于真实的 iOS 应用仓库来说,这并不是常见情况。如果底层构建命令因这一原因失败,scip-swift 会将其作为构建失败暴露出来,而不是静默地生成部分索引。
已知限制
- 规范描述符符号,原始 USR 回退:Scip_SymbolInformation.symbol 是一条规范描述符链(scip-swift swiftpm MyMod . Shape#resize(+1).),直接解析自编译器的 USR——绝不派生自 demangler,后者仅用于显示。解析器无法处理的 USR(奇特的替换、参数、格式错误的输入)会回退为规范模块头下的单个转义 Term;每次运行都会打印有多少符号采用了该回退。已知的沿用方案限制(随 Phase-1 规范冻结):
- Term 系列的追溯性冲突无法携带 (+N)——SCIP 语法只允许在 Method 描述符上使用消歧符,因此跨声明模块的追溯性属性/let/case 冲突会渲染出相同的字符串。
- 同名的 getter 和零参数方法会合并为一个 SymbolInformation(它们渲染出相同的字符串);保留下来的 Kind 是源代码顺序中最后的定义。
- 参数采用原始 USR 回退——其规范形式需要对外围函数进行容器解析,计划在后续阶段实现。
- 大纲形状(documentSymbols),已接受的 v1 行为——由 DocumentOutline 测试套件门控:
- 扩展声明是文件级条目。 一个 extension Vec { … } 声明会发出一个回退 Term 的 SymbolInformation(kind 为 Extension),它无法通过其符号字符串进行嵌套;其成员会跨模块嵌套在被扩展类型的路径下(SYM-02)。被扩展类型随后在扩展文件中是一个仅路径的大纲节点。
- 泛型类型参数在 TypeAlias kind 下发出定义。 存储中没有 genericTypeParam 符号 kind,因此 Box#T# 渲染为 kind TypeAlias(WR-05)——类型参数描述符形式([T])绝不会出现在发出的符号中。
- Swift-Testing 文档不携带局部属性符号 — 在固定工具链上,存储不会为测试文件声明发出 .local 出现,因此测试文档中的 enclosing_symbol 覆盖为空(该不变量在此处平凡成立)。
- enclosing_symbol 目标渲染为未消歧的重载组形式 — locals 分支组装 .childOf 符号时不带重载索引,因此 parse(+1) 内部的局部符号携带 parse() 字符串。该目标仍可在同一文档内解析;添加 (+N) 会改变发出的字节(需要 symbolFormatVersion 升级)。
- 参数是文件级原始 USR 回退 Term(D-06),因此它们无法通过符号字符串嵌套在其所属函数之下;而没有存储属性的结构体会在 outline 中获得编译器合成的默认 init() 定义。
- 出现范围:IndexStoreDB(与底层 IndexStore 格式一样)每次出现只记录一个锚点——而不是起始/结束范围。结束列是来自文件 SwiftSyntax 解析的精确标识符 token 范围;名称长度近似仅作为解析器无法恢复的区域(例如严重畸形的语法)的回退保留。静态链接 SwiftSyntax/SwiftParser 会使发布二进制从约 7 MB 增长到约 24.5 MB——这是本里程碑接受的权衡(无需发布单独的解析器二进制即可获得编译器级 token 范围)。
- 无调用层级角色:真实 scip.proto 的 SymbolRole 枚举没有调用专用位;调用
- 关系:witness 边(.overrideOf → is_reference + is_implementation)
和类型级子句边(baseOf/extendedBy 采集 → 仅 is_implementation,
附加到该类型的 SymbolInformation;追溯性 conformance 随
extension 文档)。接受的 v1 限制——ObjC 超类回退
(ObjCSuperclassClauseMap,D-21):一个有界、计数的 SwiftSyntax 带,用于类
子句,其存储记录不携带 baseOf;在固定工具链上,存储
记录 NSObject 子句配对本身,因此该带在
夹具上触发零次(单元证明,计数器在诊断中呈现)。接受的 v1 Term
限制:协议扩展成员 USR(…PAAE…/…Rzl 形状)、extension 声明
s:e: USR,以及 c:objc 目标渲染为原始 USR 回退 Term(按原样固定于
relationship-table.json;解析器规则会扩大格式版本涟漪,
而对 REL-01/REL-03 没有增益)。
- Apple 不保证 USR 跨工具链版本的稳定性——黄金
可复现性由工具链固定。 本项目固定其构建和测试所针对的 Swift 工具链版本
(见 .swift-version);使用不同工具链
版本进行索引在实践中可能没问题,但不是受支持/测试的配置。具体来说:
Swift Testing 合成的访问器 USR 携带依赖工具链的哈希后缀,而较新的
工具链会发出额外的标准库插值出现
(DefaultStringInterpolation.appendLiteral/appendPart)——这两者都是在 Swift 6.3.3
运行器针对 6.2.4 生成的黄金文件构建索引时观察到的。因此,提交在
Tests/scip-swiftTests/SchemeFixtureGoldens/ 下的快照黄金文件仅在
.swift-version 固定版本下可复现;CI 强制执行这一点(通过 XCODE_PIN 选择固定的 Xcode,并在
发生漂移时大声失败,另外还有套件内的工具链漂移防护),所以在
不同工具链上出现黄金文件差异是环境漂移,而不是回归。要更改固定版本:切换到
新工具链(xcode-select 或 DEVELOPER_DIR),更新 .swift-version +
ToolchainInfo.pinnedSwiftVersion + 工作流固定版本对(.github/workflows/ci.yml 中的 SWIFT_TOOLCHAIN_PIN/
XCODE_PIN),并在新工具链下使用
UPDATE_GOLDENS=1 有意重新生成黄金文件。
开发
swift build
swift test
重新生成随附的 SCIP protobuf 绑定(仅在 Protos/scip.proto 从上游 sourcegraph/scip 更新时
需要):
brew install protobuf swift-protobuf
Protos/generate.sh
许可证
Apache-2.0 — 参见 LICENSE。扫码进群