Skip to content

Generic JSX transform completion #919

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 7 commits into from
Feb 11, 2024
Merged
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -5,7 +5,9 @@ examples/*/lib

analysis/tests/lib
analysis/tests/.bsb.lock
analysis/tests/.merlin

analysis/tests-generic-jsx-transform/lib
analysis/tests-generic-jsx-transform/.bsb.lock

tools/node_modules
tools/lib
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
- Relax filter for what local files that come up in from and regular string completion in `@module`. https://github.com/rescript-lang/rescript-vscode/pull/918
- Make from completion trigger for expr hole so we get a nice experience when completing {from: <com>} in `@module`. https://github.com/rescript-lang/rescript-vscode/pull/918
- Latest parser for newest syntax features. https://github.com/rescript-lang/rescript-vscode/pull/917
- Handle completion for DOM/element attributes and attribute values properly when using a generic JSX transform. https://github.com/rescript-lang/rescript-vscode/pull/919

## 1.38.0

6 changes: 5 additions & 1 deletion analysis/Makefile
Original file line number Diff line number Diff line change
@@ -3,16 +3,20 @@ SHELL = /bin/bash
build-tests:
make -C tests build

build-tests-generic-jsx-transform:
make -C tests-generic-jsx-transform build

build-reanalyze:
make -C reanalyze build

build: build-reanalyze build-tests
build: build-reanalyze build-tests build-tests-generic-jsx-transform

dce: build-analysis-binary
opam exec reanalyze.exe -- -dce-cmt _build -suppress vendor

test-analysis-binary:
make -C tests test
make -C tests-generic-jsx-transform test

test-reanalyze:
make -C reanalyze test
36 changes: 26 additions & 10 deletions analysis/src/CompletionBackEnd.ml
Original file line number Diff line number Diff line change
@@ -1010,14 +1010,23 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
| Some (builtinNameToComplete, typ)
when Utils.checkName builtinNameToComplete ~prefix:funNamePrefix
~exact:false ->
let name =
match package.genericJsxModule with
| None -> "React." ^ builtinNameToComplete
| Some g ->
g ^ "." ^ builtinNameToComplete
|> String.split_on_char '.'
|> TypeUtils.removeOpensFromCompletionPath ~rawOpens
~package:full.package
|> String.concat "."
in
[
Completion.createWithSnippet
~name:("React." ^ builtinNameToComplete)
~kind:(Value typ) ~env ~sortText:"A"
Completion.createWithSnippet ~name ~kind:(Value typ) ~env
~sortText:"A"
~docstring:
[
"Turns `" ^ builtinNameToComplete
^ "` into `React.element` so it can be used inside of JSX.";
^ "` into a JSX element so it can be used inside of JSX.";
]
();
]
@@ -1078,7 +1087,7 @@ and getCompletionsForContextPath ~debug ~full ~opens ~rawOpens ~pos ~env ~exact
| Some f -> Some (f.fname.txt, f.typ, env))
| _ -> None
in
["ReactDOM"; "domProps"] |> digToTypeForCompletion
TypeUtils.pathToElementProps package |> digToTypeForCompletion
else
CompletionJsx.getJsxLabels ~componentPath:pathToComponent
~findTypeOfValue ~package
@@ -1692,9 +1701,14 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
(* We always try to look up completion from the actual domProps type first.
This works in JSXv4. For JSXv3, we have a backup hardcoded list of dom
labels we can use for completion. *)
let fromDomProps =
let pathToElementProps = TypeUtils.pathToElementProps package in
if Debug.verbose () then
Printf.printf
"[completing-lowercase-jsx] Attempting to complete from type at %s\n"
(pathToElementProps |> String.concat ".");
let fromElementProps =
match
["ReactDOM"; "domProps"]
pathToElementProps
|> digToRecordFieldsForCompletion ~debug ~package ~opens ~full ~pos ~env
~scope
with
@@ -1713,11 +1727,13 @@ let rec processCompletable ~debug ~full ~scope ~env ~pos ~forHover completable =
else None)
|> List.map mkLabel)
in
match fromDomProps with
| Some domProps -> domProps
match fromElementProps with
| Some elementProps -> elementProps
| None ->
if debug then
Printf.printf "Could not find ReactDOM.domProps to complete from.\n";
Printf.printf
"[completing-lowercase-jsx] could not find element props to complete \
from.\n";
(CompletionJsx.domLabels
|> List.filter (fun (name, _t) ->
Utils.startsWith name prefix
9 changes: 8 additions & 1 deletion analysis/src/CompletionDecorators.ml
Original file line number Diff line number Diff line change
@@ -164,10 +164,17 @@ Example `@raises(Exn)` or `@raises([E1, E2, E3])` for multiple exceptions.

You will need this decorator whenever you want to use a ReScript / React component in ReScript JSX expressions.

Note: The `@react.component` decorator requires the react-jsx config to be set in your `bsconfig.json` to enable the required React transformations.
Note: The `@react.component` decorator requires the `jsx` config to be set in your `rescript.json`/`bsconfig.json` to enable the required React transformations.

[Read more and see examples in the documentation](https://rescript-lang.org/syntax-lookup#react-component-decorator).|};
] );
( "jsx.component",
None,
[
{|The `@jsx.component` decorator is used to annotate functions that are JSX components used with ReScript's [generic JSX transform](https://rescript-lang.org/docs/manual/latest/jsx#generic-jsx-transform-jsx-beyond-react-experimental).

You will need this decorator whenever you want to use a JSX component in ReScript JSX expressions.|};
] );
( "return",
Some "return(${1:nullable})",
[
2 changes: 1 addition & 1 deletion analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
@@ -659,7 +659,7 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor
let value_binding (iterator : Ast_iterator.iterator)
(value_binding : Parsetree.value_binding) =
let oldInJsxContext = !inJsxContext in
if Utils.isReactComponent value_binding then inJsxContext := true;
if Utils.isJsxComponent value_binding then inJsxContext := true;
(match value_binding with
| {pvb_pat = {ppat_desc = Ppat_constraint (_pat, coreType)}; pvb_expr}
when locHasCursor pvb_expr.pexp_loc -> (
11 changes: 11 additions & 0 deletions analysis/src/Packages.ml
Original file line number Diff line number Diff line change
@@ -59,6 +59,16 @@ let newBsPackage ~rootPath =
| (major, _), None when major >= 11 -> Some true
| _, ns -> Option.bind ns Json.bool
in
let genericJsxModule =
let jsxConfig = config |> Json.get "jsx" in
match jsxConfig with
| Some jsxConfig -> (
match jsxConfig |> Json.get "module" with
| Some (String m) when String.lowercase_ascii m <> "react" ->
Some m
| _ -> None)
| None -> None
in
let uncurried = uncurried = Some true in
let sourceDirectories =
FindFiles.getSourceDirectories ~includeDev:true ~baseDir:rootPath
@@ -121,6 +131,7 @@ let newBsPackage ~rootPath =
("Opens from ReScript config file: "
^ (opens |> List.map pathToString |> String.concat " "));
{
genericJsxModule;
suffix;
rescriptVersion;
rootPath;
4 changes: 3 additions & 1 deletion analysis/src/SharedTypes.ml
Original file line number Diff line number Diff line change
@@ -497,6 +497,7 @@ type builtInCompletionModules = {
}

type package = {
genericJsxModule: string option;
suffix: string;
rootPath: filePath;
projectFiles: FileSet.t;
@@ -718,7 +719,8 @@ module Completable = struct
| Cpath cp -> "Cpath " ^ contextPathToString cp
| Cdecorator s -> "Cdecorator(" ^ str s ^ ")"
| CdecoratorPayload (Module s) -> "CdecoratorPayload(module=" ^ s ^ ")"
| CdecoratorPayload (ModuleWithImportAttributes _) -> "CdecoratorPayload(moduleWithImportAttributes)"
| CdecoratorPayload (ModuleWithImportAttributes _) ->
"CdecoratorPayload(moduleWithImportAttributes)"
| CdecoratorPayload (JsxConfig _) -> "JsxConfig"
| CnamedArg (cp, s, sl2) ->
"CnamedArg("
5 changes: 5 additions & 0 deletions analysis/src/TypeUtils.ml
Original file line number Diff line number Diff line change
@@ -1079,3 +1079,8 @@ let removeOpensFromCompletionPath ~rawOpens ~package completionPath =
|> removeRawOpens rawOpens
in
completionPathMinusOpens

let pathToElementProps package =
match package.genericJsxModule with
| None -> ["ReactDOM"; "domProps"]
| Some g -> (g |> String.split_on_char '.') @ ["Elements"; "props"]
4 changes: 2 additions & 2 deletions analysis/src/Utils.ml
Original file line number Diff line number Diff line change
@@ -156,10 +156,10 @@ let rec unwrapIfOption (t : Types.type_expr) =
| Tconstr (Path.Pident {name = "option"}, [unwrappedType], _) -> unwrappedType
| _ -> t

let isReactComponent (vb : Parsetree.value_binding) =
let isJsxComponent (vb : Parsetree.value_binding) =
vb.pvb_attributes
|> List.exists (function
| {Location.txt = "react.component"}, _payload -> true
| {Location.txt = "react.component" | "jsx.component"}, _payload -> true
| _ -> false)

let checkName name ~prefix ~exact =
6 changes: 3 additions & 3 deletions analysis/src/Xform.ml
Original file line number Diff line number Diff line change
@@ -215,9 +215,9 @@ module AddTypeAnnotation = struct
match si.pstr_desc with
| Pstr_value (_recFlag, bindings) ->
let processBinding (vb : Parsetree.value_binding) =
(* Can't add a type annotation to a react component, or the compiler crashes *)
let isReactComponent = Utils.isReactComponent vb in
if not isReactComponent then processPattern vb.pvb_pat;
(* Can't add a type annotation to a jsx component, or the compiler crashes *)
let isJsxComponent = Utils.isJsxComponent vb in
if not isJsxComponent then processPattern vb.pvb_pat;
processFunction vb.pvb_expr
in
bindings |> List.iter (processBinding ~argNum:1);
17 changes: 17 additions & 0 deletions analysis/tests-generic-jsx-transform/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
SHELL = /bin/bash

node_modules/.bin/rescript:
npm install

build: node_modules/.bin/rescript
node_modules/.bin/rescript

test: build
./test.sh

clean:
rm -r node_modules lib

.DEFAULT_GOAL := test

.PHONY: clean test
33 changes: 33 additions & 0 deletions analysis/tests-generic-jsx-transform/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions analysis/tests-generic-jsx-transform/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"scripts": {
"build": "rescript",
"clean": "rescript clean -with-deps"
},
"private": true,
"dependencies": {
"rescript": "11.1.0-rc.2"
}
}
11 changes: 11 additions & 0 deletions analysis/tests-generic-jsx-transform/rescript.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "test-generic-jsx-transform",
"sources": [
{
"dir": "src",
"subdirs": true
}
],
"bsc-flags": ["-w -33-44-8"],
"jsx": { "module": "GenericJsx" }
}
63 changes: 63 additions & 0 deletions analysis/tests-generic-jsx-transform/src/GenericJsx.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* Below is a number of aliases to the common `Jsx` module */
type element = Jsx.element

