@@ -111,6 +111,11 @@ private final class _ContextInserter<C, M>: SyntaxRewriter where C: MacroExpansi
111111 /// The nodes in this array are the _original_ nodes, not the rewritten nodes.
112112 var rewrittenNodes = Set < Syntax > ( )
113113
114+ /// The set of expanded tokens (primarily from instances of
115+ /// `DeclReferenceExprSyntax`) that may represent module names instead of type
116+ /// or variable names.
117+ var possibleModuleNames = Set < TokenSyntax > ( )
118+
114119 /// Any postflight code the caller should insert into the closure containing
115120 /// the rewritten syntax tree.
116121 var teardownItems = [ CodeBlockItemSyntax] ( )
@@ -261,6 +266,7 @@ private final class _ContextInserter<C, M>: SyntaxRewriter where C: MacroExpansi
261266 ExprSyntax ( node) == memberAccessExpr. base,
262267 let functionCallExpr = memberAccessExpr. parent? . as ( FunctionCallExprSyntax . self) ,
263268 ExprSyntax ( memberAccessExpr) == functionCallExpr. calledExpression {
269+ possibleModuleNames. insert ( node. baseName)
264270 return _rewrite (
265271 MemberAccessExprSyntax (
266272 base: node. trimmed,
@@ -556,19 +562,69 @@ private final class _ContextInserter<C, M>: SyntaxRewriter where C: MacroExpansi
556562/// the nodes within `node` (possibly including `node` itself) that were
557563/// rewritten, and a code block containing code that should be inserted into
558564/// the lexical scope of `node` _before_ its rewritten equivalent.
565+ ///
566+ /// The resulting copy of `node` may not be of the same type as `node`. In
567+ /// particular, it may not be an expression. Calling code should not assume its
568+ /// type beyond conformance to `Syntax` and should check its type with `is()` or
569+ /// `as()` before operating over it.
559570func insertCalls(
560571 toExpressionContextNamed expressionContextName: TokenSyntax ,
561- into node: some SyntaxProtocol ,
572+ into node: some ExprSyntaxProtocol ,
562573 for macro: some FreestandingMacroExpansionSyntax ,
563574 rootedAt effectiveRootNode: some SyntaxProtocol ,
564575 in context: some MacroExpansionContext
565576) -> ( Syntax , rewrittenNodes: Set < Syntax > , prefixCodeBlockItems: CodeBlockItemListSyntax ) {
566- if let node = node. as ( ExprSyntax . self) {
567- _diagnoseTrivialBooleanValue ( from: node, for: macro, in: context)
568- }
577+ _diagnoseTrivialBooleanValue ( from: ExprSyntax ( node) , for: macro, in: context)
569578
570579 let contextInserter = _ContextInserter ( in: context, for: macro, rootedAt: Syntax ( effectiveRootNode) , expressionContextName: expressionContextName)
571- let result = contextInserter. rewrite ( node)
580+
581+ var result = contextInserter. rewrite ( ExprSyntax ( node) )
582+ if !contextInserter. possibleModuleNames. isEmpty {
583+ let canImportNameExpr = DeclReferenceExprSyntax ( baseName: . identifier( " canImport " ) )
584+ let canImportExprs = contextInserter. possibleModuleNames. map { moduleName in
585+ FunctionCallExprSyntax ( calledExpression: canImportNameExpr) {
586+ LabeledExprSyntax ( expression: DeclReferenceExprSyntax ( baseName: moduleName. trimmed) )
587+ }
588+ }
589+ // FIXME: do better
590+ let anyCanImportExpr : ExprSyntax = """
591+ \(
592+ raw: canImportExprs
593+ . map ( \. description)
594+ . joined ( separator: " || " )
595+ )
596+ """
597+
598+ guard let resultExpr = result. as ( ExprSyntax . self) else {
599+ fatalError ( " Result was of kind \( result. kind) , expected some expression " )
600+ }
601+
602+ result = Syntax (
603+ IfConfigDeclSyntax (
604+ clauses: IfConfigClauseListSyntax {
605+ IfConfigClauseSyntax (
606+ poundKeyword: . poundIfKeyword( ) ,
607+ condition: anyCanImportExpr,
608+ elements: . statements(
609+ CodeBlockItemListSyntax {
610+ CodeBlockItemSyntax ( item: CodeBlockItemSyntax . Item ( node) )
611+ }
612+ )
613+ )
614+ IfConfigClauseSyntax (
615+ poundKeyword: . poundElseKeyword( ) ,
616+ condition: anyCanImportExpr,
617+ elements: . statements(
618+ CodeBlockItemListSyntax {
619+ CodeBlockItemSyntax ( item: CodeBlockItemSyntax . Item ( resultExpr) )
620+ }
621+ )
622+ )
623+ }
624+ )
625+ )
626+ }
627+
572628 let rewrittenNodes = contextInserter. rewrittenNodes
573629
574630 let prefixCodeBlockItems = CodeBlockItemListSyntax {
0 commit comments