Skip to content

Commit

Permalink
Completion for import attributes in @module (#913)
Browse files Browse the repository at this point in the history
* add completion for import attributes in @module

* changelog
  • Loading branch information
zth authored Feb 7, 2024
1 parent 9c083c2 commit bb44aa7
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

#### :nail_care: Polish

Enhance decorator completion. https://github.com/rescript-lang/rescript-vscode/pull/908
- Enhance decorator completion. https://github.com/rescript-lang/rescript-vscode/pull/908
- Completion for import attributes in `@module`. https://github.com/rescript-lang/rescript-vscode/pull/913

## 1.38.0

Expand Down
43 changes: 43 additions & 0 deletions analysis/src/CompletionBackEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,49 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
typ
|> completeTypedValue ?typeArgContext ~rawOpens ~mode:Expression ~full
~prefix ~completionContext)
| CdecoratorPayload (ModuleWithImportAttributes {prefix; nested}) -> (
let mkField ~name ~primitive =
{
stamp = -1;
fname = {loc = Location.none; txt = name};
optional = true;
typ = Ctype.newconstr (Path.Pident (Ident.create primitive)) [];
docstring = [];
deprecated = None;
}
in
let importAttributesConfig : completionType =
Trecord
{
env;
definition = `NameOnly "importAttributesConfig";
fields = [mkField ~name:"type_" ~primitive:"string"];
}
in
let rootConfig : completionType =
Trecord
{
env;
definition = `NameOnly "moduleConfig";
fields =
[
mkField ~name:"from" ~primitive:"string";
mkField ~name:"with" ~primitive:"string";
];
}
in
let nested, typ =
match nested with
| NFollowRecordField {fieldName = "with"} :: rest ->
(rest, importAttributesConfig)
| _ -> (nested, rootConfig)
in
match typ |> TypeUtils.resolveNested ~env ~full ~nested with
| None -> []
| Some (typ, _env, completionContext, typeArgContext) ->
typ
|> completeTypedValue ?typeArgContext ~rawOpens ~mode:Expression ~full
~prefix ~completionContext)
| CdecoratorPayload (Module prefix) ->
let packageJsonPath =
Utils.findPackageJson (full.package.rootPath |> Uri.fromPath)
Expand Down
42 changes: 42 additions & 0 deletions analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,48 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor
if Debug.verbose () then
print_endline "[decoratorCompletion] Found @module";
setResult (Completable.CdecoratorPayload (Module s))
| PStr
[
{
pstr_desc =
Pstr_eval
( {
pexp_desc =
Pexp_record
( ( {txt = Lident "from"},
{
pexp_loc;
pexp_desc =
Pexp_constant (Pconst_string (s, _));
} )
:: _,
_ );
},
_ );
};
]
when locHasCursor pexp_loc ->
if Debug.verbose () then
print_endline
"[decoratorCompletion] Found @module with import attributes and \
cursor on \"from\"";
setResult (Completable.CdecoratorPayload (Module s))
| PStr [{pstr_desc = Pstr_eval (expr, _)}] -> (
if Debug.verbose () then
print_endline
"[decoratorCompletion] Found @module with non-string payload";
match
CompletionExpressions.traverseExpr expr ~exprPath:[]
~pos:posBeforeCursor ~firstCharBeforeCursorNoWhite
with
| None -> ()
| Some (prefix, nested) ->
if Debug.verbose () then
print_endline "[decoratorCompletion] Found @module record path";
setResult
(Completable.CdecoratorPayload
(ModuleWithImportAttributes {nested = List.rev nested; prefix}))
)
| _ -> ()
else if id.txt = "jsxConfig" then
match payload with
Expand Down
2 changes: 2 additions & 0 deletions analysis/src/SharedTypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ module Completable = struct

type decoratorPayload =
| Module of string
| ModuleWithImportAttributes of {nested: nestedPath list; prefix: string}
| JsxConfig of {nested: nestedPath list; prefix: string}

type t =
Expand Down Expand Up @@ -717,6 +718,7 @@ module Completable = struct
| Cpath cp -> "Cpath " ^ contextPathToString cp
| Cdecorator s -> "Cdecorator(" ^ str s ^ ")"
| CdecoratorPayload (Module s) -> "CdecoratorPayload(module=" ^ s ^ ")"
| CdecoratorPayload (ModuleWithImportAttributes _) -> "CdecoratorPayload(moduleWithImportAttributes)"
| CdecoratorPayload (JsxConfig _) -> "JsxConfig"
| CnamedArg (cp, s, sl2) ->
"CnamedArg("
Expand Down
12 changes: 12 additions & 0 deletions analysis/tests/src/CompletionAttributes.res
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,15 @@
// @@jsxConfig({module_: "", })
// ^com

// @module({}) external doStuff: t = "default"
// ^com

// @module({with: }) external doStuff: t = "default"
// ^com

// @module({with: {}}) external doStuff: t = "default"
// ^com

// @module({from: "" }) external doStuff: t = "default"
// ^com

67 changes: 67 additions & 0 deletions analysis/tests/src/expected/CompletionAttributes.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,70 @@ Resolved opens 1 pervasives
"documentation": null
}]

Complete src/CompletionAttributes.res 21:12
XXX Not found!
Completable: CdecoratorPayload(moduleWithImportAttributes)
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
[{
"label": "from",
"kind": 5,
"tags": [],
"detail": "from?: string\n\ntype moduleConfig = {from: string, with: string}",
"documentation": null
}, {
"label": "with",
"kind": 5,
"tags": [],
"detail": "with?: string\n\ntype moduleConfig = {from: string, with: string}",
"documentation": null
}]

Complete src/CompletionAttributes.res 24:17
XXX Not found!
Completable: CdecoratorPayload(moduleWithImportAttributes)
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
[{
"label": "{}",
"kind": 12,
"tags": [],
"detail": "type importAttributesConfig = {type_: string}",
"documentation": null,
"sortText": "A",
"insertText": "{$0}",
"insertTextFormat": 2
}]

Complete src/CompletionAttributes.res 27:19
XXX Not found!
Completable: CdecoratorPayload(moduleWithImportAttributes)
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
[{
"label": "type_",
"kind": 5,
"tags": [],
"detail": "type_?: string\n\ntype importAttributesConfig = {type_: string}",
"documentation": null
}]

Complete src/CompletionAttributes.res 30:19
XXX Not found!
Completable: CdecoratorPayload(module=)
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
[{
"label": "@rescript/react",
"kind": 4,
"tags": [],
"detail": "Package",
"documentation": null
}, {
"label": "./tst.js",
"kind": 4,
"tags": [],
"detail": "Local file",
"documentation": null
}]

0 comments on commit bb44aa7

Please sign in to comment.