Skip to content

Commit 131f09f

Browse files
committed
Doc
1 parent e39890f commit 131f09f

File tree

1 file changed

+69
-55
lines changed

1 file changed

+69
-55
lines changed

Sources/JExtractSwiftLib/SwiftTypes/SwiftTypeLookupContext.swift

Lines changed: 69 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,68 +15,24 @@
1515
import SwiftSyntax
1616
@_spi(Experimental) import SwiftLexicalLookup
1717

18+
/// Unqualified type lookup manager.
19+
/// All unqualified lookup should be done via this instance. This caches the
20+
/// association of `Syntax.ID` to `SwiftTypeDeclaration`, and guarantees that
21+
/// there's only one `SwiftTypeDeclaration` per declaration `Syntax`.
1822
class SwiftTypeLookupContext {
1923
var symbolTable: SwiftSymbolTable
2024

21-
var typeDecls: [Syntax.ID: SwiftTypeDeclaration] = [:]
25+
private var typeDecls: [Syntax.ID: SwiftTypeDeclaration] = [:]
2226

2327
init(symbolTable: SwiftSymbolTable) {
2428
self.symbolTable = symbolTable
2529
}
2630

27-
func typeDeclaration(for node: some SyntaxProtocol) throws -> SwiftTypeDeclaration? {
28-
if let found = typeDecls[node.id] {
29-
return found
30-
}
31-
32-
let typeDecl: SwiftTypeDeclaration
33-
switch Syntax(node).as(SyntaxEnum.self) {
34-
case .genericParameter(let node):
35-
typeDecl = SwiftGenericParameterDeclaration(moduleName: symbolTable.moduleName, node: node)
36-
case .classDecl(let node):
37-
typeDecl = try nominalTypeDeclaration(for: node)
38-
case .actorDecl(let node):
39-
typeDecl = try nominalTypeDeclaration(for: node)
40-
case .structDecl(let node):
41-
typeDecl = try nominalTypeDeclaration(for: node)
42-
case .enumDecl(let node):
43-
typeDecl = try nominalTypeDeclaration(for: node)
44-
case .protocolDecl(let node):
45-
typeDecl = try nominalTypeDeclaration(for: node)
46-
case .typeAliasDecl:
47-
fatalError("typealias not implemented")
48-
case .associatedTypeDecl:
49-
fatalError("associatedtype not implemented")
50-
default:
51-
throw TypeLookupError.notType(Syntax(node))
52-
}
53-
54-
typeDecls[node.id] = typeDecl
55-
return typeDecl
56-
}
57-
58-
func parentTypeDecl(for node: some DeclSyntaxProtocol) throws -> SwiftNominalTypeDeclaration? {
59-
var node: DeclSyntax = DeclSyntax(node)
60-
while let parentDecl = node.ancestorDecl {
61-
switch parentDecl.as(DeclSyntaxEnum.self) {
62-
case .structDecl, .classDecl, .actorDecl, .enumDecl, .protocolDecl:
63-
return (try typeDeclaration(for: parentDecl) as! SwiftNominalTypeDeclaration)
64-
default:
65-
node = parentDecl
66-
continue
67-
}
68-
}
69-
return nil
70-
}
71-
72-
func nominalTypeDeclaration(for node: NominalTypeDeclSyntaxNode) throws -> SwiftNominalTypeDeclaration {
73-
SwiftNominalTypeDeclaration(
74-
moduleName: self.symbolTable.moduleName,
75-
parent: try parentTypeDecl(for: node),
76-
node: node
77-
)
78-
}
79-
31+
/// Perform unqualified type lookup.
32+
///
33+
/// - Parameters:
34+
/// - name: name to lookup
35+
/// - node: `Syntax` node the lookup happened
8036
func unqualifiedLookup(name: Identifier, from node: some SyntaxProtocol) throws -> SwiftTypeDeclaration? {
8137

8238
for result in node.lookup(name) {
@@ -113,7 +69,8 @@ class SwiftTypeLookupContext {
11369
return symbolTable.lookupTopLevelNominalType(name.name)
11470
}
11571

116-
func typeDeclaration(for names: [LookupName]) -> SwiftTypeDeclaration? {
72+
/// Find the first type declaration in the `LookupName` results.
73+
private func typeDeclaration(for names: [LookupName]) -> SwiftTypeDeclaration? {
11774
for name in names {
11875
switch name {
11976
case .identifier(let identifiableSyntax, _):
@@ -130,6 +87,63 @@ class SwiftTypeLookupContext {
13087
}
13188
return nil
13289
}
90+
91+
/// Returns the type declaration object associated with the `Syntax` node.
92+
/// If there's no declaration created, create an instance on demand, and cache it.
93+
func typeDeclaration(for node: some SyntaxProtocol) throws -> SwiftTypeDeclaration? {
94+
if let found = typeDecls[node.id] {
95+
return found
96+
}
97+
98+
let typeDecl: SwiftTypeDeclaration
99+
switch Syntax(node).as(SyntaxEnum.self) {
100+
case .genericParameter(let node):
101+
typeDecl = SwiftGenericParameterDeclaration(moduleName: symbolTable.moduleName, node: node)
102+
case .classDecl(let node):
103+
typeDecl = try nominalTypeDeclaration(for: node)
104+
case .actorDecl(let node):
105+
typeDecl = try nominalTypeDeclaration(for: node)
106+
case .structDecl(let node):
107+
typeDecl = try nominalTypeDeclaration(for: node)
108+
case .enumDecl(let node):
109+
typeDecl = try nominalTypeDeclaration(for: node)
110+
case .protocolDecl(let node):
111+
typeDecl = try nominalTypeDeclaration(for: node)
112+
case .typeAliasDecl:
113+
fatalError("typealias not implemented")
114+
case .associatedTypeDecl:
115+
fatalError("associatedtype not implemented")
116+
default:
117+
throw TypeLookupError.notType(Syntax(node))
118+
}
119+
120+
typeDecls[node.id] = typeDecl
121+
return typeDecl
122+
}
123+
124+
/// Create a nominal type declaration instance for the specified syntax node.
125+
private func nominalTypeDeclaration(for node: NominalTypeDeclSyntaxNode) throws -> SwiftNominalTypeDeclaration {
126+
SwiftNominalTypeDeclaration(
127+
moduleName: self.symbolTable.moduleName,
128+
parent: try parentTypeDecl(for: node),
129+
node: node
130+
)
131+
}
132+
133+
/// Find a parent nominal type declaration of the specified syntax node.
134+
private func parentTypeDecl(for node: some DeclSyntaxProtocol) throws -> SwiftNominalTypeDeclaration? {
135+
var node: DeclSyntax = DeclSyntax(node)
136+
while let parentDecl = node.ancestorDecl {
137+
switch parentDecl.as(DeclSyntaxEnum.self) {
138+
case .structDecl, .classDecl, .actorDecl, .enumDecl, .protocolDecl:
139+
return (try typeDeclaration(for: parentDecl) as! SwiftNominalTypeDeclaration)
140+
default:
141+
node = parentDecl
142+
continue
143+
}
144+
}
145+
return nil
146+
}
133147
}
134148

135149
enum TypeLookupError: Error {

0 commit comments

Comments
 (0)