Skip to content

Commit f159175

Browse files
authored
Merge pull request swiftlang#32391 from xedin/type-check-for-code-completion
[TypeChecker] Add a entry point to be used for code completion
2 parents cc5335c + ccd7167 commit f159175

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,49 @@ void ConstraintSystem::solveImpl(SmallVectorImpl<Solution> &solutions) {
13751375
}
13761376
}
13771377

1378+
void ConstraintSystem::solveForCodeCompletion(
1379+
Expr *expr, DeclContext *DC, Type contextualType, ContextualTypePurpose CTP,
1380+
llvm::function_ref<void(const Solution &)> callback) {
1381+
// First, pre-check the expression, validating any types that occur in the
1382+
// expression and folding sequence expressions.
1383+
if (ConstraintSystem::preCheckExpression(expr, DC))
1384+
return;
1385+
1386+
ConstraintSystemOptions options;
1387+
options |= ConstraintSystemFlags::AllowFixes;
1388+
options |= ConstraintSystemFlags::SuppressDiagnostics;
1389+
1390+
ConstraintSystem cs(DC, options);
1391+
1392+
if (CTP != ContextualTypePurpose::CTP_Unused)
1393+
cs.setContextualType(expr, TypeLoc::withoutLoc(contextualType), CTP);
1394+
1395+
// Set up the expression type checker timer.
1396+
cs.Timer.emplace(expr, cs);
1397+
1398+
cs.shrink(expr);
1399+
1400+
if (cs.generateConstraints(expr, DC))
1401+
return;
1402+
1403+
llvm::SmallVector<Solution, 4> solutions;
1404+
1405+
{
1406+
SolverState state(cs, FreeTypeVariableBinding::Disallow);
1407+
1408+
// Enable "diagnostic mode" by default, this means that
1409+
// solver would produce "fixed" solutions along side of
1410+
// valid ones, which helps code completion to rank choices.
1411+
state.recordFixes = true;
1412+
1413+
cs.solveImpl(solutions);
1414+
}
1415+
1416+
for (const auto &solution : solutions) {
1417+
callback(solution);
1418+
}
1419+
}
1420+
13781421
void ConstraintSystem::collectDisjunctions(
13791422
SmallVectorImpl<Constraint *> &disjunctions) {
13801423
for (auto &constraint : InactiveConstraints) {

lib/Sema/ConstraintSystem.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4728,6 +4728,31 @@ class ConstraintSystem {
47284728
= FreeTypeVariableBinding::Disallow,
47294729
bool allowFixes = false);
47304730

4731+
/// Construct and solve a system of constraints based on the given expression
4732+
/// and its contextual information.
4733+
///
4734+
/// This menthod is designed to be used for code completion which means that
4735+
/// it doesn't mutate given expression, even if there is a single valid
4736+
/// solution, and constraint solver is allowed to produce partially correct
4737+
/// solutions, such solutions can have any number of holes in them, alongside
4738+
/// with valid ones.
4739+
///
4740+
/// \param expr The expression involved in code completion.
4741+
///
4742+
/// \param DC The declaration context this expression is found in.
4743+
///
4744+
/// \param contextualType The type expression is being converted to.
4745+
///
4746+
/// \param CTP When contextualType is specified, this indicates what
4747+
/// the conversion is doing.
4748+
///
4749+
/// \param callback The callback to be used to provide results to
4750+
/// code completion.
4751+
static void
4752+
solveForCodeCompletion(Expr *expr, DeclContext *DC, Type contextualType,
4753+
ContextualTypePurpose CTP,
4754+
llvm::function_ref<void(const Solution &)> callback);
4755+
47314756
private:
47324757
/// Solve the system of constraints.
47334758
///

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,6 +2328,19 @@ TypeChecker::getTypeOfCompletionOperator(DeclContext *DC, Expr *LHS,
23282328
}
23292329
}
23302330

2331+
void TypeChecker::typeCheckForCodeCompletion(
2332+
Expr *expr, DeclContext *DC, Type contextualType, ContextualTypePurpose CTP,
2333+
llvm::function_ref<void(const Solution &)> callback) {
2334+
auto &Context = DC->getASTContext();
2335+
2336+
FrontendStatsTracer StatsTracer(Context.Stats,
2337+
"typecheck-for-code-completion", expr);
2338+
PrettyStackTraceExpr stackTrace(Context, "code-completion", expr);
2339+
2340+
ConstraintSystem::solveForCodeCompletion(expr, DC, contextualType, CTP,
2341+
callback);
2342+
}
2343+
23312344
bool TypeChecker::typeCheckBinding(
23322345
Pattern *&pattern, Expr *&initializer, DeclContext *DC,
23332346
Type patternType, PatternBindingDecl *PBD, unsigned patternNumber) {

lib/Sema/TypeChecker.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,17 @@ FunctionType *getTypeOfCompletionOperator(DeclContext *DC, Expr *LHS,
700700
DeclRefKind refKind,
701701
ConcreteDeclRef &refdDecl);
702702

703+
/// Type check the given expression and provide results back to code completion
704+
/// via specified callback.
705+
///
706+
/// This menthod is designed to be used for code completion which means that
707+
/// it doesn't mutate AST and constraint solver is allowed to produce partially
708+
/// correct solutions, such solutions can have any number of holes in them,
709+
/// alongside with valid ones.
710+
void typeCheckForCodeCompletion(
711+
Expr *expr, DeclContext *DC, Type contextualType, ContextualTypePurpose CTP,
712+
llvm::function_ref<void(const constraints::Solution &)> callback);
713+
703714
/// Check the key-path expression.
704715
///
705716
/// Returns the type of the last component of the key-path.

0 commit comments

Comments
 (0)