[CSFix] Attempt to replace .subscript(...) with subscript operator

If there are no members named "subscript" available, let's try to
replace it with subscript operator with might be what was intended.
This commit is contained in:
Pavel Yaskevich
2019-01-05 14:53:34 -08:00
parent 5636cd3769
commit f032b9c57c
3 changed files with 44 additions and 5 deletions

View File

@@ -235,3 +235,12 @@ InsertExplicitCall *InsertExplicitCall::create(ConstraintSystem &cs,
ConstraintLocator *locator) {
return new (cs.getAllocator()) InsertExplicitCall(cs, locator);
}
bool UseSubscriptOperator::diagnose(Expr *root, bool asNote) const {
return false;
}
UseSubscriptOperator *UseSubscriptOperator::create(ConstraintSystem &cs,
ConstraintLocator *locator) {
return new (cs.getAllocator()) UseSubscriptOperator(cs, locator);
}

View File

@@ -96,6 +96,9 @@ enum class FixKind : uint8_t {
/// Add explicit `()` at the end of function or member to call it.
InsertCall,
/// Instead of spelling out `subscript` directly, use subscript operator.
UseSubscriptOperator,
};
class ConstraintFix {
@@ -447,6 +450,21 @@ public:
ConstraintLocator *locator);
};
class UseSubscriptOperator final : public ConstraintFix {
public:
UseSubscriptOperator(ConstraintSystem &cs, ConstraintLocator *locator)
: ConstraintFix(cs, FixKind::UseSubscriptOperator, locator) {}
std::string getName() const override {
return "replace '.subscript(...)' with subscript operator";
}
bool diagnose(Expr *root, bool asNote = false) const override;
static UseSubscriptOperator *create(ConstraintSystem &cs,
ConstraintLocator *locator);
};
} // end namespace constraints
} // end namespace swift

View File

@@ -3765,10 +3765,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
// function takes no arguments, otherwise it
// would make sense to report this a missing member.
if (funcType->getNumParams() == 0) {
auto *fix = InsertExplicitCall::create(*this, locator);
if (recordFix(fix))
return SolutionKind::Error;
auto result = simplifyMemberConstraint(
kind, funcType->getResult(), member, memberTy, useDC,
functionRefKind, outerAlternatives, flags, locatorB);
@@ -3777,9 +3773,24 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
// let's return, otherwise let's fall-through and report
// this problem as a missing member.
if (result == SolutionKind::Solved)
return result;
return recordFix(InsertExplicitCall::create(*this, locator))
? SolutionKind::Error
: SolutionKind::Solved;
}
}
// Instead of using subscript operator spelled out `subscript` directly.
if (member.getBaseName() == getTokenText(tok::kw_subscript)) {
auto result = simplifyMemberConstraint(
kind, baseTy, DeclBaseName::createSubscript(), memberTy, useDC,
functionRefKind, {}, flags, locatorB);
// Looks like it was indeed meant to be a subscript operator.
if (result == SolutionKind::Solved)
return recordFix(UseSubscriptOperator::create(*this, locator))
? SolutionKind::Error
: SolutionKind::Solved;
}
}
return SolutionKind::Error;
}
@@ -5442,6 +5453,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
}
case FixKind::UseSubscriptOperator:
case FixKind::InsertCall:
case FixKind::ExplicitlyEscaping:
case FixKind::CoerceToCheckedCast: