Skip to content

enable completions for handwritten JSX components #720

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

Merged
merged 1 commit into from
Feb 1, 2023
Merged
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
13 changes: 13 additions & 0 deletions analysis/src/CompletionJsx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,19 @@ let getJsxLabels ~componentPath ~findTypeOfValue ~package =
&& Path.last path = "props" ->
(* JSX V4 external or interface *)
getFieldsV4 ~path ~typeArgs
| Tarrow (Nolabel, typ, _, _) -> (
(* Component without the JSX PPX, like a make fn taking a hand-written
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should one check anything about the return type? Or can it be anything?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We could check the return type for sure but I'm unsure if it really matters that much. Strictly though it needs to be React.element, or whatever JSX element is configured (not sure if it can be configured now, but it'll be possible later). For this to error, you'd need to use a JSX component with a make function in a module that takes a type named props, and return something else then React.element (which will error in compilation anyway).

I say we go without it for this case, and then fix it if need be?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sounds good

type props. *)
let rec digToConstr typ =
match typ.Types.desc with
| Tlink t1 | Tsubst t1 | Tpoly (t1, []) -> digToConstr t1
| Tconstr (path, typeArgs, _) when Path.last path = "props" ->
Some (path, typeArgs)
| _ -> None
in
match digToConstr typ with
| None -> []
| Some (path, typeArgs) -> getFieldsV4 ~path ~typeArgs)
| _ -> []
in
typ |> getLabels
Expand Down
12 changes: 12 additions & 0 deletions analysis/tests/src/CompletionJsx.res
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,15 @@ module SomeComponent = {
</div>
}
}

module CompWithoutJsxPpx = {
type props = {name: string}

let make = ({name}) => {
ignore(name)
React.null
}
}

// <CompWithoutJsxPpx n
// ^com
12 changes: 12 additions & 0 deletions analysis/tests/src/expected/CompletionJsx.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,15 @@ Completable: Cpath Value[someArr]->a <<jsx>>
"documentation": {"kind": "markdown", "value": "Deprecated: `append` is not type-safe. Use `concat` instead.\n\n"}
}]

Complete src/CompletionJsx.res 43:23
posCursor:[43:23] posNoWhite:[43:22] Found expr:[43:4->43:23]
JSX <CompWithoutJsxPpx:[43:4->43:21] n[43:22->43:23]=...[43:22->43:23]> _children:None
Completable: Cjsx([CompWithoutJsxPpx], n, [n])
[{
"label": "name",
"kind": 4,
"tags": [],
"detail": "string",
"documentation": null
}]