From cab738b8e58d85b2ac60f20e955196c97f5cbc73 Mon Sep 17 00:00:00 2001 From: Rintaro Ishizaki Date: Fri, 1 Aug 2025 16:57:53 -0700 Subject: [PATCH] [SwiftParser] Handle nested '#if' in attribute list correctly Parse the following '#if' directive as an attribute list for the func decl. ``` #if condition #if condition @attr #endif #endif func foo() ``` (cherry picked from commit 191392bd13f71f60e2030675a8948bc4800ba304) --- Sources/SwiftParser/Lookahead.swift | 4 ++- Tests/SwiftParserTest/DirectiveTests.swift | 36 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftParser/Lookahead.swift b/Sources/SwiftParser/Lookahead.swift index 9aa7afe8c4b..82ff8228b2d 100644 --- a/Sources/SwiftParser/Lookahead.swift +++ b/Sources/SwiftParser/Lookahead.swift @@ -254,7 +254,9 @@ extension Parser.Lookahead { didSeeAnyAttributes = true _ = self.consumeAttributeList() case .poundIf: - _ = self.consumeIfConfigOfAttributes() + if self.consumeIfConfigOfAttributes() { + didSeeAnyAttributes = true + } default: break ATTRIBUTE_LOOP } diff --git a/Tests/SwiftParserTest/DirectiveTests.swift b/Tests/SwiftParserTest/DirectiveTests.swift index d89d1431d1f..a42e72c1059 100644 --- a/Tests/SwiftParserTest/DirectiveTests.swift +++ b/Tests/SwiftParserTest/DirectiveTests.swift @@ -157,6 +157,42 @@ final class DirectiveTests: ParserTestCase { ) } + func testPoundIfNestedStructure() { + assertParse( + """ + #if true + #if true + @frozen + #endif + #endif + public struct S {} + """, + substructure: AttributeListSyntax([ + .ifConfigDecl( + IfConfigDeclSyntax(clauses: [ + IfConfigClauseSyntax( + poundKeyword: .poundIfToken(), + condition: ExprSyntax("true"), + elements: .attributes([ + .ifConfigDecl( + IfConfigDeclSyntax(clauses: [ + IfConfigClauseSyntax( + poundKeyword: .poundIfToken(), + condition: ExprSyntax("true"), + elements: .attributes([ + .attribute("@frozen") + ]) + ) + ]) + ) + ]) + ) + ]) + ) + ]) + ) + } + func testHasAttribute() { assertParse( """