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

Exotic identifiers #710

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion analysis/src/CompletionBackEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,10 @@ let rec completeTypedValue (t : SharedTypes.completionType) ~env ~full ~prefix
|> List.filter (fun (field : field) ->
List.mem field.fname.txt seenFields = false)
|> List.map (fun (field : field) ->
Completion.create field.fname.txt
let fname =
PrintType.printIdentLike ~allowUident:false field.fname.txt
in
Completion.create fname
Comment on lines +1093 to +1096
Copy link
Collaborator

Choose a reason for hiding this comment

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

One idea is to not use the name field for this, but instead the insertText field. That'll make the name appear normal in the completion list, but it's the escaped identifier that'll be insterted. What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

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

We can also consider whether this should be done inside of Completion.create directly. Probably not though, as there are quite a few instances where it shouldn't be escaped even when there are exotic characters in there (like with variant payloads, Some(whatver)).

~kind:(Field (field, typeExpr |> Shared.typeToString))
~env)
|> filterItems ~prefix
Expand Down Expand Up @@ -1214,6 +1217,7 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover
| Cjsx ([id], prefix, identsSeen) when String.uncapitalize_ascii id = id ->
(* Lowercase JSX tag means builtin *)
let mkLabel (name, typString) =
let name = PrintType.printIdentLike ~allowUident:false name in
Completion.create name ~kind:(Label typString) ~env
in
let keyLabels =
Expand All @@ -1230,6 +1234,7 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover
CompletionJsx.getJsxLabels ~componentPath ~findTypeOfValue ~package
in
let mkLabel_ name typString =
let name = PrintType.printIdentLike ~allowUident:false name in
Completion.create name ~kind:(Label typString) ~env
in
let mkLabel (name, typ, _env) =
Expand Down Expand Up @@ -1286,6 +1291,7 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover
| None -> []
in
let mkLabel (name, typ) =
let name = PrintType.printIdentLike ~allowUident:false name in
Completion.create name ~kind:(Label (typ |> Shared.typeToString)) ~env
in
labels
Expand Down
5 changes: 4 additions & 1 deletion analysis/src/Hover.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ let showModuleTopLevel ~docstring ~isType ~name (topLevel : Module.item list) =
" " ^ (decl |> Shared.declToString ~recStatus item.name)
| Module _ -> " module " ^ item.name
| Value typ ->
" let " ^ item.name ^ ": " ^ (typ |> Shared.typeToString))
" let "
^ PrintType.printIdentLike ~allowUident:false item.name
^ ": "
^ (typ |> Shared.typeToString))
(* TODO indent *)
|> String.concat "\n"
in
Expand Down
4 changes: 4 additions & 0 deletions analysis/src/PrintType.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ let printDecl ?printNameAsIs ~recStatus name decl =
Res_doc.toString ~width:60
(Res_outcome_printer.printOutSigItemDoc ?printNameAsIs
(Printtyp.tree_of_type_declaration (Ident.create name) decl recStatus))

let printIdentLike ~allowUident name =
Res_doc.toString ~width:60
(Res_outcome_printer.printIdentLike ~allowUident name)
8 changes: 6 additions & 2 deletions analysis/src/SharedTypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,12 @@ module Completable = struct
^ (match argumentLabel with
| Unlabelled {argumentPosition} ->
"$" ^ string_of_int argumentPosition
| Labelled name -> "~" ^ name
| Optional name -> "~" ^ name ^ "=?")
| Labelled name ->
let name = PrintType.printIdentLike ~allowUident:false name in
"~" ^ name
| Optional name ->
let name = PrintType.printIdentLike ~allowUident:false name in
"~" ^ name ^ "= ?")
^ ")"
| CJsxPropValue {pathToComponent; propName} ->
"CJsxPropValue " ^ (pathToComponent |> list) ^ " " ^ propName
Expand Down
40 changes: 40 additions & 0 deletions analysis/tests/src/ExoticIdentifiers.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module X = {
// ^hov
let \"Foo" = "foo"
}

// let foo = X.
// ^com