type component<'props> = Jsx.component<'props>

type componentLike<'props, 'return> = Jsx.componentLike<'props, 'return>

@module("preact")
external jsx: (component<'props>, 'props) => element = "jsx"

@module("preact")
external jsxKeyed: (component<'props>, 'props, ~key: string=?, @ignore unit) => element = "jsx"

@module("preact")
external jsxs: (component<'props>, 'props) => element = "jsxs"

@module("preact")
external jsxsKeyed: (component<'props>, 'props, ~key: string=?, @ignore unit) => element = "jsxs"

/* These identity functions and static values below are optional, but lets
you move things easily to the `element` type. The only required thing to
define though is `array`, which the JSX transform will output. */
external array: array<element> => element = "%identity"
@val external null: element = "null"

external float: float => element = "%identity"
external int: int => element = "%identity"
external string: string => element = "%identity"

/* These are needed for Fragment (<> </>) support */
type fragmentProps = {children?: element}

@module("preact") external jsxFragment: component<fragmentProps> = "Fragment"

/* The Elements module is the equivalent to the ReactDOM module in React. This holds things relevant to _lowercase_ JSX elements. */
module Elements = {
/* Here you can control what props lowercase JSX elements should have.
A base that the React JSX transform uses is provided via JsxDOM.domProps,
but you can make this anything. The editor tooling will support
autocompletion etc for your specific type. */
type props = {
testing?: bool,
test2?: string,
children?: element
}

@module("preact")
external jsx: (string, props) => Jsx.element = "jsx"

@module("preact")
external div: (string, props) => Jsx.element = "jsx"

@module("preact")
external jsxKeyed: (string, props, ~key: string=?, @ignore unit) => Jsx.element = "jsx"

@module("preact")
external jsxs: (string, props) => Jsx.element = "jsxs"

@module("preact")
external jsxsKeyed: (string, props, ~key: string=?, @ignore unit) => Jsx.element = "jsxs"

external someElement: element => option<element> = "%identity"
}
25 changes: 25 additions & 0 deletions analysis/tests-generic-jsx-transform/src/GenericJsxCompletion.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// <div
// ^com

