Files
swift-mirror/test/Frontend/ast-dump-json-conformance-context.swift
Tony Allevato 770a6b2869 [ASTDumper] Print the USR for a protocol conformance's declaring context.
It's useful to know where a conformance is coming from when doing semantic
analysis. The main motivating use case is this: imagine a module that
declares a type:

```swift
// SomeTypeModule
struct SomeType {}
```

Then a second module that adds a conformance:

```swift
// SomeTypeConformanceModule
extension SomeType: @retroactive Codable {
  // implementation of requirements
}
```

Then a third module that uses that conformance:

```swift
import SomeTypeModule
import SomeTypeConformanceModule

func f() {
  _ = try? JSONEncoder().encode(SomeType())
}
```

There's currently nothing in the printed AST that indicates that the import
of `SomeTypeConformanceModule` is required. Printing the declaring context
for conformances lets us get that signal from the substitution map at the
call site in `f()`.

Also removed a place where we redundantly output `retroactive`.
2025-12-04 15:45:14 -05:00

53 lines
2.1 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-frontend %t/SomeProtocolModule.swift -parse-as-library -emit-module -emit-module-path %t/SomeProtocolModule.swiftmodule -module-name SomeProtocolModule
// RUN: %target-swift-frontend %t/SomeTypeModule.swift -parse-as-library -emit-module -emit-module-path %t/SomeTypeModule.swiftmodule -module-name SomeTypeModule
// RUN: %target-swift-frontend %t/SomeTypeConformanceModule.swift -I %t -parse-as-library -emit-module -emit-module-path %t/SomeTypeConformanceModule.swiftmodule -module-name SomeTypeConformanceModule
// RUN: %target-swift-frontend %t/Client.swift -I %t -parse-as-library -dump-ast -dump-ast-format json -module-name Client -o - > %t/Client.json
// RUN: %{python} -c 'import json, sys; print(json.dumps(json.load(sys.stdin), indent=4))' < %t/Client.json | %FileCheck %s
//--- SomeProtocolModule.swift
public protocol SomeProtocol {}
//--- SomeTypeModule.swift
public struct SomeType {
public init() {}
}
//--- SomeTypeConformanceModule.swift
import SomeProtocolModule
import SomeTypeModule
extension SomeType: @retroactive SomeProtocol {}
//--- Client.swift
import SomeProtocolModule
import SomeTypeConformanceModule
import SomeTypeModule
func g<T: SomeProtocol>(_ t: T) {}
func f() {
g(SomeType())
}
// CHECK: "substitutions": {
// CHECK-NEXT: "_kind": "substitution_map",
// CHECK: "reqs": [
// CHECK: {
// CHECK-NEXT: "_kind": "conformance",
// CHECK-NEXT: "type": "$sxD",
// CHECK-NEXT: "conformance": {
// CHECK-NEXT: "_kind": "normal_conformance",
// CHECK-NEXT: "type": "$s14SomeTypeModule0aB0VD",
// CHECK-NEXT: "protocol": "s:18SomeProtocolModule0aB0P",
// CHECK: "context": {
// CHECK-NEXT: "_kind": "conformance_context",
// CHECK-NEXT: "decl": "s:e:s:14SomeTypeModule0aB0Vs:18SomeProtocolModule0aB0P",
// CHECK-NEXT: "module": "SomeTypeConformanceModule"
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }