Skip to content

Commit 4c1040a

Browse files
committed
support detection of the async keyword, and filtering overloads on asyncness
1 parent 83fb25b commit 4c1040a

File tree

14 files changed

+189
-20
lines changed

14 files changed

+189
-20
lines changed

Sources/LinkResolution/UCF.DisambiguationTraits.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@ extension UCF
1414
public
1515
let kinks:Phylum.Decl.Kinks
1616
public
17+
let async:Bool
18+
public
1719
let hash:FNV24
1820

1921
@inlinable public
2022
init(autograph:Autograph?,
2123
phylum:Phylum.Decl,
2224
kinks:Phylum.Decl.Kinks,
25+
async:Bool,
2326
hash:FNV24)
2427
{
2528
self.autograph = autograph
2629
self.phylum = phylum
2730
self.kinks = kinks
31+
self.async = async
2832
self.hash = hash
2933
}
3034
}

Sources/LinkResolution/UCF.Predicate.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ extension UCF.Predicate
235235
case (_, .class_var): given = false
236236
case (_, .static_var): given = false
237237

238+
case (_, .async): given = traits.async
238239
case (_, .requirement): given = kinks[is: .required]
239240
default: continue
240241
}

Sources/MarkdownPluginSwift/Signatures/Signature.Expanded (ext).swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,6 @@ extension Signature.Expanded
123123
default: break
124124
}
125125
}
126-
if case .keyword = color
127-
{
128-
// The `actor` and `async` keywords are contextual; there is no
129-
// other way to detect them besides inspecting token text!
130-
switch String.init(decoding: utf8[range], as: Unicode.UTF8.self)
131-
{
132-
case "actor": landmarks.keywords.actor = true
133-
case "class": landmarks.keywords.class = true
134-
case "final": landmarks.keywords.final = true
135-
default: break
136-
}
137-
}
138126

139127
fallthrough
140128

Sources/MarkdownPluginSwift/Signatures/SignatureLandmarks.InterestingKeywords.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ extension SignatureLandmarks
88
public
99
var actor:Bool
1010
public
11+
var async:Bool
12+
public
1113
var attached:Bool
1214
public
1315
var `class`:Bool
@@ -17,13 +19,16 @@ extension SignatureLandmarks
1719
var freestanding:Bool
1820

