@@ -58,73 +58,112 @@ struct ASTGenVisitor {
5858 }
5959
6060 func generate( sourceFile node: SourceFileSyntax ) -> [ BridgedASTNode ] {
61- var out = [ BridgedASTNode] ( )
62- let isTopLevel = self . declContext. isModuleScopeContext
61+ // If not top-level, no need for 'TopLevelCodeDecl' treatment.
62+ if !self . declContext. isModuleScopeContext {
63+ return self . generate ( codeBlockItemList: node. statements)
64+ } else {
65+ return self . generateTopLevel ( codeBlockItemList: node. statements)
66+ }
67+ }
6368
64- visitIfConfigElements (
65- node. statements,
66- of: CodeBlockItemSyntax . self,
67- split: Self . splitCodeBlockItemIfConfig
68- ) { element in
69+ func generateTopLevel( codeBlockItem node: CodeBlockItemSyntax ) -> BridgedASTNode ? {
70+ let parentDC = self . declContext
6971
70- func generateStmtOrExpr( _ body: ( ) -> BridgedASTNode ) -> BridgedASTNode {
71- if !isTopLevel {
72- return body ( )
73- }
72+ func maybeTopLevelCodeDecl( body: ( ) -> BridgedASTNode ? ) -> BridgedASTNode ? {
73+ let topLevelDecl : BridgedTopLevelCodeDecl = BridgedTopLevelCodeDecl . create ( self . ctx, declContext: self . declContext)
74+ guard let astNode = withDeclContext ( topLevelDecl. asDeclContext, body) else {
75+ return nil
76+ }
77+
78+ if astNode. kind == . decl {
79+ // If a decl is generated, discard the TopLevelCodeDecl.
80+ return astNode
81+ }
7482
75- let topLevelDecl = BridgedTopLevelCodeDecl . create ( self . ctx, declContext: self . declContext)
76- let astNode = withDeclContext ( topLevelDecl. asDeclContext) {
77- body ( )
83+ // Diagnose top-level code in non-script files.
84+ if !declContext. parentSourceFile. isScriptMode {
85+ switch astNode. kind {
86+ case . stmt:
87+ self . diagnose ( . illegalTopLevelStmt( node) )
88+ case . expr:
89+ self . diagnose ( . illegalTopLevelExpr( node) )
90+ case . decl:
91+ fatalError ( " unreachable " )
7892 }
93+ }
94+
95+ let bodyRange = self . generateImplicitBraceRange ( node)
96+ let body = BridgedBraceStmt . createImplicit (
97+ self . ctx,
98+ lBraceLoc: bodyRange. start,
99+ element: astNode,
100+ rBraceLoc: bodyRange. end
101+ )
102+ topLevelDecl. setBody ( body: body)
103+ return . decl( topLevelDecl. asDecl)
104+ }
79105
80- // Diagnose top level code in non-script file.
81- if ( !declContext. parentSourceFile. isScriptMode) {
82- switch element. item {
83- case . stmt:
84- self . diagnose ( . illegalTopLevelStmt( element) )
85- case . expr:
86- self . diagnose ( . illegalTopLevelExpr( element) )
87- case . decl:
88- fatalError ( " unreachable " )
106+ switch node. item {
107+ case . decl( let node) :
108+ if let node = node. as ( MacroExpansionDeclSyntax . self) {
109+ return maybeTopLevelCodeDecl {
110+ switch self . maybeGenerateBuiltinPound ( freestandingMacroExpansion: node) {
111+ case . generated( let generated) :
112+ return generated
113+ case . ignored:
114+ /// If it is actually a macro expansion decl, it should use the parent DC.
115+ return self . withDeclContext ( parentDC) {
116+ return . decl( self . generate ( macroExpansionDecl: node) . asDecl)
117+ }
89118 }
90119 }
120+ }
121+ // Regular 'decl' nodes never be a stmt or expr. No top-level code treatment.
122+ return self . generate ( decl: node) . map { . decl( $0) }
123+
124+ case . expr( let node) :
125+ return maybeTopLevelCodeDecl {
126+ if let node = node. as ( MacroExpansionExprSyntax . self) {
127+ switch self . maybeGenerateBuiltinPound ( freestandingMacroExpansion: node) {
128+ case . generated( let generated) :
129+ return generated
130+ case . ignored:
131+ // Let regular 'self.generate(expr:)' generate the macro expansions.
132+ break
133+ }
134+ }
135+ return . expr( self . generate ( expr: node) )
136+ }
91137
92- let bodyRange = self . generateImplicitBraceRange ( element)
93- let body = BridgedBraceStmt . createImplicit (
94- self . ctx,
95- lBraceLoc: bodyRange. start,
96- element: astNode,
97- rBraceLoc: bodyRange. end
98- )
99- topLevelDecl. setBody ( body: body)
100- return . decl( topLevelDecl. asDecl)
138+ case . stmt( let node) :
139+ return maybeTopLevelCodeDecl {
140+ return . stmt( self . generate ( stmt: node) )
101141 }
142+ }
143+ }
102144
103- // TODO: Set semicolon loc.
104- switch element. item {
105- case . decl( let node) :
106- if let d = self . generate ( decl: node) {
107- out. append ( . decl( d) )
145+ func generateTopLevel( codeBlockItemList node: CodeBlockItemListSyntax ) -> [ BridgedASTNode ] {
146+ var out = [ BridgedASTNode] ( )
147+ visitIfConfigElements (
148+ node,
149+ of: CodeBlockItemSyntax . self,
150+ split: Self . splitCodeBlockItemIfConfig
151+ ) { element in
152+ guard let item = self . generateTopLevel ( codeBlockItem: element) else {
153+ return
154+ }
155+ out. append ( item)
108156
109- // Hoist 'VarDecl' to the top-level .
110- withBridgedSwiftClosure { ptr in
111- let hoisted = ptr! . load ( as : BridgedDecl . self )
112- out . append ( . decl ( hoisted ) )
113- } call : { handle in
114- d . forEachDeclToHoist ( handle)
115- }
157+ // Hoist 'VarDecl' to the block .
158+ if item . kind == . decl {
159+ withBridgedSwiftClosure { ptr in
160+ let d = ptr! . load ( as : BridgedDecl . self )
161+ out . append ( . decl ( d ) )
162+ } call : { handle in
163+ item . castToDecl ( ) . forEachDeclToHoist ( handle )
116164 }
117- case . stmt( let node) :
118- out. append ( generateStmtOrExpr {
119- . stmt( self . generate ( stmt: node) )
120- } )
121- case . expr( let node) :
122- out. append ( generateStmtOrExpr {
123- . expr( self . generate ( expr: node) )
124- } )
125165 }
126166 }
127-
128167 return out
129168 }
130169}
0 commit comments