// <div testing={}
// ^com

module SomeComponent = {
@jsx.component
let make = (~someProp) => {
let someString = ""
let someInt = 12
let someArr = [GenericJsx.null]
ignore(someInt)
ignore(someArr)
// someString->st
// ^com
open GenericJsx
<div>
{GenericJsx.string(someProp)}
<div> {GenericJsx.null} </div>
// {someString->st}
// ^com
</div>
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
Complete src/GenericJsxCompletion.res 0:8
posCursor:[0:8] posNoWhite:[0:6] Found expr:[0:4->0:7]
JSX <div:[0:4->0:7] > _children:None
Completable: Cjsx([div], "", [])
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
Path GenericJsx.Elements.props
[{
"label": "testing",
"kind": 4,
"tags": [],
"detail": "bool",
"documentation": null
}, {
"label": "test2",
"kind": 4,
"tags": [],
"detail": "string",
"documentation": null
}, {
"label": "children",
"kind": 4,
"tags": [],
"detail": "element",
"documentation": null
}]

Complete src/GenericJsxCompletion.res 3:17
posCursor:[3:17] posNoWhite:[3:16] Found expr:[3:4->3:18]
JSX <div:[3:4->3:7] testing[3:8->3:15]=...[3:16->3:18]> _children:None
Completable: Cexpression CJsxPropValue [div] testing->recordBody
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
ContextPath CJsxPropValue [div] testing
Path GenericJsx.Elements.props
[{
"label": "true",
"kind": 4,
"tags": [],
"detail": "bool",
"documentation": null
}, {
"label": "false",
"kind": 4,
"tags": [],
"detail": "bool",
"documentation": null
}]

Complete src/GenericJsxCompletion.res 14:21
posCursor:[14:21] posNoWhite:[14:20] Found expr:[8:13->23:3]
posCursor:[14:21] posNoWhite:[14:20] Found expr:[8:14->23:3]
posCursor:[14:21] posNoWhite:[14:20] Found expr:[9:1->22:10]
posCursor:[14:21] posNoWhite:[14:20] Found expr:[10:4->22:10]
posCursor:[14:21] posNoWhite:[14:20] Found expr:[11:4->22:10]
posCursor:[14:21] posNoWhite:[14:20] Found expr:[12:4->22:10]
posCursor:[14:21] posNoWhite:[14:20] Found expr:[13:4->22:10]
posCursor:[14:21] posNoWhite:[14:20] Found expr:[14:7->22:10]
posCursor:[14:21] posNoWhite:[14:20] Found expr:[14:7->14:21]
Completable: Cpath Value[someString]->st <<jsx>>
Package opens Pervasives.JsxModules.place holder
Resolved opens 1 pervasives
ContextPath Value[someString]->st <<jsx>>
ContextPath Value[someString]
Path someString
CPPipe env:GenericJsxCompletion
Path Js.String2.st
[{
"label": "GenericJsx.string",
"kind": 12,
"tags": [],
"detail": "string",
"documentation": {"kind": "markdown", "value": "Turns `string` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {
"label": "Js.String2.startsWith",
"kind": 12,
"tags": [],
"detail": "(t, t) => bool",
"documentation": {"kind": "markdown", "value": "\nES2015: `startsWith(str, substr)` returns `true` if the `str` starts with\n`substr`, `false` otherwise.\n\nSee [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith)\non MDN.\n\n## Examples\n\n```rescript\nJs.String2.startsWith(\"ReScript\", \"Re\") == true\nJs.String2.startsWith(\"ReScript\", \"\") == true\nJs.String2.startsWith(\"JavaScript\", \"Re\") == false\n```\n"}
}, {
"label": "Js.String2.startsWithFrom",
"kind": 12,
"tags": [],
"detail": "(t, t, int) => bool",
"documentation": {"kind": "markdown", "value": "\nES2015: `startsWithFrom(str, substr, n)` returns `true` if the `str` starts\nwith `substr` starting at position `n`, false otherwise. If `n` is negative,\nthe search starts at the beginning of `str`.\n\nSee [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith)\non MDN.\n\n## Examples\n\n```rescript\nJs.String2.startsWithFrom(\"ReScript\", \"Scri\", 2) == true\nJs.String2.startsWithFrom(\"ReScript\", \"\", 2) == true\nJs.String2.startsWithFrom(\"JavaScript\", \"Scri\", 2) == false\n```\n"}
}]

Complete src/GenericJsxCompletion.res 20:24
posCursor:[20:24] posNoWhite:[20:23] Found expr:[8:13->23:3]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[8:14->23:3]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[9:1->22:10]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[10:4->22:10]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[11:4->22:10]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[12:4->22:10]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[13:4->22:10]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[16:1->22:10]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[17:5->22:10]
JSX <div:[17:5->17:8] > _children:17:8
posCursor:[20:24] posNoWhite:[20:23] Found expr:[17:8->22:4]
Pexp_construct :::[18:7->22:4] [18:7->22:4]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[18:7->22:4]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[19:7->22:4]
Pexp_construct :::[19:7->22:4] [19:7->22:4]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[19:7->22:4]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[20:10->22:4]
Pexp_construct :::[20:10->22:4] [20:10->22:4]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[20:10->22:4]
posCursor:[20:24] posNoWhite:[20:23] Found expr:[20:10->20:24]
Completable: Cpath Value[someString]->st <<jsx>>
Raw opens: 1 GenericJsx.place holder
Package opens Pervasives.JsxModules.place holder
Resolved opens 2 pervasives GenericJsx.res
ContextPath Value[someString]->st <<jsx>>
ContextPath Value[someString]
Path someString
CPPipe env:GenericJsxCompletion
Path Js.String2.st
[{
"label": "string",
"kind": 12,
"tags": [],
"detail": "string",
"documentation": {"kind": "markdown", "value": "Turns `string` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {
"label": "Js.String2.startsWith",
"kind": 12,
"tags": [],
"detail": "(t, t) => bool",
"documentation": {"kind": "markdown", "value": "\nES2015: `startsWith(str, substr)` returns `true` if the `str` starts with\n`substr`, `false` otherwise.\n\nSee [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith)\non MDN.\n\n## Examples\n\n```rescript\nJs.String2.startsWith(\"ReScript\", \"Re\") == true\nJs.String2.startsWith(\"ReScript\", \"\") == true\nJs.String2.startsWith(\"JavaScript\", \"Re\") == false\n```\n"}
}, {
"label": "Js.String2.startsWithFrom",
"kind": 12,
"tags": [],
"detail": "(t, t, int) => bool",
"documentation": {"kind": "markdown", "value": "\nES2015: `startsWithFrom(str, substr, n)` returns `true` if the `str` starts\nwith `substr` starting at position `n`, false otherwise. If `n` is negative,\nthe search starts at the beginning of `str`.\n\nSee [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith)\non MDN.\n\n## Examples\n\n```rescript\nJs.String2.startsWithFrom(\"ReScript\", \"Scri\", 2) == true\nJs.String2.startsWithFrom(\"ReScript\", \"\", 2) == true\nJs.String2.startsWithFrom(\"JavaScript\", \"Scri\", 2) == false\n```\n"}
}]

21 changes: 21 additions & 0 deletions analysis/tests-generic-jsx-transform/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
for file in src/*.res; do
output="$(dirname $file)/expected/$(basename $file).txt"
../../rescript-editor-analysis.exe test $file &> $output
# CI. We use LF, and the CI OCaml fork prints CRLF. Convert.
if [ "$RUNNER_OS" == "Windows" ]; then
perl -pi -e 's/\r\n/\n/g' -- $output
fi
done

warningYellow='\033[0;33m'
successGreen='\033[0;32m'
reset='\033[0m'

diff=$(git ls-files --modified src/expected)
if [[ $diff = "" ]]; then
printf "${successGreen}✅ No unstaged tests difference.${reset}\n"
else
printf "${warningYellow}⚠️ There are unstaged differences in tests/! Did you break a test?\n${diff}\n${reset}"
git --no-pager diff src/expected
exit 1
fi
14 changes: 7 additions & 7 deletions analysis/tests/package-lock.json
2 changes: 1 addition & 1 deletion analysis/tests/package.json
Original file line number Diff line number Diff line change
@@ -8,6 +8,6 @@
"@rescript/react": "0.12.0"
},
"dependencies": {
"rescript": "11.0.1"
"rescript": "11.1.0-rc.2"
}
}
4 changes: 2 additions & 2 deletions analysis/tests/src/expected/Completion.res.txt
Original file line number Diff line number Diff line change
@@ -553,7 +553,7 @@ Resolved opens 1 pervasives
"kind": 4,
"tags": [],
"detail": "",
"documentation": {"kind": "markdown", "value": "The `@react.component` decorator is used to annotate functions that are RescriptReact components.\n\nYou will need this decorator whenever you want to use a ReScript / React component in ReScript JSX expressions.\n\nNote: The `@react.component` decorator requires the react-jsx config to be set in your `bsconfig.json` to enable the required React transformations.\n\n[Read more and see examples in the documentation](https://rescript-lang.org/syntax-lookup#react-component-decorator)."},
"documentation": {"kind": "markdown", "value": "The `@react.component` decorator is used to annotate functions that are RescriptReact components.\n\nYou will need this decorator whenever you want to use a ReScript / React component in ReScript JSX expressions.\n\nNote: The `@react.component` decorator requires the `jsx` config to be set in your `rescript.json`/`bsconfig.json` to enable the required React transformations.\n\n[Read more and see examples in the documentation](https://rescript-lang.org/syntax-lookup#react-component-decorator)."},
"insertTextFormat": 2
}]

@@ -569,7 +569,7 @@ Resolved opens 1 pervasives
"kind": 4,
"tags": [],
"detail": "",
"documentation": {"kind": "markdown", "value": "The `@react.component` decorator is used to annotate functions that are RescriptReact components.\n\nYou will need this decorator whenever you want to use a ReScript / React component in ReScript JSX expressions.\n\nNote: The `@react.component` decorator requires the react-jsx config to be set in your `bsconfig.json` to enable the required React transformations.\n\n[Read more and see examples in the documentation](https://rescript-lang.org/syntax-lookup#react-component-decorator)."},
"documentation": {"kind": "markdown", "value": "The `@react.component` decorator is used to annotate functions that are RescriptReact components.\n\nYou will need this decorator whenever you want to use a ReScript / React component in ReScript JSX expressions.\n\nNote: The `@react.component` decorator requires the `jsx` config to be set in your `rescript.json`/`bsconfig.json` to enable the required React transformations.\n\n[Read more and see examples in the documentation](https://rescript-lang.org/syntax-lookup#react-component-decorator)."},
"insertTextFormat": 2
}]

14 changes: 7 additions & 7 deletions analysis/tests/src/expected/CompletionJsx.res.txt
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ Path Js.String2.st
"kind": 12,
"tags": [],
"detail": "string",
"documentation": {"kind": "markdown", "value": "Turns `string` into `React.element` so it can be used inside of JSX."},
"documentation": {"kind": "markdown", "value": "Turns `string` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {
@@ -93,7 +93,7 @@ Path Js.String2.st
"kind": 12,
"tags": [],
"detail": "string",
"documentation": {"kind": "markdown", "value": "Turns `string` into `React.element` so it can be used inside of JSX."},
"documentation": {"kind": "markdown", "value": "Turns `string` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {
@@ -141,7 +141,7 @@ Path Js.String2.st
"kind": 12,
"tags": [],
"detail": "string",
"documentation": {"kind": "markdown", "value": "Turns `string` into `React.element` so it can be used inside of JSX."},
"documentation": {"kind": "markdown", "value": "Turns `string` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {
@@ -191,7 +191,7 @@ Path Js.String2.st
"kind": 12,
"tags": [],
"detail": "string",
"documentation": {"kind": "markdown", "value": "Turns `string` into `React.element` so it can be used inside of JSX."},
"documentation": {"kind": "markdown", "value": "Turns `string` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {
@@ -240,7 +240,7 @@ Path Belt.Int.
"kind": 12,
"tags": [],
"detail": "int",
"documentation": {"kind": "markdown", "value": "Turns `int` into `React.element` so it can be used inside of JSX."},
"documentation": {"kind": "markdown", "value": "Turns `int` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {
@@ -324,7 +324,7 @@ Path Belt.Int.
"kind": 12,
"tags": [],
"detail": "int",
"documentation": {"kind": "markdown", "value": "Turns `int` into `React.element` so it can be used inside of JSX."},
"documentation": {"kind": "markdown", "value": "Turns `int` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {
@@ -409,7 +409,7 @@ Path Js.Array2.a
"kind": 12,
"tags": [],
"detail": "array<React.element>",
"documentation": {"kind": "markdown", "value": "Turns `array` into `React.element` so it can be used inside of JSX."},
"documentation": {"kind": "markdown", "value": "Turns `array` into a JSX element so it can be used inside of JSX."},
"sortText": "A",
"insertTextFormat": 2
}, {