Skip to content

Commit a3f1e2a

Browse files
committed
Make sure we're only parsing subscript and deinit as keywords within attributes
1 parent 3fc4474 commit a3f1e2a

File tree

5 files changed

+152
-25
lines changed

5 files changed

+152
-25
lines changed

Sources/SwiftParser/Attributes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ extension Parser {
376376
trailingComma: roleTrailingComma,
377377
arena: self.arena
378378
)
379-
let additionalArgs = self.parseArgumentListElements(pattern: .none, flavor: .attributeArgument)
379+
let additionalArgs = self.parseArgumentListElements(pattern: .none, flavor: .attributeArguments)
380380
return [roleElement] + additionalArgs
381381
}
382382
}

Sources/SwiftParser/Expressions.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ extension Parser {
7979
/// We don't allow allow newlines here.
8080
case poundIfDirective
8181

82-
/// Parsing an attribute argument, which can contain declaration references
83-
/// like `subscript` or `deinit`.
84-
case attributeArgument
82+
/// Parsing an attribute's arguments, which can contain declaration
83+
/// references like `subscript` or `deinit`.
84+
case attributeArguments
8585
}
8686

8787
enum PatternContext {
@@ -1245,7 +1245,7 @@ extension Parser {
12451245
var options: DeclNameOptions = .compoundNames
12461246
switch flavor {
12471247
case .basic, .poundIfDirective, .stmtCondition: break
1248-
case .attributeArgument: options.insert(.keywords)
1248+
case .attributeArguments: options.insert(.keywordsUsingSpecialNames)
12491249
}
12501250

12511251
let declName = self.parseDeclReferenceExpr(options)
@@ -2565,7 +2565,7 @@ private extension Parser.ExprFlavor {
25652565
var callArgumentFlavor: Parser.ExprFlavor {
25662566
switch self {
25672567
case .basic, .poundIfDirective, .stmtCondition: return .basic
2568-
case .attributeArgument: return .attributeArgument
2568+
case .attributeArguments: return .attributeArguments
25692569
}
25702570
}
25712571
}

Sources/SwiftParser/Names.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ extension Parser {
7171
} else if flags.contains(.operators), let (_, _) = self.at(anyIn: Operator.self) {
7272
base = self.consumeAnyToken(remapping: .binaryOperator)
7373
} else if flags.contains(.keywordsUsingSpecialNames),
74-
let special = self.consume(if: .keyword(.`deinit`), .keyword(.`subscript`)) {
74+
let special = self.consume(if: .keyword(.`deinit`), .keyword(.`subscript`))
75+
{
7576
base = special
7677
} else if flags.contains(.keywords) && self.currentToken.isLexerClassifiedKeyword {
7778
base = self.consumeAnyToken(remapping: .identifier)

Tests/SwiftParserTest/AttributeTests.swift

Lines changed: 128 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -692,72 +692,182 @@ final class AttributeTests: ParserTestCase {
692692
func testMacroRoleNames() {
693693
assertParse(
694694
"""
695-
@attached(member, names: named(deinit))
695+
@attached(member, names: named(1️⃣deinit))
696696
macro m()
697-
"""
697+
""",
698+
substructure: DeclReferenceExprSyntax(baseName: .keyword(.`deinit`)),
699+
substructureAfterMarker: "1️⃣"
698700
)
699701

700702
assertParse(
701703
"""
702-
@attached(member, names: named(init))
704+
@attached(member, names: named(1️⃣init))
703705
macro m()
704-
"""
706+
""",
707+
substructure: DeclReferenceExprSyntax(baseName: .keyword(.`init`)),
708+
substructureAfterMarker: "1️⃣"
705709
)
706710

707711
assertParse(
708712
"""
709-
@attached(member, names: named(init(a:b:)))
713+
@attached(member, names: named(1️⃣init(a:b:)))
710714
macro m()
711-
"""
715+
""",
716+
substructure: DeclReferenceExprSyntax(
717+
baseName: .keyword(.`init`),
718+
argumentNames: DeclNameArgumentsSyntax(
719+
arguments: [
720+
DeclNameArgumentSyntax(name: .identifier("a")),
721+
DeclNameArgumentSyntax(name: .identifier("b")),
722+
]
723+
)
724+
),
725+
substructureAfterMarker: "1️⃣"
712726
)
713727

714728
assertParse(
715729
"""
716-
@attached(member, names: named(subscript))
730+
@attached(member, names: named(1️⃣subscript))
717731
macro m()
718-
"""
732+
""",
733+
substructure: DeclReferenceExprSyntax(baseName: .keyword(.`subscript`)),
734+
substructureAfterMarker: "1️⃣"
719735
)
720736

721737
assertParse(
722738
"""
723-
@attached(declaration, names: named(subscript(a:b:)))
739+
@attached(declaration, names: named(1️⃣subscript(a:b:)))
724740
macro m()
725-
"""
741+
""",
742+
substructure: DeclReferenceExprSyntax(
743+
baseName: .keyword(.`subscript`),
744+
argumentNames: DeclNameArgumentsSyntax(
745+
arguments: [
746+
DeclNameArgumentSyntax(name: .identifier("a")),
747+
DeclNameArgumentSyntax(name: .identifier("b")),
748+
]
749+
)
750+
),
751+
substructureAfterMarker: "1️⃣"
726752
)
727753

728754
assertParse(
729755
"""
730-
@freestanding(declaration, names: named(deinit))
756+
@freestanding(declaration, names: named(1️⃣deinit))
731757
macro m()
732-
"""
758+
""",
759+
substructure: DeclReferenceExprSyntax(baseName: .keyword(.`deinit`)),
760+
substructureAfterMarker: "1️⃣"
733761
)
734762

735763
assertParse(
736764
"""
737-
@freestanding(declaration, names: named(init))
765+
@freestanding(declaration, names: named(1️⃣init))
738766
macro m()
739-
"""
767+
""",
768+
substructure: DeclReferenceExprSyntax(baseName: .keyword(.`init`)),
769+
substructureAfterMarker: "1️⃣"
740770
)
741771

742772
assertParse(
743773
"""
744-
@freestanding(declaration, names: named(init(a:b:)))
774+
@freestanding(declaration, names: named(1️⃣init(a:b:)))
745775
macro m()
746-
"""
776+
""",
777+
substructure: DeclReferenceExprSyntax(
778+
baseName: .keyword(.`init`),
779+
argumentNames: DeclNameArgumentsSyntax(
780+
arguments: [
781+
DeclNameArgumentSyntax(name: .identifier("a")),
782+
DeclNameArgumentSyntax(name: .identifier("b")),
783+
]
784+
)
785+
),
786+
substructureAfterMarker: "1️⃣"
747787
)
748788

749789
assertParse(
750790
"""
751-
@freestanding(member, names: named(subscript))
791+
@freestanding(member, names: named(1️⃣subscript))
752792
macro m()
793+
""",
794+
substructure: DeclReferenceExprSyntax(baseName: .keyword(.`subscript`)),
795+
substructureAfterMarker: "1️⃣"
796+
)
797+
798+
assertParse(
753799
"""
800+
@freestanding(member, names: named(1️⃣subscript(a:b:)))
801+
macro m()
802+
""",
803+
substructure: DeclReferenceExprSyntax(
804+
baseName: .keyword(.`subscript`),
805+
argumentNames: DeclNameArgumentsSyntax(
806+
arguments: [
807+
DeclNameArgumentSyntax(name: .identifier("a")),
808+
DeclNameArgumentSyntax(name: .identifier("b")),
809+
]
810+
)
811+
),
812+
substructureAfterMarker: "1️⃣"
754813
)
755814

756815
assertParse(
757816
"""
758-
@freestanding(member, names: named(subscript(a:b:)))
817+
@attached(member, names: named(1️⃣`class`))
759818
macro m()
819+
""",
820+
substructure: DeclReferenceExprSyntax(baseName: .identifier("`class`")),
821+
substructureAfterMarker: "1️⃣"
822+
)
823+
824+
assertParse(
760825
"""
826+
@attached4️⃣(member, names: named(1️⃣class2️⃣))
827+
macro m()3️⃣
828+
""",
829+
diagnostics: [
830+
DiagnosticSpec(
831+
locationMarker: "1️⃣",
832+
message: "expected value and ')' to end function call",
833+
fixIts: ["insert value and ')'"]
834+
),
835+
DiagnosticSpec(
836+
locationMarker: "1️⃣",
837+
message: "expected ')' to end attribute",
838+
notes: [
839+
NoteSpec(
840+
locationMarker: "4️⃣",
841+
message: "to match this opening '('"
842+
)
843+
],
844+
fixIts: ["insert ')'"]
845+
),
846+
DiagnosticSpec(
847+
locationMarker: "2️⃣",
848+
message: "expected identifier in class",
849+
fixIts: ["insert identifier"]
850+
),
851+
DiagnosticSpec(
852+
locationMarker: "2️⃣",
853+
message: "expected '{' in class",
854+
fixIts: ["insert '{'"]
855+
),
856+
DiagnosticSpec(
857+
locationMarker: "2️⃣",
858+
message: "unexpected code '))' before macro"
859+
),
860+
DiagnosticSpec(
861+
locationMarker: "3️⃣",
862+
message: "expected '}' to end class",
863+
fixIts: ["insert '}'"]
864+
),
865+
],
866+
fixedSource: """
867+
@attached(member, names: named(<#expression#>)) class <#identifier#> {))
868+
macro m()
869+
}
870+
"""
761871
)
762872
}
763873

Tests/SwiftParserTest/ExpressionTests.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,5 +3005,21 @@ final class StatementExpressionTests: ParserTestCase {
30053005
""",
30063006
substructure: DeclReferenceExprSyntax(baseName: .identifier("subscript"))
30073007
)
3008+
3009+
assertParse(
3010+
"""
3011+
x.1️⃣deinit
3012+
""",
3013+
substructure: DeclReferenceExprSyntax(baseName: .identifier("deinit")),
3014+
substructureAfterMarker: "1️⃣"
3015+
)
3016+
3017+
assertParse(
3018+
"""
3019+
x.1️⃣subscript
3020+
""",
3021+
substructure: DeclReferenceExprSyntax(baseName: .identifier("subscript")),
3022+
substructureAfterMarker: "1️⃣"
3023+
)
30083024
}
30093025
}

0 commit comments

Comments
 (0)