Skip to content

Commit a149313

Browse files
committed
Refactor ArchetypeTransformer into a reusable IDE utility. NFC
1 parent 01ec4f2 commit a149313

File tree

3 files changed

+74
-65
lines changed

3 files changed

+74
-65
lines changed

include/swift/IDE/Utils.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ namespace swift {
4343
class SourceLoc;
4444
class Type;
4545
class Decl;
46+
class DeclContext;
4647
class ClangNode;
4748
class ClangImporter;
4849

@@ -177,6 +178,17 @@ class SemaLocResolver : public SourceEntityWalker {
177178
bool visitSubscriptReference(ValueDecl *D, CharSourceRange Range,
178179
bool IsOpenBracket) override;
179180
};
181+
182+
class ArchetypeTransformer {
183+
DeclContext *DC;
184+
Type BaseTy;
185+
llvm::DenseMap<TypeBase *, Type> Cache;
186+
TypeSubstitutionMap Map;
187+
std::function<Type(Type)> TheFunc = nullptr;
188+
public:
189+
ArchetypeTransformer(DeclContext *DC, Type Ty);
190+
llvm::function_ref<Type(Type)> getTransformerFunc();
191+
};
180192
} // namespace ide
181193
} // namespace swift
182194

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/Basic/PrimitiveParsing.h"
3333
#include "swift/Basic/STLExtras.h"
3434
#include "swift/Config.h"
35+
#include "swift/IDE/Utils.h"
3536
#include "swift/Sema/CodeCompletionTypeChecking.h"
3637
#include "swift/Strings.h"
3738
#include "clang/AST/ASTContext.h"

lib/IDE/CodeCompletion.cpp

Lines changed: 61 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,78 +1252,74 @@ void CodeCompletionCallbacksImpl::completeExpr() {
12521252
deliverCompletionResults();
12531253
}
12541254

