mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CodeComplete] More efficient skipping for completions in if/switch exprs
Skip type-checking multi-statement branches if the completion is in a single-expression branch, and skip type-checking the expression as a whole if the completion is in a multi-statement branch.
This commit is contained in:
@@ -242,7 +242,9 @@ private:
|
||||
// MARK: Constraint generation
|
||||
|
||||
/// Check whether it makes sense to convert this element into a constraint.
|
||||
static bool isViableElement(ASTNode element) {
|
||||
static bool isViableElement(ASTNode element,
|
||||
bool isForSingleValueStmtCompletion,
|
||||
ConstraintSystem &cs) {
|
||||
if (auto *decl = element.dyn_cast<Decl *>()) {
|
||||
// - Ignore variable declarations, they are handled by pattern bindings;
|
||||
// - Ignore #if, the chosen children should appear in the
|
||||
@@ -255,10 +257,21 @@ static bool isViableElement(ASTNode element) {
|
||||
}
|
||||
|
||||
if (auto *stmt = element.dyn_cast<Stmt *>()) {
|
||||
// Empty brace statements are now viable because they do not require
|
||||
// inference.
|
||||
if (auto *braceStmt = dyn_cast<BraceStmt>(stmt)) {
|
||||
return braceStmt->getNumElements() > 0;
|
||||
// Empty brace statements are not viable because they do not require
|
||||
// inference.
|
||||
if (braceStmt->empty())
|
||||
return false;
|
||||
|
||||
// Skip if we're doing completion for a SingleValueStmtExpr, and have a
|
||||
// brace that doesn't involve a single expression, and doesn't have a
|
||||
// code completion token, as it won't contribute to the type of the
|
||||
// SingleValueStmtExpr.
|
||||
if (isForSingleValueStmtCompletion &&
|
||||
!braceStmt->getSingleActiveExpression() &&
|
||||
!cs.containsIDEInspectionTarget(braceStmt)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,13 +337,19 @@ static void createConjunction(ConstraintSystem &cs,
|
||||
|
||||
VarRefCollector paramCollector(cs);
|
||||
|
||||
// Whether we're doing completion, and the conjunction is for a
|
||||
// SingleValueStmtExpr, or one of its braces.
|
||||
const auto isForSingleValueStmtCompletion =
|
||||
cs.isForCodeCompletion() &&
|
||||
locator->isForSingleValueStmtConjunctionOrBrace();
|
||||
|
||||
for (const auto &entry : elements) {
|
||||
ASTNode element = std::get<0>(entry);
|
||||
ContextualTypeInfo context = std::get<1>(entry);
|
||||
bool isDiscarded = std::get<2>(entry);
|
||||
ConstraintLocator *elementLoc = std::get<3>(entry);
|
||||
|
||||
if (!isViableElement(element))
|
||||
if (!isViableElement(element, isForSingleValueStmtCompletion, cs))
|
||||
continue;
|
||||
|
||||
// If this conjunction going to represent a body of a closure,
|
||||
|
||||
Reference in New Issue
Block a user