Skip to content

Commit 5c45835

Browse files
authored
Merge pull request #384 from tayloraswift/overloadable-vars
enable type signature disambiguation for `var`s
2 parents a5b7eec + f63a4f3 commit 5c45835

File tree

7 files changed

+67
-39
lines changed

7 files changed

+67
-39
lines changed

Sources/MarkdownPluginSwift/Signatures/SignatureSyntax.AbridgedVisitor.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,4 @@ extension SignatureSyntax.AbridgedVisitor:SignatureVisitor
1515
{
1616
.init(syntax: parameter, type: type)
1717
}
18-
19-
mutating
20-
func register(returns:TypeSyntax)
21-
{
22-
}
2318
}

Sources/MarkdownPluginSwift/Signatures/SignatureSyntax.Builder.swift

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,32 @@ extension SignatureSyntax.Builder
4343
}
4444
}
4545
}
46-
47-
private mutating
48-
func register(returns clause:ReturnClauseSyntax)
49-
{
50-
self.visitor.register(returns: clause.type)
51-
self.encoder += clause
52-
}
5346
}
5447

5548
extension SignatureSyntax.Builder<SignatureSyntax.ExpandedVisitor>
5649
{
5750
mutating
5851
func encode(decl:DeclSyntax)
5952
{
53+
// It’s easier to detect the return type this way, since we don’t inject any
54+
// indentation markers into its syntax.
55+
if let decl:FunctionDeclSyntax = decl.as(FunctionDeclSyntax.self),
56+
let returns:ReturnClauseSyntax = decl.signature.returnClause
57+
{
58+
self.visitor.register(returns: returns.type)
59+
}
60+
else if
61+
let decl:SubscriptDeclSyntax = decl.as(SubscriptDeclSyntax.self)
62+
{
63+
self.visitor.register(returns: decl.returnClause.type)
64+
}
65+
else if
66+
let decl:VariableDeclSyntax = decl.as(VariableDeclSyntax.self),
67+
let type:TypeSyntax = decl.bindings.first?.typeAnnotation?.type
68+
{
69+
self.visitor.register(returns: type)
70+
}
71+
6072
for region:Syntax in decl.children(viewMode: .sourceAccurate)
6173
{
6274
if let region:TokenSyntax = region.as(TokenSyntax.self)
@@ -91,12 +103,6 @@ extension SignatureSyntax.Builder<SignatureSyntax.ExpandedVisitor>
91103
{
92104
self.register(parameters: clause, type: .func)
93105
}
94-
else if
95-
let clause:ReturnClauseSyntax =
96-
region.as(ReturnClauseSyntax.self)
97-
{
98-
self.register(returns: clause)
99-
}
100106
else
101107
{
102108
self.encoder += region
@@ -110,11 +116,6 @@ extension SignatureSyntax.Builder<SignatureSyntax.ExpandedVisitor>
110116
{
111117
self.register(parameters: clause, type: .subscript)
112118
}
113-
else if
114-
let clause:ReturnClauseSyntax = region.as(ReturnClauseSyntax.self)
115-
{
116-
self.register(returns: clause)
117-
}
118119
else
119120
{
120121
self.encoder += region
@@ -247,7 +248,7 @@ extension SignatureSyntax.Builder<SignatureSyntax.AbridgedVisitor>
247248
self.encode(decl.genericParameterClause?.trimmed)
248249

249250
self.register(parameters: decl.parameterClause, type: .subscript)
250-
self.register(returns: decl.returnClause.trimmed)
251+
self.encoder += decl.returnClause.trimmed
251252
}
252253
else if
253254
let decl:TypeAliasDeclSyntax = decl.as(TypeAliasDeclSyntax.self)
@@ -311,7 +312,7 @@ extension SignatureSyntax.Builder<SignatureSyntax.AbridgedVisitor>
311312
{
312313
self.register(parameters: function.parameterClause, type: .func)
313314
self.encoder ?= function.effectSpecifiers
314-
self.register(returns: returns.trimmed)
315+
self.encoder += returns.trimmed
315316
}
316317
else if
317318
let effects:FunctionEffectSpecifiersSyntax = function.effectSpecifiers

Sources/MarkdownPluginSwift/Signatures/SignatureSyntax.ExpandedVisitor.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ extension SignatureSyntax.ExpandedVisitor:SignatureVisitor
3333
inputs.append(autographer.autograph)
3434
return .init(syntax: parameter)
3535
}
36-
36+
}
37+
extension SignatureSyntax.ExpandedVisitor
38+
{
3739
mutating
3840
func register(returns:TypeSyntax)
3941
{
@@ -50,9 +52,7 @@ extension SignatureSyntax.ExpandedVisitor:SignatureVisitor
5052
self.register(output: element.type)
5153
}
5254
}
53-
}
54-
extension SignatureSyntax.ExpandedVisitor
55-
{
55+
5656
private mutating
5757
func register(output:TypeSyntax)
5858
{

Sources/MarkdownPluginSwift/Signatures/SignatureVisitor.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,4 @@ protocol SignatureVisitor
66

77
mutating
88
func register(parameter:FunctionParameterSyntax, type:SignatureParameterType) -> Parameter
9-
10-
mutating
11-
func register(returns:TypeSyntax)
129
}

Sources/MarkdownPluginSwiftTests/Autographs.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,36 @@ struct Autographs
8585
#expect(self.landmarks.output == ["(Int)->(Int)->Int"])
8686
}
8787

88+
@Test mutating
89+
func Var1()
90+
{
91+
let decl:String = "static var x: (String)? { get }"
92+
let _:Signature<Never>.Expanded = .init(decl, landmarks: &self.landmarks)
93+
94+
#expect(self.landmarks.inputs == [])
95+
#expect(self.landmarks.output == ["String?"])
96+
}
97+
98+
@Test mutating
99+
func Var2()
100+
{
101+
let decl:String = "static var x: (T?, Set<T>) { get set }"
102+
let _:Signature<Never>.Expanded = .init(decl, landmarks: &self.landmarks)
103+
104+
#expect(self.landmarks.inputs == [])
105+
#expect(self.landmarks.output == ["T?", "Set<T>"])
106+
}
107+
108+
@Test mutating
109+
func Var3()
110+
{
111+
let decl:String = "var x: (Int, Int) -> (Int) -> Int"
112+
let _:Signature<Never>.Expanded = .init(decl, landmarks: &self.landmarks)
113+
114+
#expect(self.landmarks.inputs == [])
115+
#expect(self.landmarks.output == ["(Int,Int)->(Int)->Int"])
116+
}
117+
88118
@Test mutating
89119
func SomeAndAnyTypes()
90120
{

Sources/SymbolGraphParts/Vertices/SymbolGraphPart.Vertex.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,14 @@ extension SymbolGraphPart.Vertex
8181
{
8282
/// We will amend the actual phylum later in this function, but none of the amendments
8383
/// should affect the overloadability of the symbol.
84-
let isDirectlyOverloadable:Bool
84+
let isOverloadable:Bool
8585
if case .decl(let decl) = phylum
8686
{
87-
isDirectlyOverloadable = decl.isDirectlyOverloadable
87+
isOverloadable = decl.isOverloadable
8888
}
8989
else
9090
{
91-
isDirectlyOverloadable = false
91+
isOverloadable = false
9292
}
9393
/// Static `Self` can appear in more places than just where `isDirectlyOverloadable`,
9494
/// but it will only be used if that is also true, so there is no point in computing it
@@ -111,7 +111,7 @@ extension SymbolGraphPart.Vertex
111111
sugarDictionary: .sSD,
112112
sugarArray: .sSa,
113113
sugarOptional: .sSq,
114-
desugarSelf: isDirectlyOverloadable
114+
desugarSelf: isOverloadable
115115
? path.prefixFormatted(inserting: generics.parameters)
116116
: nil,
117117
landmarks: &landmarks)
@@ -173,7 +173,7 @@ extension SymbolGraphPart.Vertex
173173
final: landmarks.keywords.final,
174174
extension: `extension`,
175175
signature: signature,
176-
autograph: isDirectlyOverloadable
176+
autograph: isOverloadable
177177
? .init(inputs: landmarks.inputs, output: landmarks.output)
178178
: nil,
179179
path: simplified,

Sources/Symbols/Declarations/Phylum.Decl.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,15 @@ extension Phylum.Decl
4646
}
4747

4848
@inlinable public
49-
var isDirectlyOverloadable:Bool
49+
var isOverloadable:Bool
5050
{
5151
switch self
5252
{
5353
case .actor: false
5454
case .associatedtype: false
55+
// No, `case` is not overloadable, even though it is function-like. It would never make
56+
// sense to try and disambiguate a `case` by type signature instead of using the
57+
// `[case]` disambiguator.
5558
case .case: false
5659
case .class: false
5760
case .deinitializer: false
@@ -64,7 +67,9 @@ extension Phylum.Decl
6467
case .struct: false
6568
case .subscript: true
6669
case .typealias: false
67-
case .var: false
70+
// Yes, `var` is overloadable! The most common example is `static var _:Self { get }`,
71+
// with different overloads for different generic constraints.
72+
case .var: true
6873
}
6974
}
7075
/// Indicates if the declaration is typelike. This is not the same as ``orientation``!

0 commit comments

Comments
 (0)