1921
@inlinable
20-
init(actor:Bool = false,
22+
init(
23+
actor:Bool = false,
24+
async:Bool = false,
2125
attached:Bool = false,
2226
`class`:Bool = false,
2327
final:Bool = false,
2428
freestanding:Bool = false)
2529
{
2630
self.actor = actor
31+
self.async = async
2732
self.attached = attached
2833
self.class = `class`
2934
self.final = final

Sources/MarkdownPluginSwift/Signatures/SignatureSyntax.Builder.swift

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,28 +52,57 @@ extension SignatureSyntax.Builder<SignatureSyntax.ExpandedVisitor>
5252
{
5353
// It’s easier to detect the return type this way, since we don’t inject any
5454
// indentation markers into its syntax.
55-
if let decl:FunctionDeclSyntax = decl.as(FunctionDeclSyntax.self),
56-
let returns:ReturnClauseSyntax = decl.signature.returnClause
55+
if let decl:InitializerDeclSyntax = decl.as(InitializerDeclSyntax.self)
5756
{
58-
self.visitor.register(returns: returns.type)
57+
self.visitor.mark(with: decl.modifiers)
58+
self.visitor.mark(with: decl.signature.effectSpecifiers)
59+
}
60+
else if
61+
let decl:FunctionDeclSyntax = decl.as(FunctionDeclSyntax.self)
62+
{
63+
self.visitor.mark(with: decl.modifiers)
64+
self.visitor.mark(with: decl.signature.effectSpecifiers)
65+
if let returns:ReturnClauseSyntax = decl.signature.returnClause
66+
{
67+
self.visitor.register(returns: returns.type)
68+
}
5969
}
6070
else if
6171
let decl:SubscriptDeclSyntax = decl.as(SubscriptDeclSyntax.self)
6272
{
73+
self.visitor.mark(with: decl.modifiers)
74+
self.visitor.mark(with: decl.accessorBlock)
75+
6376
self.visitor.register(returns: decl.returnClause.type)
6477
}
6578
else if
6679
let decl:VariableDeclSyntax = decl.as(VariableDeclSyntax.self),
67-
let type:TypeSyntax = decl.bindings.first?.typeAnnotation?.type
80+
let binding:PatternBindingSyntax = decl.bindings.first
81+
{
82+
self.visitor.mark(with: decl.modifiers)
83+
self.visitor.mark(with: binding.accessorBlock)
84+
if let type:TypeSyntax = binding.typeAnnotation?.type
85+
{
86+
self.visitor.register(returns: type)
87+
}
88+
}
89+
else if
90+
let decl:ActorDeclSyntax = decl.as(ActorDeclSyntax.self)
91+
{
92+
self.visitor.mark(with: decl.modifiers)
93+
self.visitor.actor = true
94+
}
95+
else if
96+
let decl:ClassDeclSyntax = decl.as(ClassDeclSyntax.self)
6897
{
69-
self.visitor.register(returns: type)
98+
self.visitor.mark(with: decl.modifiers)
7099
}
71100

72101
for region:Syntax in decl.children(viewMode: .sourceAccurate)
73102
{
74103
if let region:TokenSyntax = region.as(TokenSyntax.self)
75104
{
76-
// Allows us to detect phylum keywords.
105+
// Do we still need this?
77106
self.encoder[at: .toplevel] += region
78107
}
79108
else if
@@ -84,7 +113,7 @@ extension SignatureSyntax.Builder<SignatureSyntax.ExpandedVisitor>
84113
else if
85114
let region:DeclModifierListSyntax = region.as(DeclModifierListSyntax.self)
86115
{
87-
// Allows us to detect `class` modifier keywords.
116+
// Do we still need this?
88117
self.encoder[at: .toplevel] += region
89118
}
90119
else if

Sources/MarkdownPluginSwift/Signatures/SignatureSyntax.ExpandedVisitor.swift

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ extension SignatureSyntax
77
{
88
let sugarMap:SugarMap
99

10+
var actor:Bool
11+
private(set)
12+
var async:Bool
13+
private(set)
14+
var `class`:Bool
15+
private(set)
16+
var final:Bool
17+
1018
private(set)
1119
var inputs:[String]
1220
private(set)
@@ -16,11 +24,16 @@ extension SignatureSyntax
1624
init(sugaring sugarMap:SugarMap)
1725
{
1826
self.sugarMap = sugarMap
27+
self.actor = false
28+
self.async = false
29+
self.class = false
30+
self.final = false
1931
self.inputs = []
2032
self.output = []
2133
}
2234
}
2335
}
36+
2437
extension SignatureSyntax.ExpandedVisitor:SignatureVisitor
2538
{
2639
mutating
@@ -35,6 +48,48 @@ extension SignatureSyntax.ExpandedVisitor:SignatureVisitor
3548
}
3649
}
3750
extension SignatureSyntax.ExpandedVisitor
51+
{
52+
mutating
53+
func mark(with modifiers:DeclModifierListSyntax)
54+
{
55+
for modifier:DeclModifierSyntax in modifiers
56+
{
57+
switch modifier.name.tokenKind
58+
{
59+
case .keyword(.class): self.class = true
60+
case .keyword(.final): self.final = true
61+
default: continue
62+
}
63+
}
64+
}
65+
66+
mutating
67+
func mark(with effects:FunctionEffectSpecifiersSyntax?)
68+
{
69+
if case .keyword(.async)? = effects?.asyncSpecifier?.tokenKind
70+
{
71+
self.async = true
72+
}
73+
}
74+
75+
mutating
76+
func mark(with accessorBlock:AccessorBlockSyntax?)
77+
{
78+
if case .accessors(let accessors)? = accessorBlock?.accessors
79+
{
80+
for accessor:AccessorDeclSyntax in accessors
81+
{
82+
if let effects:AccessorEffectSpecifiersSyntax = accessor.effectSpecifiers,
83+
case .keyword(.get) = accessor.accessorSpecifier.tokenKind,
84+
case .keyword(.async)? = effects.asyncSpecifier?.tokenKind
85+
{
86+
self.async = true
87+
}
88+
}
89+
}
90+
}
91+
}
92+
extension SignatureSyntax.ExpandedVisitor
3893
{
3994
mutating
4095
func register(returns:TypeSyntax)

Sources/MarkdownPluginSwift/Signatures/SignatureSyntax.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ extension SignatureSyntax
8686

8787
builder.encode(decl: .parse(from: &parser))
8888

89+
landmarks.keywords.actor = builder.visitor.actor
90+
landmarks.keywords.async = builder.visitor.async
91+
landmarks.keywords.class = builder.visitor.class
92+
landmarks.keywords.final = builder.visitor.final
93+
8994
landmarks.inputs = builder.visitor.inputs
9095
landmarks.output = builder.visitor.output
9196

Sources/MarkdownPluginSwiftTests/InterestingKeywords.swift

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,63 @@ struct InterestingKeywords
2626
#expect("\(signature.bytecode.safe)" == decl)
2727
#expect(self.landmarks.keywords.actor)
2828
}
29+
30+
@Test mutating
31+
func Async1()
32+
{
33+
let decl:String = "func f() async"
34+
35+
let signature:Signature<Never>.Expanded = .init(decl,
36+
landmarks: &self.landmarks)
37+
38+
#expect("\(signature.bytecode.safe)" == decl)
39+
#expect(self.landmarks.keywords.async)
40+
}
41+
@Test mutating
42+
func Async2()
43+
{
44+
let decl:String = "func async(async: Int)"
45+
46+
let signature:Signature<Never>.Expanded = .init(decl,
47+
landmarks: &self.landmarks)
48+
49+
#expect("\(signature.bytecode.safe)" == decl)
50+
#expect(!self.landmarks.keywords.async)
51+
}
52+
@Test mutating
53+
func Async3()
54+
{
55+
let decl:String = "func f(_: (Int) async -> ())"
56+
57+
let signature:Signature<Never>.Expanded = .init(decl,
58+
landmarks: &self.landmarks)
59+
60+
#expect("\(signature.bytecode.safe)" == decl)
61+
#expect(!self.landmarks.keywords.async)
62+
}
63+
@Test mutating
64+
func Async4()
65+
{
66+
let decl:String = "subscript(i: Int) { get async throws set }"
67+
68+
let signature:Signature<Never>.Expanded = .init(decl,
69+
landmarks: &self.landmarks)
70+
71+
#expect("\(signature.bytecode.safe)" == decl)
72+
#expect(self.landmarks.keywords.async)
73+
}
74+
@Test mutating
75+
func Async5()
76+
{
77+
let decl:String = "var x: Int { get async set }"
78+
79+
let signature:Signature<Never>.Expanded = .init(decl,
80+
landmarks: &self.landmarks)
81+
82+
#expect("\(signature.bytecode.safe)" == decl)
83+
#expect(self.landmarks.keywords.async)
84+
}
85+
2986
@Test mutating
3087
func Final()
3188
{

Sources/SymbolGraphCompiler/Declarations/SSGC.Decl.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ extension SSGC
2626
public
2727
let phylum:Phylum.Decl
2828
public
29+
let async:Bool
30+
public
2931
let path:UnqualifiedPath
3032

3133
/// Protocol requirements.
@@ -67,6 +69,7 @@ extension SSGC
6769
phylum:Phylum.Decl,
6870
path:UnqualifiedPath,
6971
kinks:Phylum.Decl.Kinks,
72+
async:Bool,
7073
comment:DocumentationComment?)
7174
{
7275
self.id = id
@@ -75,6 +78,7 @@ extension SSGC
7578
self.autograph = autograph
7679
self.location = location
7780
self.phylum = phylum
81+
self.async = async
7882
self.path = path
7983

8084
self.requirements = []
@@ -96,6 +100,7 @@ extension SSGC.Decl
96100
autograph: self.autograph,
97101
phylum: self.phylum,
98102
kinks: self.kinks,
103+
async: self.async,
99104
hash: .decl(self.id))
100105
}
101106

@@ -106,6 +111,7 @@ extension SSGC.Decl
106111
autograph: self.autograph,
107112
phylum: self.phylum,
108113
kinks: self.kinks,
114+
async: self.async,
109115
hash: .decl(.init(self.id, self: heir)))
110116
}
111117
}