module type Y = {
// ^hov
let \"Foo": string
}

type x = {\"Foo": string}
// ^hov

let f = (x: x) => {
// let {} = x
// ^com
ignore(x)
}

let g = (~\"Foo") => \"Foo"
// ^hov

// g(~)
// ^com

module C = {
// ^hov
@react.component
let make = (~\"Foo": option<string>=?) =>
switch \"Foo" {
| Some(foo) => React.string(foo)
| None => React.null
}
}

let _ = <C />
// ^com
71 changes: 71 additions & 0 deletions analysis/tests/src/expected/ExoticIdentifiers.res.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
Hover src/ExoticIdentifiers.res 0:7
{"contents": {"kind": "markdown", "value": "```rescript\nmodule X: {\n let \\\"Foo\": string\n}\n```"}}

Complete src/ExoticIdentifiers.res 5:15
posCursor:[5:15] posNoWhite:[5:14] Found expr:[5:13->5:15]
Pexp_ident X.:[5:13->5:15]
Completable: Cpath Value[X, ""]
[{
"label": "Foo",
"kind": 12,
"tags": [],
"detail": "string",
"documentation": null
}]

Hover src/ExoticIdentifiers.res 8:12
{"contents": {"kind": "markdown", "value": "```rescript\nmodule type Y = {\n let \\\"Foo\": string\n}\n```"}}

Hover src/ExoticIdentifiers.res 13:5
{"contents": {"kind": "markdown", "value": "```rescript\ntype x = {\\\"Foo\": string}\n```"}}

Complete src/ExoticIdentifiers.res 17:10
posCursor:[17:10] posNoWhite:[17:9] Found expr:[16:8->20:1]
posCursor:[17:10] posNoWhite:[17:9] Found expr:[17:5->19:11]
posCursor:[17:10] posNoWhite:[17:9] Found pattern:[17:9->17:11]
Completable: Cpattern Value[x]->recordBody
[{
"label": "\\\"Foo\"",
"kind": 5,
"tags": [],
"detail": "\\\"Foo\": string\n\nx",
"documentation": null
}]

Hover src/ExoticIdentifiers.res 22:4
{"contents": {"kind": "markdown", "value": "```rescript\n(~Foo: 'a) => 'a\n```"}}

Complete src/ExoticIdentifiers.res 25:6
posCursor:[25:6] posNoWhite:[25:5] Found expr:[25:3->25:7]
Pexp_apply ...[25:3->25:4] ()
Completable: CnamedArg(Value[g], "", [])
Found type for function (~Foo: 'a) => 'a
[{
"label": "\\\"Foo\"",
"kind": 4,
"tags": [],
"detail": "'a",
"documentation": null
}]

Hover src/ExoticIdentifiers.res 28:7
{"contents": {"kind": "markdown", "value": "```rescript\nmodule C: {\n let makeProps: (\n ~Foo: string=?,\n ~key: string=?,\n unit,\n) => {\"Foo\": option<string>}\n let make: {\"Foo\": option<string>} => React.element\n}\n```"}}

Complete src/ExoticIdentifiers.res 38:11
posCursor:[38:11] posNoWhite:[38:9] Found expr:[38:9->38:13]
JSX <C:[38:9->38:10] > _children:38:11
Completable: Cjsx([C], "", [])
[{
"label": "\\\"Foo\"",
"kind": 4,
"tags": [],
"detail": "option<string>",
"documentation": null
}, {
"label": "key",
"kind": 4,
"tags": [],
"detail": "string",
"documentation": null
}]

2 changes: 2 additions & 0 deletions analysis/vendor/res_outcome_printer/res_outcome_printer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ val parenthesized_ident : string -> bool [@@live]
val setup : unit lazy_t [@@live]

(* Needed for e.g. the playground to print typedtree data *)
val printIdentLike : allowUident:bool -> string -> Res_doc.t

val printOutTypeDoc : Outcometree.out_type -> Res_doc.t [@@live]
val printOutSigItemDoc :
?printNameAsIs:bool -> Outcometree.out_sig_item -> Res_doc.t
Expand Down