Skip to content

Add support for multiple designated types for an operator declaration. #19816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 42 additions & 48 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -6380,45 +6380,44 @@ class OperatorDecl : public Decl {

Identifier name;

Identifier DesignatedNominalTypeName;
SourceLoc DesignatedNominalTypeNameLoc;
NominalTypeDecl *DesignatedNominalType = nullptr;
ArrayRef<Identifier> Identifiers;
ArrayRef<SourceLoc> IdentifierLocs;
ArrayRef<NominalTypeDecl *> DesignatedNominalTypes;

public:
OperatorDecl(DeclKind kind, DeclContext *DC, SourceLoc OperatorLoc,
Identifier Name, SourceLoc NameLoc,
Identifier DesignatedNominalTypeName = Identifier(),
SourceLoc DesignatedNominalTypeNameLoc = SourceLoc())
ArrayRef<Identifier> Identifiers,
ArrayRef<SourceLoc> IdentifierLocs)
: Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), name(Name),
DesignatedNominalTypeName(DesignatedNominalTypeName),
DesignatedNominalTypeNameLoc(DesignatedNominalTypeNameLoc) {}
Identifiers(Identifiers), IdentifierLocs(IdentifierLocs) {}

OperatorDecl(DeclKind kind, DeclContext *DC, SourceLoc OperatorLoc,
Identifier Name, SourceLoc NameLoc,
NominalTypeDecl *DesignatedNominalType)
ArrayRef<NominalTypeDecl *> DesignatedNominalTypes)
: Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), name(Name),
DesignatedNominalType(DesignatedNominalType) {}
DesignatedNominalTypes(DesignatedNominalTypes) {}

SourceLoc getLoc() const { return NameLoc; }

SourceLoc getOperatorLoc() const { return OperatorLoc; }
SourceLoc getNameLoc() const { return NameLoc; }
Identifier getName() const { return name; }

Identifier getDesignatedNominalTypeName() const {
return DesignatedNominalTypeName;
ArrayRef<Identifier> getIdentifiers() const {
return Identifiers;
}

SourceLoc getDesignatedNominalTypeNameLoc() const {
return DesignatedNominalTypeNameLoc;
ArrayRef<SourceLoc> getIdentifierLocs() const {
return IdentifierLocs;
}

NominalTypeDecl *getDesignatedNominalType() const {
return DesignatedNominalType;
ArrayRef<NominalTypeDecl *> getDesignatedNominalTypes() const {
return DesignatedNominalTypes;
}

void setDesignatedNominalType(NominalTypeDecl *nominal) {
DesignatedNominalType = nominal;
void setDesignatedNominalTypes(ArrayRef<NominalTypeDecl *> nominalTypes) {
DesignatedNominalTypes = nominalTypes;
}

static bool classof(const Decl *D) {
Expand All @@ -6436,46 +6435,39 @@ class OperatorDecl : public Decl {
/// infix operator /+/ : AdditionPrecedence, Numeric
/// \endcode
class InfixOperatorDecl : public OperatorDecl {
SourceLoc ColonLoc, FirstIdentifierLoc, SecondIdentifierLoc;
Identifier FirstIdentifier, SecondIdentifier;
SourceLoc ColonLoc;
PrecedenceGroupDecl *PrecedenceGroup = nullptr;

public:
InfixOperatorDecl(DeclContext *DC, SourceLoc operatorLoc, Identifier name,
SourceLoc nameLoc, SourceLoc colonLoc,
Identifier firstIdentifier, SourceLoc firstIdentifierLoc,
Identifier secondIdentifier = Identifier(),
SourceLoc secondIdentifierLoc = SourceLoc())
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc),
ColonLoc(colonLoc), FirstIdentifierLoc(firstIdentifierLoc),
SecondIdentifierLoc(secondIdentifierLoc),
FirstIdentifier(firstIdentifier), SecondIdentifier(secondIdentifier) {}
ArrayRef<Identifier> identifiers,
ArrayRef<SourceLoc> identifierLocs)
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc,
identifiers, identifierLocs),
ColonLoc(colonLoc) {}

InfixOperatorDecl(DeclContext *DC, SourceLoc operatorLoc, Identifier name,
SourceLoc nameLoc, SourceLoc colonLoc,
PrecedenceGroupDecl *precedenceGroup,
NominalTypeDecl *designatedNominalType)
ArrayRef<NominalTypeDecl *> designatedNominalTypes)
: OperatorDecl(DeclKind::InfixOperator, DC, operatorLoc, name, nameLoc,
designatedNominalType),
designatedNominalTypes),
ColonLoc(colonLoc), PrecedenceGroup(precedenceGroup) {}

SourceLoc getEndLoc() const {
if (!SecondIdentifier.empty())
return SecondIdentifierLoc;
if (!FirstIdentifier.empty())
return FirstIdentifierLoc;
return getNameLoc();
auto identifierLocs = getIdentifierLocs();
if (identifierLocs.empty())
return getNameLoc();

return identifierLocs.back();
}

SourceRange getSourceRange() const {
return { getOperatorLoc(), getEndLoc() };
}

SourceLoc getColonLoc() const { return ColonLoc; }
SourceLoc getFirstIdentifierLoc() const { return FirstIdentifierLoc; }
SourceLoc getSecondIdentifierLoc() const { return SecondIdentifierLoc; }

Identifier getFirstIdentifier() const { return FirstIdentifier; }
Identifier getSecondIdentifier() const { return SecondIdentifier; }

PrecedenceGroupDecl *getPrecedenceGroup() const { return PrecedenceGroup; }
void setPrecedenceGroup(PrecedenceGroupDecl *PGD) {
Expand All @@ -6502,15 +6494,16 @@ class PrefixOperatorDecl : public OperatorDecl {
public:
PrefixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
SourceLoc NameLoc,
Identifier DesignatedNominalTypeName = Identifier(),
SourceLoc DesignatedNominalTypeNameLoc = SourceLoc())
ArrayRef<Identifier> Identifiers,
ArrayRef<SourceLoc> IdentifierLocs)
: OperatorDecl(DeclKind::PrefixOperator, DC, OperatorLoc, Name, NameLoc,
DesignatedNominalTypeName, DesignatedNominalTypeNameLoc) {}
Identifiers, IdentifierLocs) {}

PrefixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
SourceLoc NameLoc, NominalTypeDecl *DesignatedNominalType)
SourceLoc NameLoc,
ArrayRef<NominalTypeDecl *> designatedNominalTypes)
: OperatorDecl(DeclKind::PrefixOperator, DC, OperatorLoc, Name, NameLoc,
DesignatedNominalType) {}
designatedNominalTypes) {}