Sources/SymbolGraphCompiler/Declarations/SSGC.DeclAlias.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,23 @@ extension SSGC
1616
public
1717
let kinks:Phylum.Decl.Kinks
1818
public
19+
let async:Bool
20+
public
1921
let path:UnqualifiedPath
2022
public
2123
let documented:Bool
2224

2325
init(autograph:UCF.Autograph?,
2426
phylum:Phylum.Decl,
2527
kinks:Phylum.Decl.Kinks,
28+
async:Bool,
2629
path:UnqualifiedPath,
2730
documented:Bool)
2831
{
2932
self.autograph = autograph
3033
self.phylum = phylum
3134
self.kinks = kinks
35+
self.async = async
3236
self.path = path
3337
self.documented = documented
3438
}
@@ -42,6 +46,7 @@ extension SSGC.DeclAlias
4246
autograph: decl.autograph,
4347
phylum: decl.phylum,
4448
kinks: decl.kinks,
49+
async: decl.async,
4550
path: decl.path,
4651
documented: decl.comment != nil)
4752
}

Sources/SymbolGraphCompiler/Declarations/SSGC.Declarations.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ extension SSGC.Declarations
8585
phylum: phylum,
8686
path: vertex.path,
8787
kinks: kinks,
88+
async: vertex.async,
8889
comment: vertex.doccomment.map { .init($0.text, at: $0.start) } ?? nil))
8990

9091
$0 = decl

Sources/SymbolGraphLinker/SSGC.Linker.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ extension SSGC.Linker
337337
autograph: feature.autograph,
338338
phylum: feature.phylum,
339339
kinks: feature.kinks,
340+
async: feature.async,
340341
hash: .decl(.init(id, self: $0.extendee.id))),
341342
decl: f,
342343
heir: extendee,

0 commit comments

Comments
 (0)