Skip to content

Commit e5e469f

Browse files
authored
Merge pull request #26217 from nkcsgexi/index-util-ide-type
IDE: move two AST traversal utilities from libIndex to IDE type checking
2 parents da61cc8 + ab86991 commit e5e469f

File tree

6 files changed

+91
-114
lines changed

6 files changed

+91
-114
lines changed

include/swift/Index/Utils.h

Lines changed: 0 additions & 41 deletions
This file was deleted.

include/swift/Sema/IDETypeChecking.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,24 @@ namespace swift {
241241
Optional<std::pair<Type, Type>>
242242
getRootAndResultTypeOfKeypathDynamicMember(SubscriptDecl *subscript,
243243
const DeclContext *DC);
244+
/// Collect all the protocol requirements that a given declaration can
245+
/// provide default implementations for. VD is a declaration in extension
246+
/// declaration. Scratch is the buffer to collect those protocol
247+
/// requirements.
248+
///
249+
/// \returns the slice of Scratch
250+
ArrayRef<ValueDecl*>
251+
canDeclProvideDefaultImplementationFor(ValueDecl* VD,
252+
llvm::SmallVectorImpl<ValueDecl*> &Scratch);
253+
254+
/// Get decls that the given decl overrides, protocol requirements that
255+
/// it serves as a default implementation of, and optionally protocol
256+
/// requirements it satisfies in a conforming class
257+
std::vector<ValueDecl*>
258+
collectAllOverriddenDecls(ValueDecl *VD,
259+
bool IncludeProtocolRequirements = true,
260+
bool Transitive = false);
261+
244262
}
245263

246264
#endif

lib/IDE/IDETypeChecking.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,3 +740,69 @@ swift::collectExpressionType(SourceFile &SF,
740740
Walker.walk(SF);
741741
return Scratch;
742742
}
743+
744+
static Type getContextFreeInterfaceType(ValueDecl *VD) {
745+
if (auto AFD = dyn_cast<AbstractFunctionDecl>(VD)) {
746+
return AFD->getMethodInterfaceType();
747+
}
748+
return VD->getInterfaceType();
749+
}
750+
751+
ArrayRef<ValueDecl*> swift::
752+
canDeclProvideDefaultImplementationFor(ValueDecl* VD,
753+
llvm::SmallVectorImpl<ValueDecl*> &Scratch) {
754+
755+
// Skip decls that don't have valid names.
756+
if (!VD->getFullName())
757+
return {};
758+
759+
// Check if VD is from a protocol extension.
760+
auto P = VD->getDeclContext()->getExtendedProtocolDecl();
761+
if (!P)
762+
return {};
763+
764+
// Look up all decls in the protocol's inheritance chain for the ones with
765+
// the same name with VD.
766+
ResolvedMemberResult LookupResult =
767+
resolveValueMember(*P->getInnermostDeclContext(),
768+
P->getDeclaredInterfaceType(), VD->getFullName());
769+
770+
auto VDType = getContextFreeInterfaceType(VD);
771+
for (auto Mem : LookupResult.getMemberDecls(InterestedMemberKind::All)) {
772+
if (isa<ProtocolDecl>(Mem->getDeclContext())) {
773+
if (Mem->isProtocolRequirement() &&
774+
getContextFreeInterfaceType(Mem)->isEqual(VDType)) {
775+
// We find a protocol requirement VD can provide default
776+
// implementation for.
777+
Scratch.push_back(Mem);
778+
}
779+
}
780+
}
781+
return Scratch;
782+
}
783+
784+
std::vector<ValueDecl*> swift::
785+
collectAllOverriddenDecls(ValueDecl *VD, bool IncludeProtocolRequirements,
786+
bool Transitive) {
787+
std::vector<ValueDecl*> results;
788+
789+
if (auto Overridden = VD->getOverriddenDecl()) {
790+
results.push_back(Overridden);
791+
while (Transitive && (Overridden = Overridden->getOverriddenDecl()))
792+
results.push_back(Overridden);
793+
}
794+
795+
// Collect the protocol requirements this decl is a default impl for
796+
llvm::SmallVector<ValueDecl*, 2> Buffer;
797+
for (auto Req : canDeclProvideDefaultImplementationFor(VD, Buffer)) {
798+
results.push_back(Req);
799+
}
800+
801+
if (IncludeProtocolRequirements) {
802+
for (auto Satisfied : VD->getSatisfiedProtocolRequirements()) {
803+
results.push_back(Satisfied);
804+
}
805+
}
806+
807+
return results;
808+
}

lib/Index/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ add_swift_host_library(swiftIndex STATIC
44
IndexRecord.cpp
55
IndexSymbol.cpp)
66
target_link_libraries(swiftIndex PRIVATE
7-
swiftAST)
7+
swiftAST
8+
swiftIDE)

lib/Index/Index.cpp

Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/Index/Index.h"
14-
#include "swift/Index/Utils.h"
1514

