mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[CodeCompletion] Avoid typechecking all toplevel decls in the current file
- Use `performParseAndResolveImportsOnly()` to invoke the frontend - Do `bindExtensions()` in `ide::typeCheckContextUntil()` - Typecheck preceding `TopLevelCodeDecl`s only if the compleiton is in a `TopLevelCodeDecl` - Other related tweaks rdar://problem/56636747
This commit is contained in:
@@ -4138,10 +4138,47 @@ public:
|
||||
|
||||
void addAccessControl(const ValueDecl *VD,
|
||||
CodeCompletionResultBuilder &Builder) {
|
||||
assert(CurrDeclContext->getSelfNominalTypeDecl());
|
||||
auto AccessOfContext =
|
||||
CurrDeclContext->getSelfNominalTypeDecl()->getFormalAccess();
|
||||
auto Access = std::min(VD->getFormalAccess(), AccessOfContext);
|
||||
auto CurrentNominal = CurrDeclContext->getSelfNominalTypeDecl();
|
||||
assert(CurrentNominal);
|
||||
|
||||
auto AccessOfContext = CurrentNominal->getFormalAccess();
|
||||
if (AccessOfContext < AccessLevel::Public)
|
||||
return;
|
||||
|
||||
auto Access = VD->getFormalAccess();
|
||||
// Use the greater access between the protocol requirement and the witness.
|
||||
// In case of:
|
||||
//
|
||||
// public protocol P { func foo() }
|
||||
// public class B { func foo() {} }
|
||||
// public class C: B, P {
|
||||
// <complete>
|
||||
// }
|
||||
//
|
||||
// 'VD' is 'B.foo()' which is implicitly 'internal'. But as the overriding
|
||||
// declaration, the user needs to write both 'public' and 'override':
|
||||
//
|
||||
// public class C: B {
|
||||
// public override func foo() {}
|
||||
// }
|
||||
if (Access < AccessLevel::Public &&
|
||||
!isa<ProtocolDecl>(VD->getDeclContext())) {
|
||||
for (auto Conformance : CurrentNominal->getAllConformances()) {
|
||||
auto Proto = Conformance->getProtocol();
|
||||
for (auto Member : Proto->getMembers()) {
|
||||
auto Requirement = dyn_cast<ValueDecl>(Member);
|
||||
if (!Requirement || !Requirement->isProtocolRequirement() ||
|
||||
isa<AssociatedTypeDecl>(Requirement))
|
||||
continue;
|
||||
|
||||
auto Witness = Conformance->getWitnessDecl(Requirement);
|
||||
if (Witness == VD)
|
||||
Access = std::max(Access, Requirement->getFormalAccess());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Access = std::min(Access, AccessOfContext);
|
||||
// Only emit 'public', not needed otherwise.
|
||||
if (Access >= AccessLevel::Public)
|
||||
Builder.addAccessControlKeyword(Access);
|
||||
@@ -4364,9 +4401,11 @@ public:
|
||||
if (D->shouldHideFromEditor())
|
||||
return;
|
||||
|
||||
if (D->isFinal() ||
|
||||
// A 'class' member with an initial value cannot be overriden either.
|
||||
(D->isStatic() && D->getAttrs().hasAttribute<HasInitialValueAttr>()))
|
||||
if (D->isFinal())
|
||||
return;
|
||||
|
||||
// A 'class' member with an initial value cannot be overriden either.
|
||||
if (D->isStatic() && isa<VarDecl>(D) && cast<VarDecl>(D)->hasInitialValue())
|
||||
return;
|
||||
|
||||
bool hasIntroducer = hasFuncIntroducer ||
|
||||
@@ -4955,13 +4994,16 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
|
||||
case CompletionKind::TypeIdentifierWithoutDot:
|
||||
break;
|
||||
|
||||
case CompletionKind::TypeDeclResultBeginning:
|
||||
if (!isa<ProtocolDecl>(CurDeclContext))
|
||||
if (CurDeclContext->isTypeContext() ||
|
||||
(ParsedDecl && isa<FuncDecl>(ParsedDecl)))
|
||||
case CompletionKind::TypeDeclResultBeginning: {
|
||||
auto DC = CurDeclContext;
|
||||
if (ParsedDecl && ParsedDecl == CurDeclContext->getAsDecl())
|
||||
DC = ParsedDecl->getDeclContext();
|
||||
if (!isa<ProtocolDecl>(DC))
|
||||
if (DC->isTypeContext() || (ParsedDecl && isa<FuncDecl>(ParsedDecl)))
|
||||
addOpaqueTypeKeyword(Sink);
|
||||
|
||||
LLVM_FALLTHROUGH;
|
||||
}
|
||||
case CompletionKind::TypeSimpleBeginning:
|
||||
addAnyTypeKeyword(Sink);
|
||||
break;
|
||||
@@ -5130,8 +5172,6 @@ void CodeCompletionCallbacksImpl::doneParsing() {
|
||||
CD->getContextKind() == DeclContextKind::TopLevelCodeDecl)
|
||||
MaybeFuncBody = false;
|
||||
}
|
||||
// Add keywords even if type checking fails completely.
|
||||
addKeywords(CompletionContext.getResultSink(), MaybeFuncBody);
|
||||
|
||||
if (auto *DC = dyn_cast_or_null<DeclContext>(ParsedDecl)) {
|
||||
if (DC->isChildContextOf(CurDeclContext))
|
||||
@@ -5142,6 +5182,9 @@ void CodeCompletionCallbacksImpl::doneParsing() {
|
||||
CurDeclContext,
|
||||
CurDeclContext->getASTContext().SourceMgr.getCodeCompletionLoc());
|
||||
|
||||
// Add keywords even if type checking fails completely.
|
||||
addKeywords(CompletionContext.getResultSink(), MaybeFuncBody);
|
||||
|
||||
Optional<Type> ExprType;
|
||||
ConcreteDeclRef ReferencedDecl = nullptr;
|
||||
if (ParsedExpr) {
|
||||
|
||||
Reference in New Issue
Block a user