@@ -16,98 +16,85 @@ import Foundation
16
16
import SwiftParser
17
17
import SwiftSyntax
18
18
19
- final class Swift2JavaVisitor : SyntaxVisitor {
19
+ final class Swift2JavaVisitor {
20
20
let translator : Swift2JavaTranslator
21
21
22
- /// Type context stack associated with the syntax.
23
- var typeContext : [ ( syntaxID: Syntax . ID , type: ImportedNominalType ) ] = [ ]
24
-
25
- /// Innermost type context.
26
- var currentType : ImportedNominalType ? { typeContext. last? . type }
27
-
28
- var currentSwiftType : SwiftType ? {
29
- guard let currentType else { return nil }
30
- return . nominal( SwiftNominalType ( nominalTypeDecl: currentType. swiftNominal) )
31
- }
32
-
33
- /// The current type name as a nested name like A.B.C.
34
- var currentTypeName : String ? { self . currentType? . swiftNominal. qualifiedName }
35
-
36
- var log : Logger { translator. log }
37
-
38
22
init ( translator: Swift2JavaTranslator ) {
39
23
self . translator = translator
40
-
41
- super. init ( viewMode: . all)
42
24
}
43
25
44
- /// Push specified type to the type context associated with the syntax.
45
- func pushTypeContext( syntax: some SyntaxProtocol , importedNominal: ImportedNominalType ) {
46
- typeContext. append ( ( syntax. id, importedNominal) )
47
- }
26
+ var log : Logger { translator. log }
48
27
49
- /// Pop type context if the current context is associated with the syntax.
50
- func popTypeContext( syntax: some SyntaxProtocol ) -> Bool {
51
- if typeContext. last? . syntaxID == syntax. id {
52
- typeContext. removeLast ( )
53
- return true
54
- } else {
55
- return false
28
+ func visit( sourceFile node: SourceFileSyntax ) {
29
+ for codeItem in node. statements {
30
+ if let declNode = codeItem. item. as ( DeclSyntax . self) {
31
+ self . visit ( decl: declNode, in: nil )
32
+ }
56
33
}
57
34
}
58
35
59
- override func visit( _ node: ClassDeclSyntax ) -> SyntaxVisitorContinueKind {
60
- log. debug ( " Visit \( node. kind) : ' \( node. qualifiedNameForDebug) ' " )
61
- guard let importedNominalType = translator. importedNominalType ( node, parent: self . currentType) else {
62
- return . skipChildren
36
+ func visit( decl node: DeclSyntax , in parent: ImportedNominalType ? ) {
37
+ switch node. as ( DeclSyntaxEnum . self) {
38
+ case . actorDecl( let node) :
39
+ self . visit ( nominalDecl: node, in: parent)
40
+ case . classDecl( let node) :
41
+ self . visit ( nominalDecl: node, in: parent)
42
+ case . structDecl( let node) :
43
+ self . visit ( nominalDecl: node, in: parent)
44
+ case . enumDecl( let node) :
45
+ self . visit ( nominalDecl: node, in: parent)
46
+ case . protocolDecl( let node) :
47
+ self . visit ( nominalDecl: node, in: parent)
48
+ case . extensionDecl( let node) :
49
+ self . visit ( extensionDecl: node, in: parent)
50
+ case . typeAliasDecl:
51
+ break // TODO: Implement
52
+ case . associatedTypeDecl:
53
+ break // TODO: Implement
54
+
55
+ case . initializerDecl( let node) :
56
+ self . visit ( initializerDecl: node, in: parent)
57
+ case . functionDecl( let node) :
58
+ self . visit ( functionDecl: node, in: parent)
59
+ case . variableDecl( let node) :
60
+ self . visit ( variableDecl: node, in: parent)
61
+ case . subscriptDecl:
62
+ // TODO: Implement
63
+ break
64
+
65
+ default :
66
+ break
63
67
}
64
-
65
- self . pushTypeContext ( syntax: node, importedNominal: importedNominalType)
66
- return . visitChildren
67
68
}
68
69
69
- override func visitPost( _ node: ClassDeclSyntax ) {
70
- if self . popTypeContext ( syntax: node) {
71
- log. debug ( " Completed import: \( node. kind) \( node. name) " )
70
+ func visit(
71
+ nominalDecl node: some DeclSyntaxProtocol & DeclGroupSyntax & NamedDeclSyntax & WithAttributesSyntax & WithModifiersSyntax ,
72
+ in parent: ImportedNominalType ?
73
+ ) {
74
+ guard let importedNominalType = translator. importedNominalType ( node, parent: parent) else {
75
+ return
72
76
}
73
- }
74
-
75
- override func visit( _ node: StructDeclSyntax ) -> SyntaxVisitorContinueKind {
76
- log. debug ( " Visit \( node. kind) : \( node. qualifiedNameForDebug) " )
77
- guard let importedNominalType = translator. importedNominalType ( node, parent: self . currentType) else {
78
- return . skipChildren
77
+ for memberItem in node. memberBlock. members {
78
+ self . visit ( decl: memberItem. decl, in: importedNominalType)
79
79
}
80
-
81
- self . pushTypeContext ( syntax: node, importedNominal: importedNominalType)
82
- return . visitChildren
83
80
}
84
81
85
- override func visitPost( _ node: StructDeclSyntax ) {
86
- if self . popTypeContext ( syntax: node) {
87
- log. debug ( " Completed import: \( node. kind) \( node. qualifiedNameForDebug) " )
82
+ func visit( extensionDecl node: ExtensionDeclSyntax , in parent: ImportedNominalType ? ) {
83
+ guard parent != nil else {
84
+ // 'extension' in a nominal type is invalid. Ignore
85
+ return
88
86
}
89
- }
90
-
91
- override func visit( _ node: ExtensionDeclSyntax ) -> SyntaxVisitorContinueKind {
92
- // Resolve the extended type of the extension as an imported nominal, and
93
- // recurse if we found it.
94
87
guard let importedNominalType = translator. importedNominalType ( node. extendedType) else {
95
- return . skipChildren
88
+ return
96
89
}
97
-
98
- self . pushTypeContext ( syntax: node, importedNominal: importedNominalType)
99
- return . visitChildren
100
- }
101
-
102
- override func visitPost( _ node: ExtensionDeclSyntax ) {
103
- if self . popTypeContext ( syntax: node) {
104
- log. debug ( " Completed import: \( node. kind) \( node. qualifiedNameForDebug) " )
90
+ for memberItem in node. memberBlock. members {
91
+ self . visit ( decl: memberItem. decl, in: importedNominalType)
105
92
}
106
93
}
107
94
108
- override func visit( _ node: FunctionDeclSyntax ) -> SyntaxVisitorContinueKind {
95
+ func visit( functionDecl node: FunctionDeclSyntax , in typeContext : ImportedNominalType ? ) {
109
96
guard node. shouldImport ( log: log) else {
110
- return . skipChildren
97
+ return
111
98
}
112
99
113
100
self . log. debug ( " Import function: ' \( node. qualifiedNameForDebug) ' " )
@@ -116,12 +103,12 @@ final class Swift2JavaVisitor: SyntaxVisitor {
116
103
do {
117
104
signature = try SwiftFunctionSignature (
118
105
node,
119
- enclosingType: self . currentSwiftType ,
106
+ enclosingType: typeContext ? . swiftType ,
120
107
symbolTable: self . translator. symbolTable
121
108
)
122
109
} catch {
123
110
self . log. debug ( " Failed to import: ' \( node. qualifiedNameForDebug) '; \( error) " )
124
- return . skipChildren
111
+ return
125
112
}
126
113
127
114
let imported = ImportedFunc (
@@ -133,22 +120,20 @@ final class Swift2JavaVisitor: SyntaxVisitor {
133
120
)
134
121
135
122
log. debug ( " Record imported method \( node. qualifiedNameForDebug) " )
136
- if let currentType {
137
- currentType . methods. append ( imported)
123
+ if let typeContext {
124
+ typeContext . methods. append ( imported)
138
125
} else {
139
126
translator. importedGlobalFuncs. append ( imported)
140
127
}
141
-
142
- return . skipChildren
143
128
}
144
129
145
- override func visit( _ node: VariableDeclSyntax ) -> SyntaxVisitorContinueKind {
130
+ func visit( variableDecl node: VariableDeclSyntax , in typeContext : ImportedNominalType ? ) {
146
131
guard node. shouldImport ( log: log) else {
147
- return . skipChildren
132
+ return
148
133
}
149
134
150
135
guard let binding = node. bindings. first else {
151
- return . skipChildren
136
+ return
152
137
}
153
138
154
139
let varName = " \( binding. pattern. trimmed) "
@@ -159,7 +144,7 @@ final class Swift2JavaVisitor: SyntaxVisitor {
159
144
let signature = try SwiftFunctionSignature (
160
145
node,
161
146
isSet: kind == . setter,
162
- enclosingType: self . currentSwiftType ,
147
+ enclosingType: typeContext ? . swiftType ,
163
148
symbolTable: self . translator. symbolTable
164
149
)
165
150
@@ -170,10 +155,10 @@ final class Swift2JavaVisitor: SyntaxVisitor {
170
155
apiKind: kind,
171
156
functionSignature: signature
172
157
)
173
-
158
+
174
159
log. debug ( " Record imported variable accessor \( kind == . getter ? " getter " : " setter " ) : \( node. qualifiedNameForDebug) " )
175
- if let currentType {
176
- currentType . variables. append ( imported)
160
+ if let typeContext {
161
+ typeContext . variables. append ( imported)
177
162
} else {
178
163
translator. importedGlobalVariables. append ( imported)
179
164
}
@@ -189,18 +174,16 @@ final class Swift2JavaVisitor: SyntaxVisitor {
189
174
}
190
175
} catch {
191
176
self . log. debug ( " Failed to import: \( node. qualifiedNameForDebug) ; \( error) " )
192
- return . skipChildren
193
177
}
194
-
195
- return . skipChildren
196
178
}
197
179
198
- override func visit( _ node: InitializerDeclSyntax ) -> SyntaxVisitorContinueKind {
199
- guard let currentType else {
200
- fatalError ( " Initializer must be within a current type, was: \( node) " )
180
+ func visit( initializerDecl node: InitializerDeclSyntax , in typeContext: ImportedNominalType ? ) {
181
+ guard let typeContext else {
182
+ self . log. info ( " Initializer must be within a current type; \( node) " )
183
+ return
201
184
}
202
185
guard node. shouldImport ( log: log) else {
203
- return . skipChildren
186
+ return
204
187
}
205
188
206
189
self . log. debug ( " Import initializer: \( node. kind) ' \( node. qualifiedNameForDebug) ' " )
@@ -209,12 +192,12 @@ final class Swift2JavaVisitor: SyntaxVisitor {
209
192
do {
210
193
signature = try SwiftFunctionSignature (
211
194
node,
212
- enclosingType: self . currentSwiftType ,
195
+ enclosingType: typeContext . swiftType ,
213
196
symbolTable: self . translator. symbolTable
214
197
)
215
198
} catch {
216
199
self . log. debug ( " Failed to import: \( node. qualifiedNameForDebug) ; \( error) " )
217
- return . skipChildren
200
+ return
218
201
}
219
202
let imported = ImportedFunc (
220
203
module: translator. swiftModuleName,
@@ -224,13 +207,7 @@ final class Swift2JavaVisitor: SyntaxVisitor {
224
207
functionSignature: signature
225
208
)
226
209
227
- currentType. initializers. append ( imported)
228
-
229
- return . skipChildren
230
- }
231
-
232
- override func visit( _ node: DeinitializerDeclSyntax ) -> SyntaxVisitorContinueKind {
233
- return . skipChildren
210
+ typeContext. initializers. append ( imported)
234
211
}
235
212
}
236
213
0 commit comments