Skip to content

Commit b4ce18a

Browse files
authored
Merge pull request #26268 from nkcsgexi/ide-type-checking-request
IDE+Evaluator: refactor the implementation of two type checker utilities to evaluator requests. NFC
2 parents c28174a + 77ba3a2 commit b4ce18a

17 files changed

+264
-49
lines changed

include/swift/AST/Type.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,6 @@ inline T *staticCastHelper(const Type &Ty) {
611611
template <typename T>
612612
using TypeArrayView = ArrayRefView<Type, T*, staticCastHelper,
613613
/*AllowOrigAccess*/true>;
614-
615614
} // end namespace swift
616615

617616
namespace llvm {

include/swift/Basic/Statistics.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ FRONTEND_STATISTIC(Sema, NumUnloadedLazyIterableDeclContexts)
224224
#include "swift/AST/AccessTypeIDZone.def"
225225
#include "swift/AST/NameLookupTypeIDZone.def"
226226
#include "swift/AST/TypeCheckerTypeIDZone.def"
227+
#include "swift/Sema/IDETypeCheckingRequestIDZone.def"
227228
#include "swift/IDE/IDERequestIDZone.def"
228229
#undef SWIFT_TYPEID
229230

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//===-------- IDETypeCheckingIDZone.def -------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This definition file describes the types in the IDE requests
14+
// TypeID zone, for use with the TypeID template.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
SWIFT_TYPEID(IsDeclApplicableRequest)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//===----- IDETypeCheckingRequests.h - IDE type-check Requests --*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines IDE type checking request using the evaluator model.
14+
// The file needs to exist in sema because it needs internal implementation
15+
// of the type checker to fulfill some requests
16+
//
17+
//===----------------------------------------------------------------------===//
18+
#ifndef SWIFT_IDE_TYPE_CHECKING_REQUESTS_H
19+
#define SWIFT_IDE_TYPE_CHECKING_REQUESTS_H
20+
21+
#include "swift/AST/ASTTypeIDs.h"
22+
#include "swift/AST/Evaluator.h"
23+
#include "swift/AST/SimpleRequest.h"
24+
#include "swift/AST/TypeCheckRequests.h"
25+
26+
namespace swift {
27+
//----------------------------------------------------------------------------//
28+
// Decl applicability checking
29+
//----------------------------------------------------------------------------//
30+
struct DeclApplicabilityOwner {
31+
const DeclContext *DC;
32+
const Type Ty;
33+
const Decl *ExtensionOrMember;
34+
35+
DeclApplicabilityOwner(const DeclContext *DC, Type Ty, const ExtensionDecl *ED):
36+
DC(DC), Ty(Ty), ExtensionOrMember(ED) {}
37+
DeclApplicabilityOwner(const DeclContext *DC, Type Ty, const ValueDecl *VD):
38+
DC(DC), Ty(Ty), ExtensionOrMember(VD) {}
39+
40+
friend llvm::hash_code hash_value(const DeclApplicabilityOwner &CI) {
41+
return hash_combine(hash_value(CI.Ty.getPointer()),
42+
hash_value(CI.ExtensionOrMember));
43+
}
44+
45+
friend bool operator==(const DeclApplicabilityOwner &lhs,
46+
const DeclApplicabilityOwner &rhs) {
47+
return lhs.Ty.getPointer() == rhs.Ty.getPointer() &&
48+
lhs.ExtensionOrMember == rhs.ExtensionOrMember;
49+
}
50+
51+
friend bool operator!=(const DeclApplicabilityOwner &lhs,
52+
const DeclApplicabilityOwner &rhs) {
53+
return !(lhs == rhs);
54+
}
55+
56+
friend void simple_display(llvm::raw_ostream &out,
57+
const DeclApplicabilityOwner &owner) {
58+
out << "Checking if ";
59+
simple_display(out, owner.ExtensionOrMember);
60+
out << " is applicable for ";
61+
simple_display(out, owner.Ty);
62+
}
63+
};
64+
65+
class IsDeclApplicableRequest:
66+
public SimpleRequest<IsDeclApplicableRequest,
67+
bool(DeclApplicabilityOwner),
68+
CacheKind::Cached> {
69+
public:
70+
using SimpleRequest::SimpleRequest;
71+
72+
private:
73+
friend SimpleRequest;
74+
75+
// Evaluation.
76+
llvm::Expected<bool> evaluate(Evaluator &evaluator,
77+
DeclApplicabilityOwner Owner) const;
78+
79+
public:
80+
// Caching
81+
bool isCached() const { return true; }
82+
// Source location
83+
SourceLoc getNearestLoc() const { return SourceLoc(); };
84+
};
85+
86+
87+
/// The zone number for the IDE.
88+
#define SWIFT_IDE_TYPE_CHECK_REQUESTS_TYPEID_ZONE 97
89+
#define SWIFT_TYPEID_ZONE SWIFT_IDE_TYPE_CHECK_REQUESTS_TYPEID_ZONE
90+
#define SWIFT_TYPEID_HEADER "swift/Sema/IDETypeCheckingRequestIDZone.def"
91+
#include "swift/Basic/DefineTypeIDZone.h"
92+
#undef SWIFT_TYPEID_ZONE
93+
#undef SWIFT_TYPEID_HEADER
94+
95+
// Set up reporting of evaluated requests.
96+
#define SWIFT_TYPEID(RequestType) \
97+
template<> \
98+
inline void reportEvaluatedRequest(UnifiedStatsReporter &stats, \
99+
const RequestType &request) { \
100+
++stats.getFrontendCounters().RequestType; \
101+
}
102+
#include "swift/Sema/IDETypeCheckingRequestIDZone.def"
103+
#undef SWIFT_TYPEID
104+
105+
} // end namespace swift
106+
107+
#endif // SWIFT_IDE_REQUESTS_H

include/swift/Subsystems.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,12 @@ namespace swift {
401401
/// The ASTContext will automatically call these upon construction.
402402
void registerIDERequestFunctions(Evaluator &evaluator);
403403

404+
/// Register type check request functions for IDE's usage with the evaluator.
405+
///
406+
/// The ASTContext will automatically call these upon construction.
407+
/// Calling registerIDERequestFunctions will invoke this function as well.
408+
void registerIDETypeCheckRequestFunctions(Evaluator &evaluator);
409+
404410
} // end namespace swift
405411

406412
#endif // SWIFT_SUBSYSTEMS_H

lib/Frontend/Frontend.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,10 @@ bool CompilerInstance::setUpASTContextIfNeeded() {
189189
Diagnostics));
190190
registerTypeCheckerRequestFunctions(Context->evaluator);
191191

