Skip to content

Commit

Permalink
Complete tagged template application (#7278)
Browse files Browse the repository at this point in the history
* WIP tagged template completion

* Ensure debug logging is behind flag

* Include completions of alias

* Turn off evenMoreCompletions

* Add support for tagged template + dot in FrontEnd.

* Revert change to pipe

* Yeah this is the revert pipe thing

* Revert other changes and commit test result

* Remove local execution commands

* Remove debug log

* Change sample

* Add changelog entry

* Split up cases in frontend.

* Add example
  • Loading branch information
nojaf authored Feb 6, 2025
1 parent 7b601f2 commit d153a91
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- Fix async context checking for module await. https://github.com/rescript-lang/rescript/pull/7271
- Fix `%external` extension. https://github.com/rescript-lang/rescript/pull/7272
- Fix issue with type environment for unified ops. https://github.com/rescript-lang/rescript/pull/7277
- Fix completion for application with tagged template. https://github.com/rescript-lang/rescript/pull/7278

# 12.0.0-alpha.8

Expand Down
59 changes: 59 additions & 0 deletions analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,65 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor
(* Case foo-> when the parser adds a ghost expression to the rhs
so the apply expression does not include the cursor *)
if setPipeResult ~lhs ~id:"" then setFound ()
(*
A dot completion for a tagged templated application with an expr hole.
Example:
sh`echo "meh"`.
*)
| Pexp_apply
{
funct = {pexp_desc = Pexp_ident {txt = Lident "."; loc = _}};
args =
[
(* sh`echo "meh"` *)
(_, ({pexp_desc = Pexp_apply _} as innerExpr));
(* recovery inserted node *)
(_, {pexp_desc = Pexp_extension ({txt = "rescript.exprhole"}, _)});
];
}
when Res_parsetree_viewer.is_tagged_template_literal innerExpr ->
exprToContextPath innerExpr
|> Option.iter (fun cpath ->
setResult
(Cpath
(CPField
{
contextPath = cpath;
fieldName = "";
posOfDot;
exprLoc = expr.pexp_loc;
}));
setFound ())
(*
A dot completion for a tagged templated application with an ident.
Example:
sh`echo "meh"`.foo
*)
| Pexp_apply
{
funct = {pexp_desc = Pexp_ident {txt = Lident "."; loc = _}};
args =
[
(* sh`echo "meh"` *)
(_, ({pexp_desc = Pexp_apply _} as innerExpr));
(* foo *)
(_, {pexp_desc = Pexp_ident {txt = Lident fieldName}});
];
}
when Res_parsetree_viewer.is_tagged_template_literal innerExpr
&& expr.pexp_loc |> Loc.hasPos ~pos:posBeforeCursor ->
exprToContextPath innerExpr
|> Option.iter (fun cpath ->
setResult
(Cpath
(CPField
{
contextPath = cpath;
fieldName;
posOfDot;
exprLoc = expr.pexp_loc;
}));
setFound ())
| _ -> (
if expr.pexp_loc |> Loc.hasPos ~pos:posNoWhite && !result = None then (
setFound ();
Expand Down
16 changes: 16 additions & 0 deletions tests/analysis_tests/tests/src/CompletionTaggedTemplate.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module M = {
type t

let a = (_t:t) => 4
let b = (_:t) => "c"
let xyz = (_:t, p:int) => p + 1
}

@module("meh") @taggedTemplate
external meh: (array<string>, array<string>) => M.t = "default"

// let x = meh`foo`.
// ^com

// let y = meh`bar`.x
// ^com
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
Complete src/CompletionTaggedTemplate.res 11:20
posCursor:[11:20] posNoWhite:[11:19] Found expr:[11:11->0:-1]
Completable: Cpath Value[meh](Nolabel, Nolabel).""
Package opens Pervasives.JsxModules.place holder
ContextPath Value[meh](Nolabel, Nolabel).""
ContextPath Value[meh](Nolabel, Nolabel)
ContextPath Value[meh]
Path meh
ContextPath Value[meh](Nolabel, Nolabel, Nolabel)->
ContextPath Value[meh](Nolabel, Nolabel, Nolabel)
ContextPath Value[meh]
Path meh
CPPipe pathFromEnv:M found:true
Path M.
[{
"label": "->M.xyz",
"kind": 12,
"tags": [],
"detail": "(t, int) => int",
"documentation": null,
"sortText": "xyz",
"insertText": "->M.xyz",
"additionalTextEdits": [{
"range": {"start": {"line": 11, "character": 19}, "end": {"line": 11, "character": 20}},
"newText": ""
}]
}, {
"label": "->M.b",
"kind": 12,
"tags": [],
"detail": "t => string",
"documentation": null,
"sortText": "b",
"insertText": "->M.b",
"additionalTextEdits": [{
"range": {"start": {"line": 11, "character": 19}, "end": {"line": 11, "character": 20}},
"newText": ""
}]
}, {
"label": "->M.a",
"kind": 12,
"tags": [],
"detail": "t => int",
"documentation": null,
"sortText": "a",
"insertText": "->M.a",
"additionalTextEdits": [{
"range": {"start": {"line": 11, "character": 19}, "end": {"line": 11, "character": 20}},
"newText": ""
}]
}]

Complete src/CompletionTaggedTemplate.res 14:21
posCursor:[14:21] posNoWhite:[14:20] Found expr:[14:11->14:21]
Completable: Cpath Value[meh](Nolabel, Nolabel).x
Package opens Pervasives.JsxModules.place holder
ContextPath Value[meh](Nolabel, Nolabel).x
ContextPath Value[meh](Nolabel, Nolabel)
ContextPath Value[meh]
Path meh
ContextPath Value[meh](Nolabel, Nolabel, Nolabel)->x
ContextPath Value[meh](Nolabel, Nolabel, Nolabel)
ContextPath Value[meh]
Path meh
CPPipe pathFromEnv:M found:true
Path M.x
[{
"label": "->M.xyz",
"kind": 12,
"tags": [],
"detail": "(t, int) => int",
"documentation": null,
"sortText": "xyz",
"insertText": "->M.xyz",
"additionalTextEdits": [{
"range": {"start": {"line": 14, "character": 19}, "end": {"line": 14, "character": 20}},
"newText": ""
}]
}]

1 comment on commit d153a91

@github-actions
Copy link

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Syntax Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: d153a91 Previous: e1b7fb7 Ratio
Parse RedBlackTree.res - time/run 1.3645777733333333 ms 1.2123143266666667 ms 1.13
Parse Napkinscript.res - time/run 42.85270329333333 ms 39.28006235333333 ms 1.09
Parse HeroGraphic.res - time/run 5.763896613333333 ms 5.13472718 ms 1.12

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.