[Parse] Add fix-its for empty Swift 2 operator decl braces. (#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
This commit is contained in:
Jordan Rose
2016-08-15 14:43:09 -07:00
committed by GitHub
parent 83f2eb0a42
commit 3d005f3ad9
6 changed files with 48 additions and 13 deletions

View File

@@ -381,6 +381,9 @@ ERROR(identifier_when_expecting_operator,PointsToFirstBadToken,
WARNING(deprecated_operator_body,PointsToFirstBadToken,
"operator should no longer be declared with body", ())
WARNING(deprecated_operator_body_use_group,PointsToFirstBadToken,
"operator should no longer be declared with body; "
"use a precedence group instead", ())
ERROR(operator_decl_no_fixity,none,
"operator must be declared as 'prefix', 'postfix', or 'infix'", ())

View File

@@ -647,7 +647,8 @@ private:
Info.ID == diag::any_as_anyobject_fixit.ID ||
Info.ID == diag::deprecated_protocol_composition.ID ||
Info.ID == diag::deprecated_protocol_composition_single.ID ||
Info.ID == diag::deprecated_any_composition.ID)
Info.ID == diag::deprecated_any_composition.ID ||
Info.ID == diag::deprecated_operator_body.ID)
return true;
return false;

View File

@@ -5586,9 +5586,15 @@ Parser::parseDeclOperator(ParseDeclOptions Flags, DeclAttributes &Attributes) {
ParserResult<OperatorDecl>
Parser::parseDeclPrefixOperator(SourceLoc OperatorLoc, Identifier Name,
SourceLoc NameLoc, DeclAttributes &Attributes) {
SourceLoc LBraceLoc;
if (consumeIf(tok::l_brace, LBraceLoc)) {
diagnose(LBraceLoc, diag::deprecated_operator_body);
SourceLoc lBraceLoc;
if (consumeIf(tok::l_brace, lBraceLoc)) {
auto Diag = diagnose(lBraceLoc, diag::deprecated_operator_body);
if (Tok.is(tok::r_brace)) {
SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken(SourceMgr,
NameLoc);
SourceLoc rBraceEnd = Lexer::getLocForEndOfToken(SourceMgr, Tok.getLoc());
Diag.fixItRemoveChars(lastGoodLocEnd, rBraceEnd);
}
skipUntilDeclRBrace();
(void) consumeIf(tok::r_brace);
@@ -5604,9 +5610,15 @@ ParserResult<OperatorDecl>
Parser::parseDeclPostfixOperator(SourceLoc OperatorLoc,
Identifier Name, SourceLoc NameLoc,
DeclAttributes &Attributes) {
SourceLoc lbraceLoc;
if (consumeIf(tok::l_brace, lbraceLoc)) {
diagnose(lbraceLoc, diag::deprecated_operator_body);
SourceLoc lBraceLoc;
if (consumeIf(tok::l_brace, lBraceLoc)) {
auto Diag = diagnose(lBraceLoc, diag::deprecated_operator_body);
if (Tok.is(tok::r_brace)) {
SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken(SourceMgr,
NameLoc);
SourceLoc rBraceEnd = Lexer::getLocForEndOfToken(SourceMgr, Tok.getLoc());
Diag.fixItRemoveChars(lastGoodLocEnd, rBraceEnd);
}
skipUntilDeclRBrace();
(void) consumeIf(tok::r_brace);
@@ -5631,9 +5643,20 @@ Parser::parseDeclInfixOperator(SourceLoc operatorLoc, Identifier name,
}
}
SourceLoc lbraceLoc;
if (consumeIf(tok::l_brace, lbraceLoc)) {
diagnose(lbraceLoc, diag::deprecated_operator_body);
SourceLoc lBraceLoc;
if (consumeIf(tok::l_brace, lBraceLoc)) {
if (Tok.is(tok::r_brace)) {
SourceLoc lastGoodLoc = precedenceGroupNameLoc;
if (lastGoodLoc.isInvalid())
lastGoodLoc = nameLoc;
SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken(SourceMgr,
lastGoodLoc);
SourceLoc rBraceEnd = Lexer::getLocForEndOfToken(SourceMgr, Tok.getLoc());
diagnose(lBraceLoc, diag::deprecated_operator_body)
.fixItRemoveChars(lastGoodLocEnd, rBraceEnd);
} else {
diagnose(lBraceLoc, diag::deprecated_operator_body_use_group);
}
skipUntilDeclRBrace();
(void) consumeIf(tok::r_brace);

View File

@@ -259,3 +259,5 @@ func testProtocolCompositionSyntax() {
func disable_unnamed_param_reorder(p: Int, _: String) {}
disable_unnamed_param_reorder(0, "") // no change.
prefix operator ***** {}

View File

@@ -262,3 +262,5 @@ func testProtocolCompositionSyntax() {
func disable_unnamed_param_reorder(p: Int, _: String) {}
disable_unnamed_param_reorder(0, "") // no change.
prefix operator *****

View File

@@ -1,8 +1,12 @@
// RUN: %target-parse-verify-swift
prefix operator +++ {} // expected-warning {{operator should no longer be declared with body}}
postfix operator +++ {} // expected-warning {{operator should no longer be declared with body}}
infix operator +++ {} // expected-warning {{operator should no longer be declared with body}}
prefix operator +++ {} // expected-warning {{operator should no longer be declared with body}} {{20-23=}}
postfix operator +++ {} // expected-warning {{operator should no longer be declared with body}} {{21-24=}}
infix operator +++ {} // expected-warning {{operator should no longer be declared with body}} {{19-22=}}
infix operator +++* { // expected-warning {{operator should no longer be declared with body; use a precedence group instead}} {{none}}
associativity right
}
infix operator +++** : A { } // expected-warning {{operator should no longer be declared with body}} {{25-29=}}
prefix operator // expected-error {{expected operator name in operator declaration}}