Skip to content

Commit

Permalink
In Jsx autocomplete, don't list props already used.
Browse files Browse the repository at this point in the history
Fixes #175.
  • Loading branch information
cristianoc committed Apr 28, 2021
1 parent e67ed97 commit c59532e
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## master
- Fix issue jumping to variables defined in complex patterns.
- In Jsx autocomplete, don't suggest props already assigned.

## beta 2

Expand Down
5 changes: 3 additions & 2 deletions analysis/src/NewCompletions.ml
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ let mkItem ~name ~kind ~detail ~deprecated ~docstring =
let processCompletable ~findItems ~package ~rawOpens
(completable : PartialParser.completable) =
match completable with
| Cjsx (componentPath, prefix) ->
| Cjsx (componentPath, prefix, identsSeen) ->
let items = findItems ~exact:true (componentPath @ ["make"]) in
let labels =
match items with
Expand Down Expand Up @@ -473,7 +473,8 @@ let processCompletable ~findItems ~package ~rawOpens
else
keyLabel
:: (labels
|> List.filter (fun (name, _t) -> Utils.startsWith name prefix)
|> List.filter (fun (name, _t) ->
Utils.startsWith name prefix && not (List.mem name identsSeen))
|> List.map mkLabel)
| Cpath parts ->
let items = parts |> findItems ~exact:false in
Expand Down
50 changes: 28 additions & 22 deletions analysis/src/PartialParser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,57 +57,60 @@ let findCallFromArgument text offset =
(* arg ::= id | id = [?] val *)
(* val ::= id | "abc" | 42 | {...} | (...) | [...] *)
let findJsxContext text offset =
let rec loop i =
let rec loop identsSeen i =
let i = skipWhite text i in
if i > 0 then
match text.[i] with
| '}' ->
let i1 = findBackSkippingCommentsAndStrings text '{' '}' (i - 1) 0 in
if i1 > 0 then beforeValue i1 else None
if i1 > 0 then beforeValue identsSeen i1 else None
| ')' ->
let i1 = findBackSkippingCommentsAndStrings text '(' ')' (i - 1) 0 in
if i1 > 0 then beforeValue i1 else None
if i1 > 0 then beforeValue identsSeen i1 else None
| ']' ->
let i1 = findBackSkippingCommentsAndStrings text '[' ']' (i - 1) 0 in
if i1 > 0 then beforeValue i1 else None
if i1 > 0 then beforeValue identsSeen i1 else None
| '"' ->
let i1 = findBack text '"' (i - 1) in
if i1 > 0 then beforeValue i1 else None
if i1 > 0 then beforeValue identsSeen i1 else None
| _ ->
let i1 = startOfLident text i in
let ident = String.sub text i1 (i - i1 + 1) in
if i1 >= 1 && ident <> "" then
match ident.[0] with
| 'A' .. 'Z' when i1 >= 1 && text.[i1 - 1] = '<' -> Some ident
| _ -> beforeIdent (i1 - 1)
| 'A' .. 'Z' when i1 >= 1 && text.[i1 - 1] = '<' ->
Some (ident, identsSeen)
| _ -> beforeIdent identsSeen (i1 - 1)
else None
else None
and beforeIdent i =
and beforeIdent identsSeen i =
let i = skipWhite text i in
if i > 0 then
match text.[i] with
| '?' -> fromEquals (i - 1)
| '=' -> fromEquals i
| _ -> loop (i - 1)
| '?' -> fromEquals identsSeen (i - 1)
| '=' -> fromEquals identsSeen i
| _ -> loop identsSeen (i - 1)
else None
and beforeValue i =
and beforeValue identsSeen i =
let i = skipWhite text i in
if i > 0 then
match text.[i] with '?' -> fromEquals (i - 1) | _ -> fromEquals i
match text.[i] with
| '?' -> fromEquals identsSeen (i - 1)
| _ -> fromEquals identsSeen i
else None
and fromEquals i =
and fromEquals identsSeen i =
let i = skipWhite text i in
if i > 0 then
match text.[i] with
| '=' -> (
let i = skipWhite text (i - 1) in
let i1 = startOfLident text i in
let ident = String.sub text i1 (i - i1 + 1) in
match ident with "" -> None | _ -> loop (i1 - 1))
match ident with "" -> None | _ -> loop (ident :: identsSeen) (i1 - 1))
| _ -> None
else None
in
loop offset
loop [] offset

type pipe = PipeId of string | PipeArray | PipeString

Expand All @@ -116,8 +119,8 @@ type completable =
| Clabel of string list * string
(** e.g. (["M", "foo"], "label") for M.foo(...~label...) *)
| Cpath of string list (** e.g. ["M", "foo"] for M.foo *)
| Cjsx of string list * string
(** E.g. (["M", "Comp"], "id") for <M.Comp ... id *)
| Cjsx of string list * string * string list
(** E.g. (["M", "Comp"], "id", ["id1", "id2"]) for <M.Comp id1=... id2=... ... id *)
| Cpipe of pipe * string (** E.g. ("x", "foo") for "x->foo" *)

let isLowercaseIdent id =
Expand All @@ -140,8 +143,8 @@ let findCompletable text offset =
| [id] when String.lowercase_ascii id = id -> (
match findJsxContext text (offset - len - 1) with
| None -> Cpath parts
| Some componentName ->
Cjsx (Str.split (Str.regexp_string ".") componentName, id))
| Some (componentName, identsSeen) ->
Cjsx (Str.split (Str.regexp_string ".") componentName, id, identsSeen))
| _ -> Cpath parts
in
let mkPipe off partialName =
Expand Down Expand Up @@ -179,8 +182,11 @@ let findCompletable text offset =
(* autocomplete with no id: check if inside JSX *)
match findJsxContext text (offset - 1) with
| None -> None
| Some componentName ->
Some (Cjsx (Str.split (Str.regexp_string ".") componentName, "")))
| Some (componentName, identsSeen) ->
Some
(Cjsx
(Str.split (Str.regexp_string ".") componentName, "", identsSeen))
)
| _ -> if i = offset - 1 then None else Some (mkPath (suffix i))
in
if offset > String.length text || offset = 0 then None else loop (offset - 1)
Expand Down
1 change: 1 addition & 0 deletions analysis/tests/.bsb.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
81015
6 changes: 0 additions & 6 deletions analysis/tests/src/expected/Jsx.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ Complete tests/src/Jsx.res 7:2
"tags": [],
"detail": "string",
"documentation": null
}, {
"label": "second",
"kind": 4,
"tags": [],
"detail": "option<string>",
"documentation": null
}, {
"label": "first",
"kind": 4,
Expand Down

0 comments on commit c59532e

Please sign in to comment.