192-
// Migrator and indexing need some IDE requests.
192+
// Migrator, indexing and typo correction need some IDE requests.
193193
if (Invocation.getMigratorOptions().shouldRunMigrator() ||
194-
!Invocation.getFrontendOptions().IndexStorePath.empty()) {
194+
!Invocation.getFrontendOptions().IndexStorePath.empty() ||
195+
Invocation.getLangOptions().TypoCorrectionLimit) {
195196
registerIDERequestFunctions(Context->evaluator);
196197
}
197198
if (setUpModuleLoaders())

lib/IDE/IDERequests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ reinterpret_cast<AbstractRequestFunction *>(&Name::evaluateRequest),
4646
void swift::registerIDERequestFunctions(Evaluator &evaluator) {
4747
evaluator.registerRequestFunctions(SWIFT_IDE_REQUESTS_TYPEID_ZONE,
4848
ideRequestFunctions);
49+
registerIDETypeCheckRequestFunctions(evaluator);
4950
}
5051

5152
//----------------------------------------------------------------------------//

lib/IDE/IDETypeChecking.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/ASTDemangler.h"
2525
#include "swift/AST/ProtocolConformance.h"
2626
#include "swift/Sema/IDETypeChecking.h"
27+
#include "swift/Sema/IDETypeCheckingRequests.h"
2728
#include "swift/IDE/SourceEntityWalker.h"
2829
#include "swift/IDE/IDERequests.h"
2930
#include "swift/Parse/Lexer.h"
@@ -756,3 +757,15 @@ collectAllOverriddenDecls(ValueDecl *VD, bool IncludeProtocolRequirements,
756757
CollectOverriddenDeclsRequest(OverridenDeclsOwner(VD,
757758
IncludeProtocolRequirements, Transitive)), ArrayRef<ValueDecl*>());
758759
}
760+
761+
bool swift::isExtensionApplied(const DeclContext *DC, Type BaseTy,
762+
const ExtensionDecl *ED) {
763+
return evaluateOrDefault(DC->getASTContext().evaluator,
764+
IsDeclApplicableRequest(DeclApplicabilityOwner(DC, BaseTy, ED)), false);
765+
}
766+
767+
bool swift::isMemberDeclApplied(const DeclContext *DC, Type BaseTy,
768+
const ValueDecl *VD) {
769+
return evaluateOrDefault(DC->getASTContext().evaluator,
770+
IsDeclApplicableRequest(DeclApplicabilityOwner(DC, BaseTy, VD)), false);
771+
}

