IDE+Evaluator: refactor resolveProtocolName to using the request evaluator, NFC

This commit is contained in:
Xi Ge
2019-07-22 15:35:09 -07:00
parent 344d9311a8
commit 1cb746b47c
8 changed files with 104 additions and 39 deletions

View File

@@ -17,6 +17,7 @@
SWIFT_TYPEID_NAMED(NominalTypeDecl *, NominalTypeDecl)
SWIFT_TYPEID_NAMED(VarDecl *, VarDecl)
SWIFT_TYPEID_NAMED(ValueDecl *, ValueDecl)
SWIFT_TYPEID_NAMED(ProtocolDecl *, ProtocolDecl)
SWIFT_TYPEID_NAMED(Decl *, Decl)
SWIFT_TYPEID(Type)
SWIFT_TYPEID(PropertyWrapperBackingPropertyInfo)

View File

@@ -18,3 +18,4 @@ SWIFT_TYPEID(CursorInfoRequest)
SWIFT_TYPEID(RangeInfoRequest)
SWIFT_TYPEID(ProvideDefaultImplForRequest)
SWIFT_TYPEID(CollectOverriddenDeclsRequest)
SWIFT_TYPEID(ResolveProtocolNameRequest)

View File

@@ -229,6 +229,58 @@ public:
SourceLoc getNearestLoc() const { return SourceLoc(); };
};
//----------------------------------------------------------------------------//
// ResolveProtocolNameRequest
//----------------------------------------------------------------------------//
struct ProtocolNameOwner {
DeclContext *DC;
StringRef Name;
ProtocolNameOwner(DeclContext *DC, StringRef Name): DC(DC), Name(Name) {}
friend llvm::hash_code hash_value(const ProtocolNameOwner &CI) {
return hash_value(CI.Name);
}
friend bool operator==(const ProtocolNameOwner &lhs,
const ProtocolNameOwner &rhs) {
return lhs.Name == rhs.Name;
}
friend bool operator!=(const ProtocolNameOwner &lhs,
const ProtocolNameOwner &rhs) {
return !(lhs == rhs);
}
friend void simple_display(llvm::raw_ostream &out,
const ProtocolNameOwner &owner) {
out << "Resolve " << owner.Name << " from ";
simple_display(out, owner.DC);
}
};
/// Resolve a protocol name to the protocol decl pointer inside the ASTContext
class ResolveProtocolNameRequest:
public SimpleRequest<ResolveProtocolNameRequest,
ProtocolDecl*(ProtocolNameOwner),
CacheKind::Cached>
{
public:
using SimpleRequest::SimpleRequest;
private:
friend SimpleRequest;
// Evaluation.
llvm::Expected<ProtocolDecl*> evaluate(Evaluator &evaluator,
ProtocolNameOwner Input) const;
public:
// Caching
bool isCached() const { return true; }
// Source location
SourceLoc getNearestLoc() const { return SourceLoc(); };
};
/// The zone number for the IDE.
#define SWIFT_IDE_REQUESTS_TYPEID_ZONE 137
#define SWIFT_TYPEID_ZONE SWIFT_IDE_REQUESTS_TYPEID_ZONE

View File

