Skip to content

Commit 7930583

Browse files
committed
Work around module names sneaking in places they shouldn't (WIP)
1 parent 36fdfa5 commit 7930583

File tree

2 files changed

+62
-6
lines changed

2 files changed

+62
-6
lines changed

Sources/TestingMacros/Support/ConditionArgumentParsing.swift

+61-5
Original file line numberDiff line numberDiff line change
@@ -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.
559570
func 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 {

Tests/TestingTests/Support/CErrorTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct CErrorTests {
1717
func errorDescription(errorCode: CInt) {
1818
let description = String(describing: CError(rawValue: errorCode))
1919
#expect(!description.isEmpty)
20-
#expect(strerror(errorCode) == description)
20+
#expect(Testing.strerror(errorCode) == description)
2121
}
2222
}
2323

0 commit comments

Comments
 (0)