[CodeCompletion] Store ignored arguments as Expr * instead of ConstraintLocators

This avoids the construction of `ConstraintLocator`s.
This commit is contained in:
Alex Hoppen
2022-03-18 08:30:03 +01:00
parent a8cec01c6f
commit 82fc059018
4 changed files with 36 additions and 23 deletions

View File

@@ -2415,7 +2415,7 @@ private:
/// Arguments after the code completion token that were thus ignored (i.e. /// Arguments after the code completion token that were thus ignored (i.e.
/// assigned fresh type variables) for type checking. /// assigned fresh type variables) for type checking.
llvm::SetVector<ConstraintLocator *> IgnoredArguments; llvm::SetVector<Expr *> IgnoredArguments;
/// Maps node types used within all portions of the constraint /// Maps node types used within all portions of the constraint
/// system, instead of directly using the types on the /// system, instead of directly using the types on the
@@ -3187,18 +3187,25 @@ public:
bool containsCodeCompletionLoc(ASTNode node) const; bool containsCodeCompletionLoc(ASTNode node) const;
bool containsCodeCompletionLoc(const ArgumentList *args) const; bool containsCodeCompletionLoc(const ArgumentList *args) const;
/// Marks the argument with the \p ArgLoc locator as being ignored because it /// Marks the argument \p Arg as being ignored because it occurs after the
/// occurs after the code completion token. This assumes that the argument is /// code completion token. This assumes that the argument is not type checked
/// not type checked (by assigning it a fresh type variable) and prevents /// (by assigning it a fresh type variable) and prevents fixes from being
/// fixes from being generated for this argument. /// generated for this argument.
void markArgumentIgnoredForCodeCompletion(ConstraintLocator *ArgLoc) { void markArgumentIgnoredForCodeCompletion(Expr *Arg) {
IgnoredArguments.insert(ArgLoc); IgnoredArguments.insert(Arg);
} }
/// Whether the argument with the \p ArgLoc locator occurs after the code /// Whether the argument \p Arg occurs after the code completion token and
/// completion tokena and thus should be ignored and not generate any fixes. /// thus should be ignored and not generate any fixes.
bool isArgumentIgnoredForCodeCompletion(ConstraintLocator *ArgLoc) { bool isArgumentIgnoredForCodeCompletion(Expr *Arg) const {
return IgnoredArguments.count(ArgLoc) > 0; return IgnoredArguments.count(Arg) > 0;
}
/// Whether the constraint system has ignored any arguments for code
/// completion, i.e. whether there is an expression for which
/// \c isArgumentIgnoredForCodeCompletion returns \c true.
bool hasArgumentsIgnoredForCodeCompletion() const {
return !IgnoredArguments.empty();
} }
void setClosureType(const ClosureExpr *closure, FunctionType *type) { void setClosureType(const ClosureExpr *closure, FunctionType *type) {

View File

@@ -2024,9 +2024,13 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const {
return false; return false;
// Don't penailze solutions that have holes for ignored arguments. // Don't penailze solutions that have holes for ignored arguments.
if (cs.isArgumentIgnoredForCodeCompletion( if (cs.hasArgumentsIgnoredForCodeCompletion()) {
TypeVar->getImpl().getLocator())) { // Avoid simplifying the locator if the constriant system didn't ignore
return false; // any arguments.
auto argExpr = simplifyLocatorToAnchor(TypeVar->getImpl().getLocator());
if (cs.isArgumentIgnoredForCodeCompletion(argExpr.dyn_cast<Expr *>())) {
return false;
}
} }
} }
// Reflect in the score that this type variable couldn't be // Reflect in the score that this type variable couldn't be

View File

@@ -788,8 +788,7 @@ namespace {
CS(cs) {} CS(cs) {}
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override { std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
if (CS.isArgumentIgnoredForCodeCompletion( if (CS.isArgumentIgnoredForCodeCompletion(expr)) {
CS.getConstraintLocator(expr))) {
return {false, expr}; return {false, expr};
} }
@@ -3648,8 +3647,7 @@ namespace {
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override { std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
auto &CS = CG.getConstraintSystem(); auto &CS = CG.getConstraintSystem();
if (CS.isArgumentIgnoredForCodeCompletion( if (CS.isArgumentIgnoredForCodeCompletion(expr)) {
CS.getConstraintLocator(expr))) {
CG.setTypeForArgumentIgnoredForCompletion(expr); CG.setTypeForArgumentIgnoredForCompletion(expr);
return {false, expr}; return {false, expr};
} }
@@ -3724,8 +3722,7 @@ namespace {
SmallVector<Expr *, 2> ignoredArgs; SmallVector<Expr *, 2> ignoredArgs;
getArgumentsAfterCodeCompletionToken(expr, CS, ignoredArgs); getArgumentsAfterCodeCompletionToken(expr, CS, ignoredArgs);
for (auto ignoredArg : ignoredArgs) { for (auto ignoredArg : ignoredArgs) {
CS.markArgumentIgnoredForCodeCompletion( CS.markArgumentIgnoredForCodeCompletion(ignoredArg);
CS.getConstraintLocator(ignoredArg));
} }
} }

View File

@@ -12470,9 +12470,14 @@ bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact) {
log << ")\n"; log << ")\n";
} }
if (isArgumentIgnoredForCodeCompletion(fix->getLocator())) { if (hasArgumentsIgnoredForCodeCompletion()) {
// The argument was ignored. Don't record any fixes for it. // Avoid simplifying the locator if the constraint system didn't ignore any
return false; // arguments.
auto argExpr = simplifyLocatorToAnchor(fix->getLocator());
if (isArgumentIgnoredForCodeCompletion(getAsExpr<Expr>(argExpr))) {
// The argument was ignored. Don't record any fixes for it.
return false;
}
} }
// Record the fix. // Record the fix.