1615
#include "swift/AST/ASTContext.h"
1716
#include "swift/AST/Comment.h"
@@ -847,7 +846,7 @@ bool IndexSwiftASTWalker::startEntityDecl(ValueDecl *D) {
847846
return false;
848847
}
849848

850-
for (auto Overriden: getOverriddenDecls(D, /*IncludeProtocolReqs=*/false)) {
849+
for (auto Overriden: collectAllOverriddenDecls(D, /*IncludeProtocolReqs=*/false)) {
851850
addRelation(Info, (SymbolRoleSet) SymbolRole::RelationOverrideOf, Overriden);
852851
}
853852

@@ -1564,73 +1563,6 @@ void IndexSwiftASTWalker::collectRecursiveModuleImports(
15641563
}
15651564
}
15661565

1567-
static Type getContextFreeInterfaceType(ValueDecl *VD) {
1568-
if (auto AFD = dyn_cast<AbstractFunctionDecl>(VD)) {
1569-
return AFD->getMethodInterfaceType();
1570-
}
1571-
return VD->getInterfaceType();
1572-
}
1573-
1574-
ArrayRef<ValueDecl*> swift::
1575-
canDeclProvideDefaultImplementationFor(ValueDecl* VD,
1576-
llvm::SmallVectorImpl<ValueDecl*> &Scratch) {
1577-
1578-
// Skip decls that don't have valid names.
1579-
if (!VD->getFullName())
1580-
return {};
1581-
1582-
// Check if VD is from a protocol extension.
1583-
auto P = VD->getDeclContext()->getExtendedProtocolDecl();
1584-
if (!P)
1585-
return {};
1586-
1587-
// Look up all decls in the protocol's inheritance chain for the ones with
1588-
// the same name with VD.
1589-
ResolvedMemberResult LookupResult =
1590-
resolveValueMember(*P->getInnermostDeclContext(),
1591-
P->getDeclaredInterfaceType(), VD->getFullName());
1592-
1593-
auto VDType = getContextFreeInterfaceType(VD);
1594-
for (auto Mem : LookupResult.getMemberDecls(InterestedMemberKind::All)) {
1595-
if (isa<ProtocolDecl>(Mem->getDeclContext())) {
1596-
if (Mem->isProtocolRequirement() &&
1597-
getContextFreeInterfaceType(Mem)->isEqual(VDType)) {
1598-
// We find a protocol requirement VD can provide default
1599-
// implementation for.
1600-
Scratch.push_back(Mem);
1601-
}
1602-
}
1603-
}
1604-
return Scratch;
1605-
}
1606-
1607-
std::vector<ValueDecl*> swift::
1608-
getOverriddenDecls(ValueDecl *VD, bool IncludeProtocolRequirements,
1609-
bool Transitive) {
1610-
std::vector<ValueDecl*> results;
1611-
1612-
if (auto Overridden = VD->getOverriddenDecl()) {
1613-
results.push_back(Overridden);
1614-
while (Transitive && (Overridden = Overridden->getOverriddenDecl()))
1615-
results.push_back(Overridden);
1616-
}
1617-
1618-
// Collect the protocol requirements this decl is a default impl for
1619-
llvm::SmallVector<ValueDecl*, 2> Buffer;
1620-
for (auto Req : canDeclProvideDefaultImplementationFor(VD, Buffer)) {
1621-
results.push_back(Req);
1622-
}
1623-
1624-
if (IncludeProtocolRequirements) {
1625-
for (auto Satisfied : VD->getSatisfiedProtocolRequirements()) {
1626-
results.push_back(Satisfied);
1627-
}
1628-
}
1629-
1630-
return results;
1631-
}
1632-
1633-
16341566
//===----------------------------------------------------------------------===//
16351567
// Indexing entry points
16361568
//===----------------------------------------------------------------------===//

lib/Migrator/APIDiffMigratorPass.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include "swift/Basic/StringExtras.h"
1616
#include "swift/Frontend/Frontend.h"
1717
#include "swift/IDE/Utils.h"
18-
#include "swift/Index/Utils.h"
18+
#include "swift/Sema/IDETypeChecking.h"
1919
#include "swift/Migrator/ASTMigratorPass.h"
2020
#include "swift/Migrator/EditorAdapter.h"
2121
#include "swift/Migrator/FixitApplyDiagnosticConsumer.h"
@@ -298,8 +298,9 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
298298
};
299299

300300
addDiffItems(VD);
301-
for (auto *Overridden: getOverriddenDecls(VD, /*IncludeProtocolReqs=*/true,
302-
/*Transitive=*/true)) {
301+
for (auto *Overridden: collectAllOverriddenDecls(VD,
302+
/*IncludeProtocolReqs=*/true,
303+
/*Transitive=*/true)) {
303304
addDiffItems(Overridden);
304305
}
305306
return results;

0 commit comments

Comments
 (0)