Skip to content

Commit 578db55

Browse files
committed
[nfc] factor out logic to remove inherited entry
1 parent 2cbb637 commit 578db55

File tree

3 files changed

+73
-45
lines changed

3 files changed

+73
-45
lines changed

include/swift/AST/Decl.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,9 @@ class InheritedTypes {
15961596
size_t size() const { return Entries.size(); }
15971597
IntRange<size_t> const getIndices() { return indices(Entries); }
15981598

1599+
/// Returns the ASTContext associated with the wrapped declaration.
1600+
ASTContext &getASTContext() const;
1601+
15991602
/// Returns the `TypeRepr *` for the entry of the inheritance clause at the
16001603
/// given index.
16011604
TypeRepr *getTypeRepr(unsigned i) const { return Entries[i].getTypeRepr(); }
@@ -1615,6 +1618,10 @@ class InheritedTypes {
16151618
/// NOTE: The `Type` associated with the entry may not be resolved yet.
16161619
const InheritedEntry &getEntry(unsigned i) const { return Entries[i]; }
16171620

1621+
// Retrieve the location of the colon character introducing the inheritance
1622+
// clause.
1623+
SourceLoc getColonLoc() const;
1624+
16181625
/// Returns the source location of the beginning of the inheritance clause.
16191626
SourceLoc getStartLoc() const {
16201627
return getEntries().front().getSourceRange().Start;
@@ -1624,6 +1631,10 @@ class InheritedTypes {
16241631
SourceLoc getEndLoc() const {
16251632
return getEntries().back().getSourceRange().End;
16261633
}
1634+
1635+
/// Compute the SourceRange to be used when removing entry \c i from the
1636+
/// inheritance clause. Accounts for commas and colons as-needed.
1637+
SourceRange getRemovalRange(unsigned i) const;
16271638
};
16281639

16291640
/// ExtensionDecl - This represents a type extension containing methods

lib/AST/Decl.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,61 @@ InheritedTypes::InheritedTypes(const class Decl *decl) {
15851585
}
15861586
}
15871587

1588+
ASTContext &InheritedTypes::getASTContext() const {
1589+
if (auto typeDecl = Decl.dyn_cast<const TypeDecl *>()) {
1590+
return typeDecl->getASTContext();
1591+
} else {
1592+
return Decl.get<const ExtensionDecl *>()->getASTContext();
1593+
}
1594+
}
1595+
1596+
SourceLoc InheritedTypes::getColonLoc() const {
1597+
if (Entries.size() == 0)
1598+
return SourceLoc();
1599+
1600+
SourceLoc precedingTok;
1601+
if (auto typeDecl = Decl.dyn_cast<const TypeDecl *>()) {
1602+
precedingTok = typeDecl->getNameLoc();
1603+
} else {
1604+
auto *ext = Decl.get<const ExtensionDecl *>();
1605+
precedingTok = ext->getSourceRange().End;
1606+
}
1607+
1608+
auto &ctx = getASTContext();
1609+
return Lexer::getLocForEndOfToken(ctx.SourceMgr, precedingTok);
1610+
}
1611+
1612+
SourceRange InheritedTypes::getRemovalRange(unsigned i) const {
1613+
auto inheritedClause = getEntries();
1614+
auto &ctx = getASTContext();
1615+
1616+
// If there is just one entry, remove the entire inheritance clause.
1617+
if (inheritedClause.size() == 1) {
1618+
SourceLoc end = inheritedClause[i].getSourceRange().End;
1619+
return SourceRange(getColonLoc(),
1620+
Lexer::getLocForEndOfToken(ctx.SourceMgr, end));
1621+
}
1622+
1623+
// If we're at the first entry, remove from the start of this entry to the
1624+
// start of the next entry.
1625+
if (i == 0) {
1626+
return SourceRange(inheritedClause[i].getSourceRange().Start,
1627+
inheritedClause[i+1].getSourceRange().Start);
1628+
}
1629+
1630+
// Otherwise, remove from the end of the previous entry to the end of this
1631+
// entry.
1632+
SourceLoc afterPriorLoc =
1633+
Lexer::getLocForEndOfToken(ctx.SourceMgr,
1634+
inheritedClause[i-1].getSourceRange().End);
1635+
1636+
SourceLoc afterMyEndLoc =
1637+
Lexer::getLocForEndOfToken(ctx.SourceMgr,
1638+
inheritedClause[i].getSourceRange().End);
1639+
1640+
return SourceRange(afterPriorLoc, afterMyEndLoc);
1641+
}
1642+
15881643
InheritedTypes::InheritedTypes(const TypeDecl *typeDecl) : Decl(typeDecl) {
15891644
Entries = typeDecl->Inherited;
15901645
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ static Type containsParameterizedProtocolType(Type inheritedTy) {
9292
/// file.
9393
static void checkInheritanceClause(
9494
llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *> declUnion) {
95-
auto inheritedClause = InheritedTypes(declUnion).getEntries();
95+
auto inheritedTypes = InheritedTypes(declUnion);
96+
auto inheritedClause = inheritedTypes.getEntries();
9697
const ExtensionDecl *ext = nullptr;
9798
const TypeDecl *typeDecl = nullptr;
9899
const Decl *decl;
@@ -123,45 +124,6 @@ static void checkInheritanceClause(
123124
ASTContext &ctx = decl->getASTContext();
124125
auto &diags = ctx.Diags;
125126

126-
// Retrieve the location of the start of the inheritance clause.
127-
auto getStartLocOfInheritanceClause = [&] {
128-
if (ext)
129-
return ext->getSourceRange().End;
130-
131-
return typeDecl->getNameLoc();
132-
};
133-
134-
// Compute the source range to be used when removing something from an
135-
// inheritance clause.
136-
auto getRemovalRange = [&](unsigned i) {
137-
// If there is just one entry, remove the entire inheritance clause.
138-
if (inheritedClause.size() == 1) {
139-
SourceLoc start = getStartLocOfInheritanceClause();
140-
SourceLoc end = inheritedClause[i].getSourceRange().End;
141-
return SourceRange(Lexer::getLocForEndOfToken(ctx.SourceMgr, start),
142-
Lexer::getLocForEndOfToken(ctx.SourceMgr, end));
143-
}
144-
145-
// If we're at the first entry, remove from the start of this entry to the
146-
// start of the next entry.
147-
if (i == 0) {
148-
return SourceRange(inheritedClause[i].getSourceRange().Start,
149-
inheritedClause[i+1].getSourceRange().Start);
150-
}
151-
152-
// Otherwise, remove from the end of the previous entry to the end of this
153-
// entry.
154-
SourceLoc afterPriorLoc =
155-
Lexer::getLocForEndOfToken(ctx.SourceMgr,
156-
inheritedClause[i-1].getSourceRange().End);
157-
158-
SourceLoc afterMyEndLoc =
159-
Lexer::getLocForEndOfToken(ctx.SourceMgr,
160-
inheritedClause[i].getSourceRange().End);
161-
162-
return SourceRange(afterPriorLoc, afterMyEndLoc);
163-
};
164-
165127
// Check all of the types listed in the inheritance clause.
166128
Type superclassTy;
167129
SourceRange superclassRange;
@@ -210,7 +172,7 @@ static void checkInheritanceClause(
210172
// Swift <= 4.
211173
auto knownIndex = inheritedAnyObject->first;
212174
auto knownRange = inheritedAnyObject->second;
213-
SourceRange removeRange = getRemovalRange(knownIndex);
175+
SourceRange removeRange = inheritedTypes.getRemovalRange(knownIndex);
214176
if (!ctx.LangOpts.isSwiftVersionAtLeast(5) &&
215177
isa<ProtocolDecl>(decl) &&
216178
Lexer::getTokenAtLocation(ctx.SourceMgr, knownRange.Start)
@@ -278,7 +240,7 @@ static void checkInheritanceClause(
278240
// Check if we already had a raw type.
279241
if (superclassTy) {
280242
if (superclassTy->isEqual(inheritedTy)) {
281-
auto removeRange = getRemovalRange(i);
243+
auto removeRange = inheritedTypes.getRemovalRange(i);
282244
diags.diagnose(inherited.getSourceRange().Start,
283245
diag::duplicate_inheritance, inheritedTy)
284246
.fixItRemoveChars(removeRange.Start, removeRange.End);
@@ -305,7 +267,7 @@ static void checkInheritanceClause(
305267

306268
// If this is not the first entry in the inheritance clause, complain.
307269
if (i > 0) {
308-
auto removeRange = getRemovalRange(i);
270+
auto removeRange = inheritedTypes.getRemovalRange(i);
309271

310272
diags.diagnose(inherited.getSourceRange().Start,
311273
diag::raw_type_not_first, inheritedTy)
@@ -330,7 +292,7 @@ static void checkInheritanceClause(
330292

331293
if (superclassTy->isEqual(inheritedTy)) {
332294
// Duplicate superclass.
333-
auto removeRange = getRemovalRange(i);
295+
auto removeRange = inheritedTypes.getRemovalRange(i);
334296
diags.diagnose(inherited.getSourceRange().Start,
335297
diag::duplicate_inheritance, inheritedTy)
336298
.fixItRemoveChars(removeRange.Start, removeRange.End);
@@ -346,7 +308,7 @@ static void checkInheritanceClause(
346308

347309
// If this is not the first entry in the inheritance clause, complain.
348310
if (isa<ClassDecl>(decl) && i > 0) {
349-
auto removeRange = getRemovalRange(i);
311+
auto removeRange = inheritedTypes.getRemovalRange(i);
350312
diags.diagnose(inherited.getSourceRange().Start,
351313
diag::superclass_not_first, inheritedTy)
352314
.fixItRemoveChars(removeRange.Start, removeRange.End)

0 commit comments

Comments
 (0)