lib/Sema/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ add_swift_host_library(swiftSema STATIC
6161
TypeCheckSwitchStmt.cpp
6262
TypeCheckType.cpp
6363
TypeChecker.cpp
64+
IDETypeCheckingRequests.cpp
6465

6566
${EXTRA_TYPECHECKER_FLAGS})
6667
target_link_libraries(swiftSema PRIVATE

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3742,7 +3742,7 @@ void ConstraintSystem::optimizeConstraints(Expr *e) {
37423742
e->walk(optimizer);
37433743
}
37443744

3745-
static bool areGenericRequirementsSatisfied(
3745+
bool swift::areGenericRequirementsSatisfied(
37463746
const DeclContext *DC, const GenericSignature *sig,
37473747
const SubstitutionMap &Substitutions, bool isExtension) {
37483748

@@ -3766,48 +3766,6 @@ static bool areGenericRequirementsSatisfied(
37663766
return CS.solveSingle().hasValue();
37673767
}
37683768

3769-
bool swift::isExtensionApplied(const DeclContext *DC, Type BaseTy,
3770-
const ExtensionDecl *ED) {
3771-
// We can't do anything if the base type has unbound generic parameters.
3772-
// We can't leak type variables into another constraint system.
3773-
if (BaseTy->hasTypeVariable() || BaseTy->hasUnboundGenericType() ||
3774-
BaseTy->hasUnresolvedType() || BaseTy->hasError())
3775-
return true;
3776-
3777-
if (!ED->isConstrainedExtension())
3778-
return true;
3779-
3780-
TypeChecker *TC = &createTypeChecker(DC->getASTContext());
3781-
TC->validateExtension(const_cast<ExtensionDecl *>(ED));
3782-
3783-
GenericSignature *genericSig = ED->getGenericSignature();
3784-
SubstitutionMap substMap = BaseTy->getContextSubstitutionMap(
3785-
DC->getParentModule(), ED->getExtendedNominal());
3786-
return areGenericRequirementsSatisfied(DC, genericSig, substMap,
3787-
/*isExtension=*/true);
3788-
}
3789-
3790-
bool swift::isMemberDeclApplied(const DeclContext *DC, Type BaseTy,
3791-
const ValueDecl *VD) {
3792-
// We can't leak type variables into another constraint system.
3793-
// We can't do anything if the base type has unbound generic parameters.
3794-
if (BaseTy->hasTypeVariable() || BaseTy->hasUnboundGenericType()||
3795-
BaseTy->hasUnresolvedType() || BaseTy->hasError())
3796-
return true;
3797-
3798-
const GenericContext *genericDecl = VD->getAsGenericContext();
3799-
if (!genericDecl)
3800-
return true;
3801-
const GenericSignature *genericSig = genericDecl->getGenericSignature();
3802-
if (!genericSig)
3803-
return true;
3804-
3805-
SubstitutionMap substMap = BaseTy->getContextSubstitutionMap(
3806-
DC->getParentModule(), VD->getDeclContext());
3807-
return areGenericRequirementsSatisfied(DC, genericSig, substMap,
3808-
/*isExtension=*/false);
3809-
}
3810-
38113769
static bool canSatisfy(Type type1, Type type2, bool openArchetypes,
38123770
ConstraintKind kind, DeclContext *dc) {
38133771
std::unique_ptr<TypeChecker> CreatedTC;

lib/Sema/IDETypeCheckingRequests.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift/AST/ASTPrinter.h"
14+
#include "swift/AST/Decl.h"
15+
#include "swift/AST/NameLookup.h"
16+
#include "swift/Basic/SourceManager.h"
17+
#include "swift/Frontend/Frontend.h"
18+
#include "swift/Sema/IDETypeCheckingRequests.h"
19+
#include "swift/Subsystems.h"
20+
#include "TypeChecker.h"
21+
22+
using namespace swift;
23+
24+
namespace swift {
25+
// Implement the IDE type zone.
26+
#define SWIFT_TYPEID_ZONE SWIFT_IDE_TYPE_CHECK_REQUESTS_TYPEID_ZONE
27+
#define SWIFT_TYPEID_HEADER "swift/Sema/IDETypeCheckingRequestIDZone.def"
28+
#include "swift/Basic/ImplementTypeIDZone.h"
29+
#undef SWIFT_TYPEID_ZONE
30+
#undef SWIFT_TYPEID_HEADER
31+
}
32+
33+
// Define request evaluation functions for each of the IDE type check requests.
34+
static AbstractRequestFunction *ideTypeCheckRequestFunctions[] = {
35+
#define SWIFT_TYPEID(Name) \
36+
reinterpret_cast<AbstractRequestFunction *>(&Name::evaluateRequest),
37+
#include "swift/Sema/IDETypeCheckingRequestIDZone.def"
38+
#undef SWIFT_TYPEID
39+
};
40+
41+
void swift::registerIDETypeCheckRequestFunctions(Evaluator &evaluator) {
42+
evaluator.registerRequestFunctions(SWIFT_IDE_TYPE_CHECK_REQUESTS_TYPEID_ZONE,
43+
ideTypeCheckRequestFunctions);
44+
}
45+
46+
static bool isExtensionAppliedInternal(const DeclContext *DC, Type BaseTy,
47+
const ExtensionDecl *ED) {
48+
// We can't do anything if the base type has unbound generic parameters.
49+
// We can't leak type variables into another constraint system.
50+
if (BaseTy->hasTypeVariable() || BaseTy->hasUnboundGenericType() ||
51+
BaseTy->hasUnresolvedType() || BaseTy->hasError())
52+
return true;
53+
54+
if (!ED->isConstrainedExtension())
55+
return true;
56+
57+
TypeChecker *TC = &TypeChecker::createForContext((DC->getASTContext()));
58+
TC->validateExtension(const_cast<ExtensionDecl *>(ED));
59+
60+
GenericSignature *genericSig = ED->getGenericSignature();
61+
SubstitutionMap substMap = BaseTy->getContextSubstitutionMap(
62+
DC->getParentModule(), ED->getExtendedNominal());
63+
return areGenericRequirementsSatisfied(DC, genericSig, substMap,
64+
/*isExtension=*/true);
65+
}
66+
67+
static bool isMemberDeclAppliedInternal(const DeclContext *DC, Type BaseTy,
68+
const ValueDecl *VD) {
69+
// We can't leak type variables into another constraint system.
70+
// We can't do anything if the base type has unbound generic parameters.
71+
if (BaseTy->hasTypeVariable() || BaseTy->hasUnboundGenericType()||
72+
BaseTy->hasUnresolvedType() || BaseTy->hasError())
73+
return true;
74+
75+
const GenericContext *genericDecl = VD->getAsGenericContext();
76+
if (!genericDecl)
77+
return true;
78+
const GenericSignature *genericSig = genericDecl->getGenericSignature();
79+
if (!genericSig)
80+
return true;
81+
82+
SubstitutionMap substMap = BaseTy->getContextSubstitutionMap(
83+
DC->getParentModule(), VD->getDeclContext());
84+
return areGenericRequirementsSatisfied(DC, genericSig, substMap,
85+
/*isExtension=*/false);
86+
}
87+
88+
llvm::Expected<bool>
89+
IsDeclApplicableRequest::evaluate(Evaluator &evaluator,
90+
DeclApplicabilityOwner Owner) const {
91+
if (auto *VD = dyn_cast<ValueDecl>(Owner.ExtensionOrMember)) {
92+
return isMemberDeclAppliedInternal(Owner.DC, Owner.Ty, VD);
93+
} else if (auto *ED = dyn_cast<ExtensionDecl>(Owner.ExtensionOrMember)) {
94+
return isExtensionAppliedInternal(Owner.DC, Owner.Ty, ED);
95+
} else {
96+
llvm_unreachable("unhandled decl kind");
97+
}
98+
}

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/ProtocolConformance.h"
2525
#include "swift/Basic/SourceManager.h"
2626
#include "swift/Basic/STLExtras.h"
27+
#include "swift/Sema/IDETypeCheckingRequests.h"
2728
#include "swift/Sema/IDETypeChecking.h"
2829
#include "llvm/ADT/SetVector.h"
2930
#include <set>
@@ -197,7 +198,9 @@ static void collectVisibleMemberDecls(const DeclContext *CurrDC, LookupState LS,
197198
continue;
198199
if (!isDeclVisibleInLookupMode(VD, LS, CurrDC, TypeResolver))
199200
continue;
200-
if (!isMemberDeclApplied(CurrDC, BaseType, VD))
201+
if (!evaluateOrDefault(CurrDC->getASTContext().evaluator,
202+
IsDeclApplicableRequest(DeclApplicabilityOwner(CurrDC, BaseType, VD)),
203+
false))
201204
continue;
202205
FoundDecls.push_back(VD);
203206
}
@@ -216,8 +219,9 @@ static void doGlobalExtensionLookup(Type BaseType,
216219

217220
// Look in each extension of this type.
218221
for (auto extension : nominal->getExtensions()) {
219-
if (!isExtensionApplied(const_cast<DeclContext *>(CurrDC), BaseType,
220-
extension))
222+
if (!evaluateOrDefault(CurrDC->getASTContext().evaluator,
223+
IsDeclApplicableRequest(DeclApplicabilityOwner(CurrDC, BaseType,
224+
extension)), false))
221225
continue;
222226

223227
collectVisibleMemberDecls(CurrDC, LS, BaseType, extension, FoundDecls,

0 commit comments

Comments
 (0)