Skip to content
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

Complete switch constructor #415

Merged
merged 12 commits into from
May 12, 2022
28 changes: 24 additions & 4 deletions analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ type labelled = {
}

type label = labelled option

type arg = {label : label; exp : Parsetree.expression}

let findNamedArgCompletable ~(args : arg list) ~endPos ~posBeforeCursor
Expand Down Expand Up @@ -561,10 +562,10 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text =
| Pexp_apply ({pexp_desc = Pexp_ident {txt = Lident "|."}}, [_; _]) ->
()
| Pexp_apply (funExpr, args)
when not
(* Normally named arg completion fires when the cursor is right after the expression.
E.g in foo(~<---there
But it should not fire in foo(~a)<---there *)
when (* Normally named arg completion fires when the cursor is right after the expression.
E.g in foo(~<---there
But it should not fire in foo(~a)<---there *)
not
(Loc.end_ expr.pexp_loc = posCursor
&& charBeforeCursor = Some ')') ->
let args = extractExpApplyArgs ~args in
Expand Down Expand Up @@ -666,6 +667,24 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text =
| _ -> ());
Ast_iterator.default_iterator.typ iterator core_type
in
let pat (iterator : Ast_iterator.iterator) (pat : Parsetree.pattern) =
if pat.ppat_loc |> Loc.hasPos ~pos:posNoWhite then (
found := true;
if debug then
Printf.printf "posCursor:[%s] posNoWhite:[%s] Found pattern:%s\n"
(Pos.toString posCursor) (Pos.toString posNoWhite)
(Loc.toString pat.ppat_loc);
(match pat.ppat_desc with
| Ppat_construct (lid, _) ->
let lidPath = flattenLidCheckDot lid in
if debug then
Printf.printf "Ppat_construct %s:%s\n"
(lidPath |> String.concat ".")
(Loc.toString lid.loc);
setResult (Cpath (CPId (lidPath, Value)))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Triggering completion as a Value. There's no need for specific completions for Constructor because of the upper case. Lower-case ids are normal values, and upper-case values are constructors.

| _ -> ());
Ast_iterator.default_iterator.pat iterator pat)
in
let module_expr (iterator : Ast_iterator.iterator)
(me : Parsetree.module_expr) =
(match me.pmod_desc with
Expand Down Expand Up @@ -725,6 +744,7 @@ let completionWithParser ~debug ~path ~posCursor ~currentFile ~text =
location;
module_expr;
module_type;
pat;
signature;
signature_item;
structure;
Expand Down
20 changes: 20 additions & 0 deletions analysis/tests/src/Completion.res
Original file line number Diff line number Diff line change
Expand Up @@ -355,3 +355,23 @@ let _ = <div name="" />

// (let _ = ff(~opt1=3))
// ^com

type v = This | That

let _ = x =>
switch x {
// | T
// ^com
| _ => 4
}

module AndThatOther = {
type v = And | ThatOther
}

let _ = x =>
switch x {
// | AndThatOther.T
// ^com
| _ => 4
}
50 changes: 50 additions & 0 deletions analysis/tests/src/expected/Completion.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,7 @@ Completable: Cpath Value[SomeLocal]
}]

Complete tests/src/Completion.res 271:20
posCursor:[271:20] posNoWhite:[271:19] Found pattern:[271:7->274:3]
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This, and other similar lines indicate that this affects a bit existing test cases, but does not lead to a different outcome.
It just means that the relevant type, found below, happens to be inside a pattern containing the cursor.

posCursor:[271:20] posNoWhite:[271:19] Found type:[271:11->274:3]
Ptyp_constr SomeLocal:[271:11->274:3]
Completable: Cpath Type[SomeLocal]
Expand Down Expand Up @@ -1313,6 +1314,7 @@ posCursor:[336:26] posNoWhite:[336:25] Found expr:[334:13->346:23]
posCursor:[336:26] posNoWhite:[336:25] Found expr:[334:13->338:6]
posCursor:[336:26] posNoWhite:[336:25] Found expr:[335:6->338:5]
posCursor:[336:26] posNoWhite:[336:25] Found expr:[336:16->338:5]
posCursor:[336:26] posNoWhite:[336:25] Found pattern:[336:20->338:5]
posCursor:[336:26] posNoWhite:[336:25] Found type:[336:23->338:5]
Ptyp_constr Res:[336:23->338:5]
Completable: Cpath Type[Res]
Expand Down Expand Up @@ -1381,3 +1383,51 @@ posCursor:[355:23] posNoWhite:[355:22] Found expr:[0:-1->355:23]
posCursor:[355:23] posNoWhite:[355:22] Found expr:[355:12->355:23]
[]