@@ -207,8 +207,7 @@ namespace swift {
/// Resolve a list of mangled names to accessible protocol decls from
/// the decl context.
bool resolveProtocolNames(DeclContext *DC, ArrayRef<const char *> names,
llvm::MapVector<ProtocolDecl*, StringRef> &result);
ProtocolDecl *resolveProtocolName(DeclContext *dc, StringRef Name);
/// FIXME: All of the below goes away once CallExpr directly stores its
/// arguments.

View File

@@ -33,7 +33,7 @@ class ConformingMethodListCallbacks : public CodeCompletionCallbacks {
DeclContext *CurDeclContext = nullptr;
void getMatchingMethods(Type T,
llvm::MapVector<ProtocolDecl*, StringRef> &expectedTypes,
llvm::SmallPtrSetImpl<ProtocolDecl*> &expectedTypes,
SmallVectorImpl<ValueDecl *> &result);
public:
@@ -91,8 +91,12 @@ void ConformingMethodListCallbacks::doneParsing() {
if (T->hasArchetype())
T = T->mapTypeOutOfContext();
llvm::MapVector<ProtocolDecl*, StringRef> expectedProtocols;
resolveProtocolNames(CurDeclContext, ExpectedTypeNames, expectedProtocols);
llvm::SmallPtrSet<ProtocolDecl*, 8> expectedProtocols;
for (auto Name: ExpectedTypeNames) {
if (auto *PD = resolveProtocolName(CurDeclContext, Name)) {
expectedProtocols.insert(PD);
}
}
// Collect the matching methods.
ConformingMethodListResult result(CurDeclContext, T);
@@ -102,7 +106,7 @@ void ConformingMethodListCallbacks::doneParsing() {
}
void ConformingMethodListCallbacks::getMatchingMethods(
Type T, llvm::MapVector<ProtocolDecl*, StringRef> &expectedTypes,
Type T, llvm::SmallPtrSetImpl<ProtocolDecl*> &expectedTypes,
SmallVectorImpl<ValueDecl *> &result) {
if (!T->mayHaveMembers())
return;
@@ -114,7 +118,7 @@ void ConformingMethodListCallbacks::getMatchingMethods(
Type T;
/// The list of expected types.
llvm::MapVector<ProtocolDecl*, StringRef> &ExpectedTypes;
llvm::SmallPtrSetImpl<ProtocolDecl*> &ExpectedTypes;
/// Result sink to populate.
SmallVectorImpl<ValueDecl *> &Result;
@@ -137,7 +141,7 @@ void ConformingMethodListCallbacks::getMatchingMethods(
// The return type conforms to any of the requested protocols.
for (auto Proto : ExpectedTypes) {
if (CurModule->conformsToProtocol(declTy, Proto.first))
if (CurModule->conformsToProtocol(declTy, Proto))
return true;
}
@@ -146,7 +150,7 @@ void ConformingMethodListCallbacks::getMatchingMethods(
public:
LocalConsumer(DeclContext *DC, Type T,
llvm::MapVector<ProtocolDecl*, StringRef> &expectedTypes,
llvm::SmallPtrSetImpl<ProtocolDecl*> &expectedTypes,
SmallVectorImpl<ValueDecl *> &result)
: CurModule(DC->getParentModule()), T(T), ExpectedTypes(expectedTypes),
Result(result) {}

View File

@@ -13,6 +13,7 @@
#include "swift/AST/ASTPrinter.h"
#include "swift/AST/Decl.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/ASTDemangler.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
@@ -1144,3 +1145,28 @@ CollectOverriddenDeclsRequest::evaluate(Evaluator &evaluator,
return copyToContext(VD->getASTContext(), llvm::makeArrayRef(results));
}
//----------------------------------------------------------------------------//
// ResolveProtocolNameRequest
//----------------------------------------------------------------------------//
llvm::Expected<ProtocolDecl*>
ResolveProtocolNameRequest::evaluate(Evaluator &evaluator,
ProtocolNameOwner Input) const {
auto &ctx = Input.DC->getASTContext();
auto name = Input.Name;
// First try to solve by usr
ProtocolDecl *pd = dyn_cast_or_null<ProtocolDecl>(Demangle::
getTypeDeclForUSR(ctx, name));
if (!pd) {
// Second try to solve by mangled symbol name
pd = dyn_cast_or_null<ProtocolDecl>(Demangle::getTypeDeclForMangling(ctx, name));
}
if (!pd) {
// Thirdly try to solve by mangled type name
if (auto ty = Demangle::getTypeForMangling(ctx, name)) {
pd = dyn_cast_or_null<ProtocolDecl>(ty->getAnyGeneric());
}
}
return pd;
}

View File

@@ -699,33 +699,10 @@ public:
}
};
bool swift::resolveProtocolNames(DeclContext *DC,
ArrayRef<const char *> names,
llvm::MapVector<ProtocolDecl*, StringRef> &result) {
assert(result.empty());
auto &ctx = DC->getASTContext();
for (auto name : names) {
// First try to solve by usr
ProtocolDecl *pd = dyn_cast_or_null<ProtocolDecl>(Demangle::
getTypeDeclForUSR(ctx, name));
if (!pd) {
// Second try to solve by mangled symbol name
pd = dyn_cast_or_null<ProtocolDecl>(Demangle::getTypeDeclForMangling(ctx, name));
}
if (!pd) {
// Thirdly try to solve by mangled type name
if (auto ty = Demangle::getTypeForMangling(ctx, name)) {
pd = dyn_cast_or_null<ProtocolDecl>(ty->getAnyGeneric());
}
}
if (pd) {
result.insert({pd, name});
}
}
if (names.size() == result.size())
return false;
// If we resolved none but the given names are not empty, return true for failure.
return result.size() == 0;
ProtocolDecl* swift::resolveProtocolName(DeclContext *dc, StringRef name) {
return evaluateOrDefault(dc->getASTContext().evaluator,
ResolveProtocolNameRequest(ProtocolNameOwner(dc, name)),
nullptr);
}
ArrayRef<ExpressionTypeInfo>
@@ -735,8 +712,13 @@ swift::collectExpressionType(SourceFile &SF,
bool CanonicalType,
llvm::raw_ostream &OS) {
llvm::MapVector<ProtocolDecl*, StringRef> InterestedProtocols;
if (resolveProtocolNames(&SF, ExpectedProtocols, InterestedProtocols))
return {};
for (auto Name: ExpectedProtocols) {
if (auto *pd = resolveProtocolName(&SF, Name)) {
InterestedProtocols.insert({pd, Name});
} else {
return {};
}
}
ExpressionTypeCollector Walker(SF, InterestedProtocols, Scratch,
CanonicalType, OS);
Walker.walk(SF);

View File

@@ -81,7 +81,7 @@ static bool swiftConformingMethodListImpl(
// FIXME: error?
return true;
}
registerIDETypeCheckRequestFunctions(CI.getASTContext().evaluator);
registerIDERequestFunctions(CI.getASTContext().evaluator);
CI.performSema();
return true;