Skip to content

Commit afad9d9

Browse files
committed
[Parse] Add fix-its for empty Swift 2 operator decl braces. (swiftlang#4309)
And improve the error message for non-empty braces; if we're going to ignore the contents, we should at least point you in the right direction for Swift 3. rdar://problem/27576922 (cherry picked from commit 3d005f3)
1 parent e9fe560 commit afad9d9

File tree

6 files changed

+48
-13
lines changed

6 files changed

+48
-13
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,9 @@ ERROR(identifier_when_expecting_operator,PointsToFirstBadToken,
381381

382382
WARNING(deprecated_operator_body,PointsToFirstBadToken,
383383
"operator should no longer be declared with body", ())
384+
WARNING(deprecated_operator_body_use_group,PointsToFirstBadToken,
385+
"operator should no longer be declared with body; "
386+
"use a precedence group instead", ())
384387
ERROR(operator_decl_no_fixity,none,
385388
"operator must be declared as 'prefix', 'postfix', or 'infix'", ())
386389

lib/FrontendTool/FrontendTool.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,8 @@ class JSONFixitWriter : public DiagnosticConsumer {
647647
Info.ID == diag::any_as_anyobject_fixit.ID ||
648648
Info.ID == diag::deprecated_protocol_composition.ID ||
649649
Info.ID == diag::deprecated_protocol_composition_single.ID ||
650-
Info.ID == diag::deprecated_any_composition.ID)
650+
Info.ID == diag::deprecated_any_composition.ID ||
651+
Info.ID == diag::deprecated_operator_body.ID)
651652
return true;
652653

653654
return false;

lib/Parse/ParseDecl.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5586,9 +5586,15 @@ Parser::parseDeclOperator(ParseDeclOptions Flags, DeclAttributes &Attributes) {
55865586
ParserResult<OperatorDecl>
55875587
Parser::parseDeclPrefixOperator(SourceLoc OperatorLoc, Identifier Name,
55885588
SourceLoc NameLoc, DeclAttributes &Attributes) {
5589-
SourceLoc LBraceLoc;
5590-
if (consumeIf(tok::l_brace, LBraceLoc)) {
5591-
diagnose(LBraceLoc, diag::deprecated_operator_body);
5589+
SourceLoc lBraceLoc;
5590+
if (consumeIf(tok::l_brace, lBraceLoc)) {
5591+
auto Diag = diagnose(lBraceLoc, diag::deprecated_operator_body);
5592+
if (Tok.is(tok::r_brace)) {
5593+
SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken(SourceMgr,
5594+
NameLoc);
5595+
SourceLoc rBraceEnd = Lexer::getLocForEndOfToken(SourceMgr, Tok.getLoc());
5596+
Diag.fixItRemoveChars(lastGoodLocEnd, rBraceEnd);
5597+
}
55925598

55935599
skipUntilDeclRBrace();
55945600
(void) consumeIf(tok::r_brace);
@@ -5604,9 +5610,15 @@ ParserResult<OperatorDecl>
56045610
Parser::parseDeclPostfixOperator(SourceLoc OperatorLoc,
56055611
Identifier Name, SourceLoc NameLoc,
56065612
DeclAttributes &Attributes) {
5607-
SourceLoc lbraceLoc;
5608-
if (consumeIf(tok::l_brace, lbraceLoc)) {
5609-
diagnose(lbraceLoc, diag::deprecated_operator_body);
5613+
SourceLoc lBraceLoc;
5614+
if (consumeIf(tok::l_brace, lBraceLoc)) {
5615+
auto Diag = diagnose(lBraceLoc, diag::deprecated_operator_body);
5616+
if (Tok.is(tok::r_brace)) {
5617+
SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken(SourceMgr,
5618+
NameLoc);
5619+
SourceLoc rBraceEnd = Lexer::getLocForEndOfToken(SourceMgr, Tok.getLoc());
5620+
Diag.fixItRemoveChars(lastGoodLocEnd, rBraceEnd);
5621+
}
56105622

56115623
skipUntilDeclRBrace();
56125624
(void) consumeIf(tok::r_brace);
@@ -5631,9 +5643,20 @@ Parser::parseDeclInfixOperator(SourceLoc operatorLoc, Identifier name,
56315643
}
56325644
}
56335645

5634-
SourceLoc lbraceLoc;
5635-
if (consumeIf(tok::l_brace, lbraceLoc)) {
5636-
diagnose(lbraceLoc, diag::deprecated_operator_body);
5646+
SourceLoc lBraceLoc;
5647+
if (consumeIf(tok::l_brace, lBraceLoc)) {
5648+
if (Tok.is(tok::r_brace)) {
5649+
SourceLoc lastGoodLoc = precedenceGroupNameLoc;
5650+
if (lastGoodLoc.isInvalid())
5651+
lastGoodLoc = nameLoc;
5652+
SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken(SourceMgr,
5653+
lastGoodLoc);
5654+
SourceLoc rBraceEnd = Lexer::getLocForEndOfToken(SourceMgr, Tok.getLoc());
5655+
diagnose(lBraceLoc, diag::deprecated_operator_body)
5656+
.fixItRemoveChars(lastGoodLocEnd, rBraceEnd);
5657+
} else {
5658+
diagnose(lBraceLoc, diag::deprecated_operator_body_use_group);
5659+
}
56375660

56385661
skipUntilDeclRBrace();
56395662
(void) consumeIf(tok::r_brace);

test/FixCode/fixits-apply.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,5 @@ func testProtocolCompositionSyntax() {
259259

260260
func disable_unnamed_param_reorder(p: Int, _: String) {}
261261
disable_unnamed_param_reorder(0, "") // no change.
262+
263+
prefix operator ***** {}

test/FixCode/fixits-apply.swift.result

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,5 @@ func testProtocolCompositionSyntax() {
262262

263263
func disable_unnamed_param_reorder(p: Int, _: String) {}
264264
disable_unnamed_param_reorder(0, "") // no change.
265+
266+
prefix operator *****

test/Parse/operator_decl.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
// RUN: %target-parse-verify-swift
22

3-
prefix operator +++ {} // expected-warning {{operator should no longer be declared with body}}
4-
postfix operator +++ {} // expected-warning {{operator should no longer be declared with body}}
5-
infix operator +++ {} // expected-warning {{operator should no longer be declared with body}}
3+
prefix operator +++ {} // expected-warning {{operator should no longer be declared with body}} {{20-23=}}
4+
postfix operator +++ {} // expected-warning {{operator should no longer be declared with body}} {{21-24=}}
5+
infix operator +++ {} // expected-warning {{operator should no longer be declared with body}} {{19-22=}}
6+
infix operator +++* { // expected-warning {{operator should no longer be declared with body; use a precedence group instead}} {{none}}
7+
associativity right
8+
}
9+
infix operator +++** : A { } // expected-warning {{operator should no longer be declared with body}} {{25-29=}}
610

711
prefix operator // expected-error {{expected operator name in operator declaration}}
812

0 commit comments

Comments
 (0)