Skip to content

Commit cf641d8

Browse files
committed
Change how OperatorDeclSyntax is presented
Assign precedence to most of declaration modifiers Add diagnostic for missing fixity in operator declaration Make `unowned` parsing accept `RecoveryConsumptionHandle`
1 parent 239de6c commit cf641d8

23 files changed

+457
-342
lines changed

CodeGeneration/Sources/SyntaxSupport/AttributeKinds.swift

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -676,10 +676,57 @@ public let DECL_ATTR_KINDS: [Attribute] = [
676676
///
677677
/// If you're adding a new kind of attribute that is spelled with a leading
678678
/// '@' symbol, add an entry to the `DECL_ATTR_KINDS` array instead.
679-
public let DECL_MODIFIER_KINDS: [Attribute] = [
680-
// These are not really attributes or modifiers in the C++ AST and they are
681-
// serialized directly into the ASTs they are attached to rather than using
682-
// the generic attribute serialization infrastructure.
679+
680+
// These are not really attributes or modifiers in the C++ AST and they are
681+
// serialized directly into the ASTs they are attached to rather than using
682+
// the generic attribute serialization infrastructure.
683+
public let DECL_MODIFIER_KINDS: [Attribute] = CONTEXTUAL_DECL_MODIFIER_KINDS + NONCONTEXTUAL_DECL_MODIFIER_KINDS
684+
685+
// Modifiers that not exclusively used for declarations
686+
public let CONTEXTUAL_DECL_MODIFIER_KINDS: [Attribute] = [
687+
ContextualDeclAttribute(
688+
name: "weak",
689+
className: "ReferenceOwnership"
690+
),
691+
ContextualDeclAttributeAlias(
692+
name: "unowned",
693+
className: "ReferenceOwnership",
694+
swiftName: "unowned"
695+
),
696+
SimpleDeclAttribute(
697+
name: "rethrows",
698+
className: "Rethrows",
699+
swiftName: "`rethrows`"
700+
),
701+
ContextualSimpleDeclAttribute(
702+
name: "isolated",
703+
className: "Isolated"
704+
),
705+
ContextualSimpleDeclAttribute(
706+
name: "async",
707+
className: "Async"
708+
),
709+
SimpleDeclAttribute(
710+
name: "reasync",
711+
className: "Reasync",
712+
swiftName: "reasync"
713+
),
714+
ContextualSimpleDeclAttribute(
715+
name: "consuming",
716+
className: "Consuming"
717+
),
718+
ContextualSimpleDeclAttribute(
719+
name: "borrowing",
720+
className: "Borrowing"
721+
),
722+
ContextualSimpleDeclAttribute(
723+
name: "_const",
724+
className: "CompileTimeConst"
725+
),
726+
]
727+
728+
// Modifiers that exclusively used for declarations
729+
public let NONCONTEXTUAL_DECL_MODIFIER_KINDS: [Attribute] = [
683730
BuiltinDeclModifier(
684731
name: "static",
685732
swiftName: "`static`"
@@ -775,37 +822,10 @@ public let DECL_MODIFIER_KINDS: [Attribute] = [
775822
className: "SetterAccess",
776823
swiftName: "__setter_access"
777824
),
778-
ContextualDeclAttribute(
779-
name: "weak",
780-
className: "ReferenceOwnership"
781-
),
782-
ContextualDeclAttributeAlias(
783-
name: "unowned",
784-
className: "ReferenceOwnership",
785-
swiftName: "unowned"
786-
),
787-
SimpleDeclAttribute(
788-
name: "rethrows",
789-
className: "Rethrows",
790-
swiftName: "`rethrows`"
791-
),
792825
ContextualSimpleDeclAttribute(
793826
name: "indirect",
794827
className: "Indirect"
795828
),
796-
ContextualSimpleDeclAttribute(
797-
name: "isolated",
798-
className: "Isolated"
799-
),
800-
ContextualSimpleDeclAttribute(
801-
name: "async",
802-
className: "Async"
803-
),
804-
SimpleDeclAttribute(
805-
name: "reasync",
806-
className: "Reasync",
807-
swiftName: "reasync"
808-
),
809829
ContextualSimpleDeclAttribute(
810830
name: "nonisolated",
811831
className: "Nonisolated"
@@ -814,22 +834,10 @@ public let DECL_MODIFIER_KINDS: [Attribute] = [
814834
name: "distributed",
815835
className: "DistributedActor"
816836
),
817-
ContextualSimpleDeclAttribute(
818-
name: "_const",
819-
className: "CompileTimeConst"
820-
),
821837
ContextualSimpleDeclAttribute(
822838
name: "_local",
823839
className: "KnownToBeLocal"
824840
),
825-
ContextualSimpleDeclAttribute(
826-
name: "consuming",
827-
className: "Consuming"
828-
),
829-
ContextualSimpleDeclAttribute(
830-
name: "borrowing",
831-
className: "Borrowing"
832-
),
833841
]
834842

835843
public let DEPRECATED_MODIFIER_KINDS: [Attribute] = [

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,25 +1426,14 @@ public let DECL_NODES: [Node] = [
14261426
nameForDiagnostics: "operator declaration",
14271427
documentation: "A Swift `operator` declaration.",
14281428
traits: [
1429-
"IdentifiedDecl",
1430-
"WithAttributes",
1431-
"WithModifiers",
1429+
"IdentifiedDecl"
14321430
],
14331431
children: [
14341432
Child(
1435-
name: "Attributes",
1436-
kind: .collection(kind: .attributeList, collectionElementName: "Attribute"),
1437-
nameForDiagnostics: "attributes",
1438-
description: "The attributes applied to the 'operator' declaration.",
1439-
isOptional: true
1440-
),
1441-
Child(
1442-
name: "Modifiers",
1443-
kind: .collection(kind: .modifierList, collectionElementName: "Modifier"),
1444-
nameForDiagnostics: "modifiers",
1445-
description: "The declaration modifiers applied to the 'operator' declaration.",
1446-
isOptional: true,
1447-
classification: "Attribute"
1433+
name: "Fixity",
1434+
kind: .token(choices: [.keyword(text: "prefix"), .keyword(text: "postfix"), .keyword(text: "infix")]),
1435+
nameForDiagnostics: "fixity",
1436+
description: "The fixity applied to the 'operator' declaration."
14481437
),
14491438
Child(
14501439
name: "OperatorKeyword",

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparser/DeclarationModifierFile.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,14 @@ let declarationModifierFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
3838

3939
try VariableDeclSyntax("var spec: TokenSpec") {
4040
try SwitchExprSyntax("switch self") {
41-
for attribute in DECL_MODIFIER_KINDS {
41+
for attribute in NONCONTEXTUAL_DECL_MODIFIER_KINDS {
42+
SwitchCaseSyntax("case .\(raw: attribute.swiftName):") {
43+
StmtSyntax("return .keyword(.\(raw: attribute.swiftName))")
44+
}
45+
}
46+
for attribute in CONTEXTUAL_DECL_MODIFIER_KINDS {
4247
SwitchCaseSyntax("case .\(raw: attribute.swiftName):") {
43-
if attribute.swiftName.hasSuffix("Keyword") {
44-
StmtSyntax("return .\(raw: attribute.swiftName)")
45-
} else {
46-
StmtSyntax("return .keyword(.\(raw: attribute.swiftName))")
47-
}
48+
StmtSyntax("return TokenSpec(.\(raw: attribute.swiftName), recoveryPrecedence: .declKeyword)")
4849
}
4950
}
5051
}

Sources/SwiftIDEUtils/generated/SyntaxClassification.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ extension SyntaxClassification {
8787
return (.buildConfigId, false)
8888
case \MemberTypeIdentifierSyntax.name:
8989
return (.typeIdentifier, false)
90-
case \OperatorDeclSyntax.modifiers:
91-
return (.attribute, false)
9290
case \OperatorDeclSyntax.identifier:
9391
return (.operatorIdentifier, false)
9492
case \PrecedenceGroupAssociativitySyntax.associativityKeyword:

Sources/SwiftOperators/OperatorTable+Semantics.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,7 @@ extension Operator {
6868
/// TODO: This ignores all semantic errors.
6969
init(from syntax: OperatorDeclSyntax) {
7070
self.syntax = syntax
71-
72-
kind =
73-
syntax.modifiers?.compactMap {
74-
OperatorKind(rawValue: $0.name.text)
75-
}.first ?? .infix
71+
kind = OperatorKind(rawValue: syntax.fixity.text) ?? .infix
7672

7773
name = syntax.identifier.text
7874

Sources/SwiftOperators/SyntaxSynthesis.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ extension Operator {
2626
/// Synthesize a syntactic representation of this operator based on its
2727
/// semantic definition.
2828
public func synthesizedSyntax() -> OperatorDeclSyntax {
29-
let modifiers = ModifierListSyntax(
30-
[DeclModifierSyntax(name: .keyword(kind.keyword))]
31-
)
29+
let fixity = TokenSyntax.keyword(kind.keyword)
3230
let operatorKeyword = TokenSyntax.keyword(.operator, leadingTrivia: .space)
3331
let identifierSyntax =
3432
TokenSyntax.binaryOperator(name, leadingTrivia: .space)
@@ -41,7 +39,7 @@ extension Operator {
4139
}
4240

4341
return OperatorDeclSyntax(
44-
modifiers: modifiers,
42+
fixity: fixity,
4543
operatorKeyword: operatorKeyword,
4644
identifier: identifierSyntax,
4745
operatorPrecedenceAndTypes: precedenceGroupSyntax

Sources/SwiftParser/Declarations.swift

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,15 @@ extension TokenConsumer {
8989
return attrLookahead.consumeIfConfigOfAttributes()
9090
}
9191

92-
let declStartKeyword: DeclarationStart?
92+
let declStartKeyword: DeclarationKeyword?
9393
if allowRecovery {
9494
declStartKeyword =
9595
subparser.canRecoverTo(
96-
anyIn: DeclarationStart.self,
96+
anyIn: DeclarationKeyword.self,
9797
overrideRecoveryPrecedence: isAtTopLevel ? nil : .closingBrace
9898
)?.0
9999
} else {
100-
declStartKeyword = subparser.at(anyIn: DeclarationStart.self)?.0
100+
declStartKeyword = subparser.at(anyIn: DeclarationKeyword.self)?.0
101101
}
102102
switch declStartKeyword {
103103
case .actorKeyword:
@@ -233,7 +233,7 @@ extension Parser {
233233
// while recoverying to the declaration start.
234234
let recoveryPrecedence = inMemberDeclList ? TokenPrecedence.closingBrace : nil
235235

236-
switch self.canRecoverTo(anyIn: DeclarationStart.self, overrideRecoveryPrecedence: recoveryPrecedence) {
236+
switch self.canRecoverTo(anyIn: DeclarationKeyword.self, overrideRecoveryPrecedence: recoveryPrecedence) {
237237
case (.importKeyword, let handle)?:
238238
return RawDeclSyntax(self.parseImportDeclaration(attrs, handle))
239239
case (.classKeyword, let handle)?:
@@ -1694,11 +1694,69 @@ extension Parser {
16941694
/// postfix-operator-declaration → 'postfix' 'operator' operator
16951695
/// infix-operator-declaration → 'infix' 'operator' operator infix-operator-group?
16961696
/// infix-operator-group → ':' precedence-group-name
1697+
1698+
struct OperatorDeclIntroducer {
1699+
var unexpectedBeforeFixity: RawUnexpectedNodesSyntax?
1700+
var fixity: RawTokenSyntax
1701+
var unexpectedBeforeOperatorKeyword: RawUnexpectedNodesSyntax?
1702+
var operatorKeyword: RawTokenSyntax
1703+
}
1704+
1705+
mutating func parseOperatorDeclIntroducer(_ attrs: DeclAttributes, _ handle: RecoveryConsumptionHandle) -> OperatorDeclIntroducer {
1706+
func isFixity(_ modifier: RawDeclModifierSyntax) -> Bool {
1707+
switch modifier.name {
1708+
case .keyword(.prefix),
1709+
.keyword(.infix),
1710+
.keyword(.postfix):
1711+
return true
1712+
default:
1713+
return false
1714+
}
1715+
}
1716+
1717+
var unexpectedBeforeFixity = RawUnexpectedNodesSyntax(attrs.attributes?.elements ?? [], arena: self.arena)
1718+
1719+
var fixity: RawTokenSyntax?
1720+
var unexpectedAfterFixity: RawUnexpectedNodesSyntax?
1721+
1722+
if let modifiers = attrs.modifiers?.elements {
1723+
if let firstFixityIndex = modifiers.firstIndex(where: { isFixity($0) }) {
1724+
let fixityModifier = modifiers[firstFixityIndex]
1725+
fixity = fixityModifier.name
1726+
1727+
unexpectedBeforeFixity = RawUnexpectedNodesSyntax(combining: unexpectedBeforeFixity, RawUnexpectedNodesSyntax(Array(modifiers[0..<firstFixityIndex]), arena: self.arena), fixityModifier.unexpectedBeforeName, arena: self.arena)
1728+
1729+
unexpectedAfterFixity = RawUnexpectedNodesSyntax(
1730+
combining: fixityModifier.unexpectedBetweenNameAndDetail,
1731+
RawUnexpectedNodesSyntax([fixityModifier.detail], arena: self.arena),
1732+
fixityModifier.unexpectedAfterDetail,
1733+
RawUnexpectedNodesSyntax(Array(modifiers[modifiers.index(after: firstFixityIndex)...]), arena: self.arena),
1734+
arena: self.arena
1735+
)
1736+
1737+
} else {
1738+
unexpectedBeforeFixity = RawUnexpectedNodesSyntax(combining: unexpectedBeforeFixity, RawUnexpectedNodesSyntax(modifiers, arena: self.arena), arena: self.arena)
1739+
}
1740+
}
1741+
1742+
var (unexpectedBeforeOperatorKeyword, operatorKeyword) = self.expect(.keyword(.operator))
1743+
1744+
unexpectedBeforeOperatorKeyword = RawUnexpectedNodesSyntax(combining: unexpectedAfterFixity, unexpectedBeforeOperatorKeyword, arena: self.arena)
1745+
1746+
return OperatorDeclIntroducer(
1747+
unexpectedBeforeFixity: unexpectedBeforeFixity,
1748+
fixity: fixity ?? self.missingToken(.prefix),
1749+
unexpectedBeforeOperatorKeyword: unexpectedBeforeOperatorKeyword,
1750+
operatorKeyword: operatorKeyword
1751+
)
1752+
}
1753+
16971754
mutating func parseOperatorDeclaration(
16981755
_ attrs: DeclAttributes,
16991756
_ handle: RecoveryConsumptionHandle
17001757
) -> RawOperatorDeclSyntax {
1701-
let (unexpectedBeforeOperatorKeyword, operatorKeyword) = self.eat(handle)
1758+
let introducer = parseOperatorDeclIntroducer(attrs, handle)
1759+
17021760
let unexpectedBeforeName: RawUnexpectedNodesSyntax?
17031761
let name: RawTokenSyntax
17041762
switch self.canRecoverTo(anyIn: OperatorLike.self) {
@@ -1775,10 +1833,10 @@ extension Parser {
17751833
unexpectedAtEnd = nil
17761834
}
17771835
return RawOperatorDeclSyntax(
1778-
attributes: attrs.attributes,
1779-
modifiers: attrs.modifiers,
1780-
unexpectedBeforeOperatorKeyword,
1781-
operatorKeyword: operatorKeyword,
1836+
introducer.unexpectedBeforeFixity,
1837+
fixity: introducer.fixity,
1838+
introducer.unexpectedBeforeOperatorKeyword,
1839+
operatorKeyword: introducer.operatorKeyword,
17821840
unexpectedBeforeName,
17831841
identifier: name,
17841842
RawUnexpectedNodesSyntax(identifiersAfterOperatorName, arena: self.arena),

0 commit comments

Comments
 (0)