Skip to content

[CodeCompletion] Improve context type analysis #18564

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 10, 2018

Conversation

rintaro
Copy link
Member

@rintaro rintaro commented Aug 8, 2018

  • Always activate CodeCompletionExpr so we don't interfere typechecking contexts.
  • Improve inference of return type from context.
    • For methods, un-curry function interface type so we can get declared return type.
    • For closures, fall back to getting explicit result type in case we failed to retrieve it from the type of the closure itself.
  • Handle binary/unary expression in context type analysis. This improves completion for RHS of operators.
  • Handle ExprPattern in context type analysis. This improves completion in matching pattern.
  • Small cleanups for getPositionInArgs() ([IDE][NFC] Cleanup collectArgumentExpectation() #18535 (comment))

@rintaro
Copy link
Member Author

rintaro commented Aug 8, 2018

@swift-ci Please smoke test

@rintaro
Copy link
Member Author

rintaro commented Aug 8, 2018

@benlangmuir I'm doing this because I want to use CodeCompletionTypeContextAnalyzer in UnresolvedMember completion. If we improve this, we can get rid of most of UnresolvedMember specific logic. Here's WIP branch 4556a51

@rintaro rintaro requested a review from benlangmuir August 8, 2018 10:58
Copy link
Contributor

@benlangmuir benlangmuir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this patch looks great! More correct and less complex.

Could you explain more about what effect this has:

Always activate CodeCompletionExpr so we don't interfere typechecking contexts.

I wasn't aware of this flag; why were we skipping CSGen for code completion expressions before?

if (CE->hasExplicitResultType())
return const_cast<ClosureExpr *>(CE)
->getExplicitResultTypeLoc()
.getType();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't this just set as the result type?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked into it yet, but probably, if the type checker fails to type check the body of single expression closure, type checking for closure also fails.

break;
}
default:
llvm_unreachable("Unhandled pattern kinds.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: it should be "kind" singular.

@@ -1510,12 +1510,19 @@ static Type getReturnTypeFromContext(const DeclContext *DC) {
if (auto FD = dyn_cast<AbstractFunctionDecl>(DC)) {
if (FD->hasInterfaceType()) {
if (auto FT = FD->getInterfaceType()->getAs<FunctionType>()) {
if (FD->getDeclContext()->isTypeContext())
FT = FT->getResult()->castTo<FunctionType>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use getMethodInterfaceType() here

@rintaro
Copy link
Member Author

rintaro commented Aug 9, 2018

Always activate CodeCompletionExpr so we don't interfere typechecking contexts.

I wasn't aware of this flag; why were we skipping CSGen for code completion expressions before?

To be honest, I don't know.
When CodeCompletionExpr was introduced in 398e923...1cb8468, It was used only for inferring type for call arguments. It was probably "OK" to skip them.
The flag itself was introduced in 17c9b2b. But I guess @slavapestov just wanted to preserve the behavior "generate type variable only if we're type checking from inside TypeChecker::typeCheckCompletionSequence()"

rintaro added 6 commits August 9, 2018 19:16
There's no reason not to activate them.
* For methods, un-curry function interface type so we can get declared
return type.
* For closures, fall back to getting explicit result type in case we
cannot retrieve it from the type of closure itself.
…lyzer

Don't discard parsed expression in Parser. This improves type inference
for CodeCompletionExpr.
in 'ExprParentFinder'. There's no reason to re-pack into ASTNode.
This improves type inference for code completion in argument position of
EnumElementPattern.
* Don't need to look for CodeCompletionExpr. It's wrong anyway because
  what we are looking for is not neccessarily a 'CodeCompletionExpr'.
* Use getElementLoc(i).isValid() instead of !getElementName(i).empty().
  Just in case users write '_:' for call argument.
* Don't suggest argument labels for implicit call expression. For
  instance, string interpolation segments.
@rintaro rintaro force-pushed the ide-completion-contextanalysis branch from 043aa25 to 137ca65 Compare August 9, 2018 10:50
@rintaro
Copy link
Member Author

rintaro commented Aug 9, 2018

@swift-ci Please smoke test

@rintaro rintaro merged commit 254be25 into swiftlang:master Aug 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants