Skip to content

Commit e252970

Browse files
committed
Change operator decl representation for designated type.
Update the representation to allow for multiple types to be specified for a single operator. No parsing, serialization, or deserialization support yet, so NFC.
1 parent 16ec978 commit e252970

File tree

2 files changed

+67
-49
lines changed

2 files changed

+67
-49
lines changed

include/swift/AST/Decl.h

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6380,18 +6380,17 @@ class OperatorDecl : public Decl {
63806380

63816381
Identifier name;
63826382

6383-
Identifier DesignatedNominalTypeName;
6384-
SourceLoc DesignatedNominalTypeNameLoc;
6383+
ArrayRef<Identifier> Identifiers;
6384+
ArrayRef<SourceLoc> IdentifierLocs;
63856385
NominalTypeDecl *DesignatedNominalType = nullptr;
63866386

63876387
public:
63886388
OperatorDecl(DeclKind kind, DeclContext *DC, SourceLoc OperatorLoc,
63896389
Identifier Name, SourceLoc NameLoc,
6390-
Identifier DesignatedNominalTypeName = Identifier(),
6391-
SourceLoc DesignatedNominalTypeNameLoc = SourceLoc())
6390+
ArrayRef<Identifier> Identifiers,
6391+
ArrayRef<SourceLoc> IdentifierLocs)
63926392
: Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), name(Name),
6393-
DesignatedNominalTypeName(DesignatedNominalTypeName),
6394-
DesignatedNominalTypeNameLoc(DesignatedNominalTypeNameLoc) {}
6393+
Identifiers(Identifiers), IdentifierLocs(IdentifierLocs) {}
63956394

63966395
OperatorDecl(DeclKind kind, DeclContext *DC, SourceLoc OperatorLoc,
63976396
Identifier Name, SourceLoc NameLoc,
@@ -6405,12 +6404,20 @@ class OperatorDecl : public Decl {
64056404
SourceLoc getNameLoc() const { return NameLoc; }
64066405
Identifier getName() const { return name; }
64076406

6407+
ArrayRef<Identifier> getIdentifiers() const {
6408+
return Identifiers;
6409+
}
6410+
6411+
ArrayRef<SourceLoc> getIdentifierLocs() const {
6412+
return IdentifierLocs;
6413+
}
6414+
64086415
Identifier getDesignatedNominalTypeName() const {
6409-
return DesignatedNominalTypeName;
6416+
return !Identifiers.empty() ? Identifiers[0] : Identifier();
64106417
}
64116418

64126419
SourceLoc getDesignatedNominalTypeNameLoc() const {
6413-
return DesignatedNominalTypeNameLoc;
6420+
return !IdentifierLocs.empty() ? IdentifierLocs[0] : SourceLoc();
64146421
}
64156422

64166423
NominalTypeDecl *getDesignatedNominalType() const {
@@ -6436,20 +6443,17 @@ class OperatorDecl : public Decl {
64366443
/// infix operator /+/ : AdditionPrecedence, Numeric
64376444
/// \endcode
64386445
class InfixOperatorDecl : public OperatorDecl {
6439-
SourceLoc ColonLoc, FirstIdentifierLoc, SecondIdentifierLoc;
6440-
Identifier FirstIdentifier, SecondIdentifier;
6446+
SourceLoc ColonLoc;
64416447
PrecedenceGroupDecl *PrecedenceGroup = nullptr;
64426448

64436449
public:
64446450
InfixOperatorDecl(DeclContext *DC, SourceLoc operatorLoc, Identifier name,
64456451
SourceLoc nameLoc, SourceLoc colonLoc,
6446-
Identifier firstIdentifier, SourceLoc firstIdentifierLoc,
6447-
Identifier secondIdentifier = Identifier(),
6448-
SourceLoc secondIdentifierLoc = SourceLoc())
6449-
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc),
6450-
ColonLoc(colonLoc), FirstIdentifierLoc(firstIdentifierLoc),
6451-
SecondIdentifierLoc(secondIdentifierLoc),
6452-
FirstIdentifier(firstIdentifier), SecondIdentifier(secondIdentifier) {}
6452+
ArrayRef<Identifier> identifiers,
6453+
ArrayRef<SourceLoc> identifierLocs)
6454+
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc,
6455+
identifiers, identifierLocs),
6456+
ColonLoc(colonLoc) {}
64536457

64546458
InfixOperatorDecl(DeclContext *DC, SourceLoc operatorLoc, Identifier name,
64556459
SourceLoc nameLoc, SourceLoc colonLoc,
@@ -6460,22 +6464,34 @@ class InfixOperatorDecl : public OperatorDecl {
64606464
ColonLoc(colonLoc), PrecedenceGroup(precedenceGroup) {}
64616465

64626466
SourceLoc getEndLoc() const {
6463-
if (!SecondIdentifier.empty())
6464-
return SecondIdentifierLoc;
6465-
if (!FirstIdentifier.empty())
6466-
return FirstIdentifierLoc;
6467+
if (!getSecondIdentifier().empty())
6468+
return getSecondIdentifierLoc();
6469+
if (!getFirstIdentifier().empty())
6470+
return getFirstIdentifierLoc();
64676471
return getNameLoc();
64686472
}
64696473
SourceRange getSourceRange() const {
64706474
return { getOperatorLoc(), getEndLoc() };
64716475
}
64726476

64736477
SourceLoc getColonLoc() const { return ColonLoc; }
6474-
SourceLoc getFirstIdentifierLoc() const { return FirstIdentifierLoc; }
6475-
SourceLoc getSecondIdentifierLoc() const { return SecondIdentifierLoc; }
6478+
SourceLoc getFirstIdentifierLoc() const {
6479+
auto identifierLocs = getIdentifierLocs();
6480+
return !identifierLocs.empty() ? identifierLocs[0] : SourceLoc();
6481+
}
6482+
SourceLoc getSecondIdentifierLoc() const {
6483+
auto identifierLocs = getIdentifierLocs();
6484+
return identifierLocs.size() > 1 ? identifierLocs[1] : SourceLoc();
6485+
}
64766486

6477-
Identifier getFirstIdentifier() const { return FirstIdentifier; }
6478-
Identifier getSecondIdentifier() const { return SecondIdentifier; }
6487+
Identifier getFirstIdentifier() const {
6488+
auto identifiers = getIdentifiers();
6489+
return !identifiers.empty() ? identifiers[0] : Identifier();
6490+
}
6491+
Identifier getSecondIdentifier() const {
6492+
auto identifiers = getIdentifiers();
6493+
return identifiers.size() > 1 ? identifiers[1] : Identifier();
6494+
}
64796495

64806496
PrecedenceGroupDecl *getPrecedenceGroup() const { return PrecedenceGroup; }
64816497
void setPrecedenceGroup(PrecedenceGroupDecl *PGD) {
@@ -6502,10 +6518,10 @@ class PrefixOperatorDecl : public OperatorDecl {
65026518
public:
65036519
PrefixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
65046520
SourceLoc NameLoc,
6505-
Identifier DesignatedNominalTypeName = Identifier(),
6506-
SourceLoc DesignatedNominalTypeNameLoc = SourceLoc())
6521+
ArrayRef<Identifier> Identifiers,
6522+
ArrayRef<SourceLoc> IdentifierLocs)
65076523
: OperatorDecl(DeclKind::PrefixOperator, DC, OperatorLoc, Name, NameLoc,
6508-
DesignatedNominalTypeName, DesignatedNominalTypeNameLoc) {}
6524+
Identifiers, IdentifierLocs) {}
65096525

65106526
PrefixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
65116527
SourceLoc NameLoc, NominalTypeDecl *DesignatedNominalType)
@@ -6536,10 +6552,10 @@ class PostfixOperatorDecl : public OperatorDecl {
65366552
public:
65376553
PostfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
65386554
SourceLoc NameLoc,
6539-
Identifier DesignatedNominalTypeName = Identifier(),
6540-
SourceLoc DesignatedNominalTypeNameLoc = SourceLoc())
6555+
ArrayRef<Identifier> Identifiers,
6556+
ArrayRef<SourceLoc> IdentifierLocs)
65416557
: OperatorDecl(DeclKind::PostfixOperator, DC, OperatorLoc, Name, NameLoc,
6542-
DesignatedNominalTypeName, DesignatedNominalTypeNameLoc) {}
6558+
Identifiers, IdentifierLocs) {}
65436559

65446560
PostfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
65456561
SourceLoc NameLoc, NominalTypeDecl *DesignatedNominalType)

lib/Parse/ParseDecl.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6496,40 +6496,39 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
64966496
// parse them both as identifiers here and sort it out in type
64976497
// checking.
64986498
SourceLoc colonLoc;
6499-
Identifier firstIdentifierName;
6500-
SourceLoc firstIdentifierNameLoc;
6501-
Identifier secondIdentifierName;
6502-
SourceLoc secondIdentifierNameLoc;
6499+
SmallVector<Identifier, 4> identifiers;
6500+
SmallVector<SourceLoc, 4> identifierLocs;
65036501
if (Tok.is(tok::colon)) {
6504-
SyntaxParsingContext GroupCtxt(SyntaxContext, SyntaxKind::InfixOperatorGroup);
6502+
SyntaxParsingContext GroupCtxt(SyntaxContext,
6503+
SyntaxKind::InfixOperatorGroup);
65056504
colonLoc = consumeToken();
65066505

65076506
if (Context.LangOpts.EnableOperatorDesignatedTypes) {
65086507
if (Tok.is(tok::identifier)) {
6509-
firstIdentifierName = Context.getIdentifier(Tok.getText());
6510-
firstIdentifierNameLoc = consumeToken(tok::identifier);
6508+
identifiers.push_back(Context.getIdentifier(Tok.getText()));
6509+
identifierLocs.push_back(consumeToken(tok::identifier));
65116510

65126511
if (consumeIf(tok::comma)) {
65136512
if (isPrefix || isPostfix)
65146513
diagnose(colonLoc, diag::precedencegroup_not_infix)
6515-
.fixItRemove({colonLoc, firstIdentifierNameLoc});
6514+
.fixItRemove({colonLoc, identifierLocs.back()});
65166515

65176516
if (Tok.is(tok::identifier)) {
6518-
secondIdentifierName = Context.getIdentifier(Tok.getText());
6519-
secondIdentifierNameLoc = consumeToken(tok::identifier);
6517+
identifiers.push_back(Context.getIdentifier(Tok.getText()));
6518+
identifierLocs.push_back(consumeToken(tok::identifier));
65206519
} else {
65216520
auto otherTokLoc = consumeToken();
65226521
diagnose(otherTokLoc, diag::operator_decl_trailing_comma);
65236522
}
65246523
}
65256524
}
65266525
} else if (Tok.is(tok::identifier)) {
6527-
firstIdentifierName = Context.getIdentifier(Tok.getText());
6528-
firstIdentifierNameLoc = consumeToken(tok::identifier);
6526+
identifiers.push_back(Context.getIdentifier(Tok.getText()));
6527+
identifierLocs.push_back(consumeToken(tok::identifier));
65296528

65306529
if (isPrefix || isPostfix) {
65316530
diagnose(colonLoc, diag::precedencegroup_not_infix)
6532-
.fixItRemove({colonLoc, firstIdentifierNameLoc});
6531+
.fixItRemove({colonLoc, identifierLocs.back()});
65336532
}
65346533
}
65356534
}
@@ -6542,7 +6541,8 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
65426541
} else {
65436542
auto Diag = diagnose(lBraceLoc, diag::deprecated_operator_body);
65446543
if (Tok.is(tok::r_brace)) {
6545-
SourceLoc lastGoodLoc = firstIdentifierNameLoc;
6544+
SourceLoc lastGoodLoc =
6545+
!identifierLocs.empty() ? identifierLocs.back() : SourceLoc();
65466546
if (lastGoodLoc.isInvalid())
65476547
lastGoodLoc = NameLoc;
65486548
SourceLoc lastGoodLocEnd = Lexer::getLocForEndOfToken(SourceMgr,
@@ -6560,16 +6560,18 @@ Parser::parseDeclOperatorImpl(SourceLoc OperatorLoc, Identifier Name,
65606560
if (Attributes.hasAttribute<PrefixAttr>())
65616561
res = new (Context)
65626562
PrefixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc,
6563-
firstIdentifierName, firstIdentifierNameLoc);
6563+
Context.AllocateCopy(identifiers),
6564+
Context.AllocateCopy(identifierLocs));
65646565
else if (Attributes.hasAttribute<PostfixAttr>())
65656566
res = new (Context)
65666567
PostfixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc,
6567-
firstIdentifierName, firstIdentifierNameLoc);
6568+
Context.AllocateCopy(identifiers),
6569+
Context.AllocateCopy(identifierLocs));
65686570
else
65696571
res = new (Context)
65706572
InfixOperatorDecl(CurDeclContext, OperatorLoc, Name, NameLoc, colonLoc,
6571-
firstIdentifierName, firstIdentifierNameLoc,
6572-
secondIdentifierName, secondIdentifierNameLoc);
6573+
Context.AllocateCopy(identifiers),
6574+
Context.AllocateCopy(identifierLocs));
65736575

65746576
diagnoseOperatorFixityAttributes(*this, Attributes, res);
65756577

0 commit comments

Comments
 (0)