mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IDE+Evaluator: refactor resolveProtocolName to using the request evaluator, NFC
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
SWIFT_TYPEID_NAMED(NominalTypeDecl *, NominalTypeDecl)
|
SWIFT_TYPEID_NAMED(NominalTypeDecl *, NominalTypeDecl)
|
||||||
SWIFT_TYPEID_NAMED(VarDecl *, VarDecl)
|
SWIFT_TYPEID_NAMED(VarDecl *, VarDecl)
|
||||||
SWIFT_TYPEID_NAMED(ValueDecl *, ValueDecl)
|
SWIFT_TYPEID_NAMED(ValueDecl *, ValueDecl)
|
||||||
|
SWIFT_TYPEID_NAMED(ProtocolDecl *, ProtocolDecl)
|
||||||
SWIFT_TYPEID_NAMED(Decl *, Decl)
|
SWIFT_TYPEID_NAMED(Decl *, Decl)
|
||||||
SWIFT_TYPEID(Type)
|
SWIFT_TYPEID(Type)
|
||||||
SWIFT_TYPEID(PropertyWrapperBackingPropertyInfo)
|
SWIFT_TYPEID(PropertyWrapperBackingPropertyInfo)
|
||||||
|
|||||||
@@ -18,3 +18,4 @@ SWIFT_TYPEID(CursorInfoRequest)
|
|||||||
SWIFT_TYPEID(RangeInfoRequest)
|
SWIFT_TYPEID(RangeInfoRequest)
|
||||||
SWIFT_TYPEID(ProvideDefaultImplForRequest)
|
SWIFT_TYPEID(ProvideDefaultImplForRequest)
|
||||||
SWIFT_TYPEID(CollectOverriddenDeclsRequest)
|
SWIFT_TYPEID(CollectOverriddenDeclsRequest)
|
||||||
|
SWIFT_TYPEID(ResolveProtocolNameRequest)
|
||||||
|
|||||||
@@ -229,6 +229,58 @@ public:
|
|||||||
SourceLoc getNearestLoc() const { return SourceLoc(); };
|
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.
|
/// The zone number for the IDE.
|
||||||
#define SWIFT_IDE_REQUESTS_TYPEID_ZONE 137
|
#define SWIFT_IDE_REQUESTS_TYPEID_ZONE 137
|
||||||
#define SWIFT_TYPEID_ZONE SWIFT_IDE_REQUESTS_TYPEID_ZONE
|
#define SWIFT_TYPEID_ZONE SWIFT_IDE_REQUESTS_TYPEID_ZONE
|
||||||
|
|||||||
@@ -207,8 +207,7 @@ namespace swift {
|
|||||||
|
|
||||||
/// Resolve a list of mangled names to accessible protocol decls from
|
/// Resolve a list of mangled names to accessible protocol decls from
|
||||||
/// the decl context.
|
/// the decl context.
|
||||||
bool resolveProtocolNames(DeclContext *DC, ArrayRef<const char *> names,
|
ProtocolDecl *resolveProtocolName(DeclContext *dc, StringRef Name);
|
||||||
llvm::MapVector<ProtocolDecl*, StringRef> &result);
|
|
||||||
|
|
||||||
/// FIXME: All of the below goes away once CallExpr directly stores its
|
/// FIXME: All of the below goes away once CallExpr directly stores its
|
||||||
/// arguments.
|
/// arguments.
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class ConformingMethodListCallbacks : public CodeCompletionCallbacks {
|
|||||||
DeclContext *CurDeclContext = nullptr;
|
DeclContext *CurDeclContext = nullptr;
|
||||||
|
|
||||||
void getMatchingMethods(Type T,
|
void getMatchingMethods(Type T,
|
||||||
llvm::MapVector<ProtocolDecl*, StringRef> &expectedTypes,
|
llvm::SmallPtrSetImpl<ProtocolDecl*> &expectedTypes,
|
||||||
SmallVectorImpl<ValueDecl *> &result);
|
SmallVectorImpl<ValueDecl *> &result);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -91,8 +91,12 @@ void ConformingMethodListCallbacks::doneParsing() {
|
|||||||
if (T->hasArchetype())
|
if (T->hasArchetype())
|
||||||
T = T->mapTypeOutOfContext();
|
T = T->mapTypeOutOfContext();
|
||||||
|
|
||||||
llvm::MapVector<ProtocolDecl*, StringRef> expectedProtocols;
|
llvm::SmallPtrSet<ProtocolDecl*, 8> expectedProtocols;
|
||||||
resolveProtocolNames(CurDeclContext, ExpectedTypeNames, expectedProtocols);
|
for (auto Name: ExpectedTypeNames) {
|
||||||
|
if (auto *PD = resolveProtocolName(CurDeclContext, Name)) {
|
||||||
|
expectedProtocols.insert(PD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Collect the matching methods.
|
// Collect the matching methods.
|
||||||
ConformingMethodListResult result(CurDeclContext, T);
|
ConformingMethodListResult result(CurDeclContext, T);
|
||||||
@@ -102,7 +106,7 @@ void ConformingMethodListCallbacks::doneParsing() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConformingMethodListCallbacks::getMatchingMethods(
|
void ConformingMethodListCallbacks::getMatchingMethods(
|
||||||
Type T, llvm::MapVector<ProtocolDecl*, StringRef> &expectedTypes,
|
Type T, llvm::SmallPtrSetImpl<ProtocolDecl*> &expectedTypes,
|
||||||
SmallVectorImpl<ValueDecl *> &result) {
|
SmallVectorImpl<ValueDecl *> &result) {
|
||||||
if (!T->mayHaveMembers())
|
if (!T->mayHaveMembers())
|
||||||
return;
|
return;
|
||||||
@@ -114,7 +118,7 @@ void ConformingMethodListCallbacks::getMatchingMethods(
|
|||||||
Type T;
|
Type T;
|
||||||
|
|
||||||
/// The list of expected types.
|
/// The list of expected types.
|
||||||
llvm::MapVector<ProtocolDecl*, StringRef> &ExpectedTypes;
|
llvm::SmallPtrSetImpl<ProtocolDecl*> &ExpectedTypes;
|
||||||
|
|
||||||
/// Result sink to populate.
|
/// Result sink to populate.
|
||||||
SmallVectorImpl<ValueDecl *> &Result;
|
SmallVectorImpl<ValueDecl *> &Result;
|
||||||
@@ -137,7 +141,7 @@ void ConformingMethodListCallbacks::getMatchingMethods(
|
|||||||
|
|
||||||
// The return type conforms to any of the requested protocols.
|
// The return type conforms to any of the requested protocols.
|
||||||
for (auto Proto : ExpectedTypes) {
|
for (auto Proto : ExpectedTypes) {
|
||||||
if (CurModule->conformsToProtocol(declTy, Proto.first))
|
if (CurModule->conformsToProtocol(declTy, Proto))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +150,7 @@ void ConformingMethodListCallbacks::getMatchingMethods(
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
LocalConsumer(DeclContext *DC, Type T,
|
LocalConsumer(DeclContext *DC, Type T,
|
||||||
llvm::MapVector<ProtocolDecl*, StringRef> &expectedTypes,
|
llvm::SmallPtrSetImpl<ProtocolDecl*> &expectedTypes,
|
||||||
SmallVectorImpl<ValueDecl *> &result)
|
SmallVectorImpl<ValueDecl *> &result)
|
||||||
: CurModule(DC->getParentModule()), T(T), ExpectedTypes(expectedTypes),
|
: CurModule(DC->getParentModule()), T(T), ExpectedTypes(expectedTypes),
|
||||||
Result(result) {}
|
Result(result) {}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "swift/AST/ASTPrinter.h"
|
#include "swift/AST/ASTPrinter.h"
|
||||||
#include "swift/AST/Decl.h"
|
#include "swift/AST/Decl.h"
|
||||||
#include "swift/AST/NameLookup.h"
|
#include "swift/AST/NameLookup.h"
|
||||||
|
#include "swift/AST/ASTDemangler.h"
|
||||||
#include "swift/Basic/SourceManager.h"
|
#include "swift/Basic/SourceManager.h"
|
||||||
#include "swift/Frontend/Frontend.h"
|
#include "swift/Frontend/Frontend.h"
|
||||||
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
|
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
|
||||||
@@ -1144,3 +1145,28 @@ CollectOverriddenDeclsRequest::evaluate(Evaluator &evaluator,
|
|||||||
|
|
||||||
return copyToContext(VD->getASTContext(), llvm::makeArrayRef(results));
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -699,33 +699,10 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool swift::resolveProtocolNames(DeclContext *DC,
|
ProtocolDecl* swift::resolveProtocolName(DeclContext *dc, StringRef name) {
|
||||||
ArrayRef<const char *> names,
|
return evaluateOrDefault(dc->getASTContext().evaluator,
|
||||||
llvm::MapVector<ProtocolDecl*, StringRef> &result) {
|
ResolveProtocolNameRequest(ProtocolNameOwner(dc, name)),
|
||||||
assert(result.empty());
|
nullptr);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayRef<ExpressionTypeInfo>
|
ArrayRef<ExpressionTypeInfo>
|
||||||
@@ -735,8 +712,13 @@ swift::collectExpressionType(SourceFile &SF,
|
|||||||
bool CanonicalType,
|
bool CanonicalType,
|
||||||
llvm::raw_ostream &OS) {
|
llvm::raw_ostream &OS) {
|
||||||
llvm::MapVector<ProtocolDecl*, StringRef> InterestedProtocols;
|
llvm::MapVector<ProtocolDecl*, StringRef> InterestedProtocols;
|
||||||
if (resolveProtocolNames(&SF, ExpectedProtocols, InterestedProtocols))
|
for (auto Name: ExpectedProtocols) {
|
||||||
return {};
|
if (auto *pd = resolveProtocolName(&SF, Name)) {
|
||||||
|
InterestedProtocols.insert({pd, Name});
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
ExpressionTypeCollector Walker(SF, InterestedProtocols, Scratch,
|
ExpressionTypeCollector Walker(SF, InterestedProtocols, Scratch,
|
||||||
CanonicalType, OS);
|
CanonicalType, OS);
|
||||||
Walker.walk(SF);
|
Walker.walk(SF);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ static bool swiftConformingMethodListImpl(
|
|||||||
// FIXME: error?
|
// FIXME: error?
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
registerIDETypeCheckRequestFunctions(CI.getASTContext().evaluator);
|
registerIDERequestFunctions(CI.getASTContext().evaluator);
|
||||||
CI.performSema();
|
CI.performSema();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user