Complete tests/src/Completion.res 362:8
posCursor:[362:8] posNoWhite:[362:7] Found expr:[360:8->365:3]
posCursor:[362:8] posNoWhite:[362:7] Found expr:[361:2->365:3]
posCursor:[362:8] posNoWhite:[362:7] Found pattern:[362:7->364:5]
posCursor:[362:8] posNoWhite:[362:7] Found pattern:[362:7->362:8]
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

From the location, this could be the pattern T.

Ppat_construct T:[362:7->362:8]
Completable: Cpath Value[T]
[{
"label": "That",
"kind": 4,
"tags": [],
"detail": "That\n\ntype v = This | That",
"documentation": null
}, {
"label": "This",
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This and That are found as expected.

"kind": 4,
"tags": [],
"detail": "This\n\ntype v = This | That",
"documentation": null
}, {
"label": "TableclothMap",
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is a module starting with T which happens to be in scope.
This is accurate, as the user might be in the process of writing ThatSpecificModule.SomeConstructor.

Choose a reason for hiding this comment

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

I disagree with this, except in the rare case where the type of the switch variable is not known (because it might be used to disambiguate, as you suggested). That should only happen once, or in many cases never.

My understanding is that once the type is known the compiler no longer needs disambiguation to find constructors. At that point seeing all scope modules in the autocomplete list is just noise.

https://rescript-lang.org/try?code=LYewJgrgNgpgBAeQC4AsYCc4F44G8BQccSAngA7wBu2iAdvAD5wAqA7iHE8yujDIXFhI4AMxqUAhlAjwsAPgFEAzqwCWSAMYo4k6fAJEiAeiNxaHMKqUTgAI1UBzCBKSqQtRZzqy5cAIyeXOzYvgBMgSw8fCFwAMyeAL74SfhCouJSMiECKupaOpn6AiZwSqq0DrBwltZ2js6u7gJMyGjoAHQI9DEBREEc8nDhfZG8PnECSUA

I'm about to start looking at how to remove modules from the autocomplete list in this scenario, but now I realise it was intentional... can we discuss whether removing them is a good idea?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think you're interested in type contexts, here: #494
Not this PR.

Choose a reason for hiding this comment

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

I am, but then I found this PR and it looked like completion in switch statements already included all the valid constructors.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is an ongoing process. Not everything is at the level it could be.
In the process, some techniques have been used to aid autocompletion where the alternative would be to get nothing.

"kind": 9,
"tags": [],
"detail": "file module",
"documentation": null
}, {
"label": "TypeDefinition",
"kind": 9,
"tags": [],
"detail": "file module",
"documentation": null
}]

Complete tests/src/Completion.res 373:21
posCursor:[373:21] posNoWhite:[373:20] Found expr:[371:8->376:3]
posCursor:[373:21] posNoWhite:[373:20] Found expr:[372:2->376:3]
posCursor:[373:21] posNoWhite:[373:20] Found pattern:[373:7->375:5]
posCursor:[373:21] posNoWhite:[373:20] Found pattern:[373:7->373:21]
Ppat_construct AndThatOther.T:[373:7->373:21]
Completable: Cpath Value[AndThatOther, T]
[{
"label": "ThatOther",
"kind": 4,
"tags": [],
"detail": "ThatOther\n\ntype v = And | ThatOther",
"documentation": null
}]

2 changes: 2 additions & 0 deletions analysis/tests/src/expected/Jsx.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ Completable: Cjsx([WithChildren], n, [n])
}]

Complete tests/src/Jsx.res 94:18
posCursor:[94:18] posNoWhite:[94:17] Found pattern:[94:7->94:18]
posCursor:[94:18] posNoWhite:[94:17] Found type:[94:11->94:18]
Ptyp_constr React.e:[94:11->94:18]
Completable: Cpath Type[React, e]
Expand All @@ -288,6 +289,7 @@ Completable: Cpath Type[React, e]
}]

Complete tests/src/Jsx.res 96:20
posCursor:[96:20] posNoWhite:[96:19] Found pattern:[96:7->99:6]
posCursor:[96:20] posNoWhite:[96:19] Found type:[96:11->99:6]
Ptyp_constr ReactDOMR:[96:11->99:6]
Completable: Cpath Type[ReactDOMR]
Expand Down