SourceRange getSourceRange() const {
return { getOperatorLoc(), getNameLoc() };
Expand All @@ -6536,15 +6529,16 @@ class PostfixOperatorDecl : public OperatorDecl {
public:
PostfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
SourceLoc NameLoc,
Identifier DesignatedNominalTypeName = Identifier(),
SourceLoc DesignatedNominalTypeNameLoc = SourceLoc())
ArrayRef<Identifier> Identifiers,
ArrayRef<SourceLoc> IdentifierLocs)
: OperatorDecl(DeclKind::PostfixOperator, DC, OperatorLoc, Name, NameLoc,
DesignatedNominalTypeName, DesignatedNominalTypeNameLoc) {}
Identifiers, IdentifierLocs) {}

PostfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, Identifier Name,
SourceLoc NameLoc, NominalTypeDecl *DesignatedNominalType)
SourceLoc NameLoc,
ArrayRef<NominalTypeDecl *> designatedNominalTypes)
: OperatorDecl(DeclKind::PostfixOperator, DC, OperatorLoc, Name, NameLoc,
DesignatedNominalType) {}
designatedNominalTypes) {}

SourceRange getSourceRange() const {
return { getOperatorLoc(), getNameLoc() };
Expand Down
5 changes: 4 additions & 1 deletion include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

//===--- DiagnosticsParse.def - Diagnostics Text ----------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
Expand Down Expand Up @@ -431,8 +432,10 @@ ERROR(deprecated_operator_body_use_group,PointsToFirstBadToken,
ERROR(operator_decl_no_fixity,none,
"operator must be declared as 'prefix', 'postfix', or 'infix'", ())

ERROR(operator_decl_trailing_comma,none,
ERROR(operator_decl_expected_type,none,
"expected designated type in operator declaration", ())
ERROR(operator_decl_trailing_comma,none,
"trailing comma in operator declaration", ())

// PrecedenceGroup
ERROR(precedencegroup_not_infix,none,
Expand Down
6 changes: 3 additions & 3 deletions include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t VERSION_MINOR = 453; // Last change: borrow always
const uint16_t VERSION_MINOR = 454; // Last change: multiple nominal types for operators

using DeclIDField = BCFixed<31>;

Expand Down Expand Up @@ -1099,7 +1099,7 @@ namespace decls_block {
Code, // ID field
IdentifierIDField, // name
DeclContextIDField, // context decl
DeclIDField // protocol
BCArray<DeclIDField> // designated types
>;

using PrefixOperatorLayout = UnaryOperatorLayout<PREFIX_OPERATOR_DECL>;
Expand All @@ -1110,7 +1110,7 @@ namespace decls_block {
IdentifierIDField, // name
DeclContextIDField,// context decl
DeclIDField, // precedence group
DeclIDField // protocol
BCArray<DeclIDField> // designated types
>;

using PrecedenceGroupLayout = BCRecordLayout<
Expand Down
43 changes: 28 additions & 15 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1169,30 +1169,43 @@ namespace {
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void printOperatorIdentifiers(OperatorDecl *OD) {
auto identifiers = OD->getIdentifiers();
for (auto index : indices(identifiers)) {
OS.indent(Indent + 2);
OS << "identifier #" << index << " " << identifiers[index];
if (index != identifiers.size() - 1)
OS << "\n";
}
}

void visitInfixOperatorDecl(InfixOperatorDecl *IOD) {
printCommon(IOD, "infix_operator_decl ");
OS << IOD->getName() << "\n";
OS.indent(Indent+2);
if (!IOD->getFirstIdentifier().empty())
OS << "first identifier " << IOD->getFirstIdentifier();
else
OS << "first identifier <null>";
if (!IOD->getSecondIdentifier().empty())
OS << "second identifier " << IOD->getSecondIdentifier();
else
OS << "second identifier <null>";
printCommon(IOD, "infix_operator_decl");
OS << " " << IOD->getName();
if (!IOD->getIdentifiers().empty()) {
OS << "\n";
printOperatorIdentifiers(IOD);
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitPrefixOperatorDecl(PrefixOperatorDecl *POD) {
printCommon(POD, "prefix_operator_decl ");
OS << POD->getName();
printCommon(POD, "prefix_operator_decl");
OS << " " << POD->getName();
if (!POD->getIdentifiers().empty()) {
OS << "\n";
printOperatorIdentifiers(POD);
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitPostfixOperatorDecl(PostfixOperatorDecl *POD) {
printCommon(POD, "postfix_operator_decl ");
OS << POD->getName();
printCommon(POD, "postfix_operator_decl");
OS << " " << POD->getName();
if (!POD->getIdentifiers().empty()) {
OS << "\n";
printOperatorIdentifiers(POD);
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

Expand Down
33 changes: 27 additions & 6 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2875,8 +2875,15 @@ void PrintAST::visitInfixOperatorDecl(InfixOperatorDecl *decl) {
});
if (auto *group = decl->getPrecedenceGroup())
Printer << " : " << group->getName();
if (!decl->getSecondIdentifier().empty())
Printer << ", " << decl->getSecondIdentifier();
auto designatedNominalTypes = decl->getDesignatedNominalTypes();
auto first = true;
for (auto typeDecl : designatedNominalTypes) {
if (first && !decl->getPrecedenceGroup())
Printer << " : " << typeDecl->getName();
else
Printer << ", " << typeDecl->getName();
first = false;
}
}

void PrintAST::visitPrecedenceGroupDecl(PrecedenceGroupDecl *decl) {
Expand Down Expand Up @@ -2949,8 +2956,15 @@ void PrintAST::visitPrefixOperatorDecl(PrefixOperatorDecl *decl) {
[&]{
Printer.printName(decl->getName());
});
if (!decl->getDesignatedNominalTypeName().empty())
Printer << " : " << decl->getDesignatedNominalTypeName();
auto designatedNominalTypes = decl->getDesignatedNominalTypes();
auto first = true;
for (auto typeDecl : designatedNominalTypes) {
if (first)
Printer << " : " << typeDecl->getName();
else
Printer << ", " << typeDecl->getName();
first = false;
}
}

void PrintAST::visitPostfixOperatorDecl(PostfixOperatorDecl *decl) {
Expand All @@ -2960,8 +2974,15 @@ void PrintAST::visitPostfixOperatorDecl(PostfixOperatorDecl *decl) {
[&]{
Printer.printName(decl->getName());
});
if (!decl->getDesignatedNominalTypeName().empty())
Printer << " : " << decl->getDesignatedNominalTypeName();
auto designatedNominalTypes = decl->getDesignatedNominalTypes();
auto first = true;
for (auto typeDecl : designatedNominalTypes) {
if (first)
Printer << " : " << typeDecl->getName();
else
Printer << ", " << typeDecl->getName();
first = false;
}
}

void PrintAST::visitModuleDecl(ModuleDecl *decl) { }
Expand Down
Loading