1255-
namespace {
1256-
class ArchetypeTransformer {
1257-
DeclContext *DC;
1258-
Type BaseTy;
1259-
llvm::DenseMap<TypeBase *, Type> Cache;
1260-
TypeSubstitutionMap Map;
1261-
1262-
public:
1263-
ArchetypeTransformer(DeclContext *DC, Type Ty) : DC(DC), BaseTy(Ty->getRValueType()){
1264-
auto D = BaseTy->getNominalOrBoundGenericNominal();
1265-
if (!D)
1266-
return;
1267-
SmallVector<Type, 3> Scrach;
1268-
auto Params = D->getGenericParamTypes();
1269-
auto Args = BaseTy->getAllGenericArgs(Scrach);
1270-
assert(Params.size() == Args.size());
1271-
for (unsigned I = 0, N = Params.size(); I < N; I ++) {
1272-
Map[Params[I]->getCanonicalType()->castTo<GenericTypeParamType>()] = Args[I];
1273-
}
1255+
ArchetypeTransformer::ArchetypeTransformer(DeclContext *DC, Type Ty) :
1256+
DC(DC), BaseTy(Ty->getRValueType()){
1257+
auto D = BaseTy->getNominalOrBoundGenericNominal();
1258+
if (!D)
1259+
return;
1260+
SmallVector<Type, 3> Scrach;
1261+
auto Params = D->getGenericParamTypes();
1262+
auto Args = BaseTy->getAllGenericArgs(Scrach);
1263+
assert(Params.size() == Args.size());
1264+
for (unsigned I = 0, N = Params.size(); I < N; I ++) {
1265+
Map[Params[I]->getCanonicalType()->castTo<GenericTypeParamType>()] = Args[I];
12741266
}
1267+
}
12751268

1276-
std::function<Type(Type)> getTransformerFunc() {
1277-
return [&](Type Ty) {
1278-
if (Ty->getKind() != TypeKind::Archetype)
1279-
return Ty;
1280-
if (Cache.count(Ty.getPointer()) > 0) {
1281-
return Cache[Ty.getPointer()];
1282-
}
1283-
Type Result = Ty;
1284-
auto *RootArc = cast<ArchetypeType>(Result.getPointer());
1285-
llvm::SmallVector<Identifier, 1> Names;
1286-
bool SelfDerived = false;
1287-
for(auto *AT = RootArc; AT; AT = AT->getParent()) {
1288-
if(!AT->getSelfProtocol())
1289-
Names.insert(Names.begin(), AT->getName());
1290-
else
1291-
SelfDerived = true;
1292-
}
1293-
if (SelfDerived) {
1294-
if (auto MT = checkMemberType(*DC, BaseTy, Names)) {
1295-
if (auto NAT = dyn_cast<NameAliasType>(MT.getPointer())) {
1296-
Result = NAT->getSinglyDesugaredType();
1297-
} else {
1298-
Result = MT;
1299-
}
1269+
llvm::function_ref<Type(Type)> ArchetypeTransformer::getTransformerFunc() {
1270+
if (TheFunc)
1271+
return TheFunc;
1272+
TheFunc = [&](Type Ty) {
1273+
if (Ty->getKind() != TypeKind::Archetype)
1274+
return Ty;
1275+
if (Cache.count(Ty.getPointer()) > 0) {
1276+
return Cache[Ty.getPointer()];
1277+
}
1278+
Type Result = Ty;
1279+
auto *RootArc = cast<ArchetypeType>(Result.getPointer());
1280+
llvm::SmallVector<Identifier, 1> Names;
1281+
bool SelfDerived = false;
1282+
for(auto *AT = RootArc; AT; AT = AT->getParent()) {
1283+
if(!AT->getSelfProtocol())
1284+
Names.insert(Names.begin(), AT->getName());
1285+
else
1286+
SelfDerived = true;
1287+
}
1288+
if (SelfDerived) {
1289+
if (auto MT = checkMemberType(*DC, BaseTy, Names)) {
1290+
if (auto NAT = dyn_cast<NameAliasType>(MT.getPointer())) {
1291+
Result = NAT->getSinglyDesugaredType();
1292+
} else {
1293+
Result = MT;
13001294
}
1301-
} else {
1302-
Result = Ty.subst(DC->getParentModule(), Map, SubstFlags::IgnoreMissing);
13031295
}
1304-
1305-
auto ATT = dyn_cast<ArchetypeType>(Result.getPointer());
1306-
if (ATT && !ATT->getParent()) {
1307-
auto Conformances = ATT->getConformsTo();
1308-
if (Conformances.size() == 1) {
1309-
Result = Conformances[0]->getDeclaredType();
1310-
} else if (!Conformances.empty()) {
1311-
llvm::SmallVector<Type, 3> ConformedTypes;
1312-
for (auto PD : Conformances) {
1313-
ConformedTypes.push_back(PD->getDeclaredType());
1314-
}
1315-
Result = ProtocolCompositionType::get(DC->getASTContext(),
1316-
ConformedTypes);
1296+
} else {
1297+
Result = Ty.subst(DC->getParentModule(), Map, SubstFlags::IgnoreMissing);
1298+
}
1299+
1300+
auto ATT = dyn_cast<ArchetypeType>(Result.getPointer());
1301+
if (ATT && !ATT->getParent()) {
1302+
auto Conformances = ATT->getConformsTo();
1303+
if (Conformances.size() == 1) {
1304+
Result = Conformances[0]->getDeclaredType();
1305+
} else if (!Conformances.empty()) {
1306+
llvm::SmallVector<Type, 3> ConformedTypes;
1307+
for (auto PD : Conformances) {
1308+
ConformedTypes.push_back(PD->getDeclaredType());
13171309
}
1310+
Result = ProtocolCompositionType::get(DC->getASTContext(),
1311+
ConformedTypes);
13181312
}
1319-
if (Result->getKind() != TypeKind::Archetype)
1320-
Result = Result.transform(getTransformerFunc());
1321-
Cache[Ty.getPointer()] = Result;
1322-
return Result;
1323-
};
1324-
}
1325-
};
1313+
}
1314+
if (Result->getKind() != TypeKind::Archetype)
1315+
Result = Result.transform(getTransformerFunc());
1316+
Cache[Ty.getPointer()] = Result;
1317+
return Result;
1318+
};
1319+
return TheFunc;
1320+
}
13261321

1322+
namespace {
13271323
static bool isTopLevelContext(const DeclContext *DC) {
13281324
for (; DC && DC->isLocalContext(); DC = DC->getParent()) {
13291325
switch (DC->getContextKind()) {

0 commit comments

Comments
 (0)