Skip to content

Commit

Permalink
Merge branch 'master' into 2.0.0-patches
Browse files Browse the repository at this point in the history
* master:
  fix hints for type definitions
  playground: remove overflow in editor so type hints are not cropped
  playground: fix onload error markers
  playground: hints in reason syntax
  playground: type hints
  Add section about check-npm-deps
  Rename to reason-react-ppx
  • Loading branch information
jchavarri committed Oct 5, 2023
2 parents e558d91 + b66011f commit 3fe8249
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 18 deletions.
39 changes: 36 additions & 3 deletions docs/package-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,39 @@ The advantage of this approach —as opposed to vendoring the JavaScript package
inside the bindings— is that it gives users of the bindings complete flexibility
over the way these JavaScript packages are downloaded and bundled.

Melange provides a way to define dependencies from opam packages to npm packages
inside the `opam` files through the
[check-npm-deps](https://github.com/jchavarri/opam-check-npm-deps) opam plugin.

With this plugin, library authors can include constraints in the npm format
inside the opam `depexts` field, for example, the `reason-react` opam file can
include a section like this:

```
depexts: [
["react" "react-dom"] {npm-version = "^17.0.0 || ^18.0.0"}
]
```

This indicates that the version of `reason-react` is compatible with ReactJS
versions 17 and 18.

Users of Melange bindings can check that the constraints defined in the opam
packages installed in their switch are fulfilled by the packages installed in
`node_modules` by using the `check-npm-deps` plugin. For this, one just needs to
install the plugin:

```bash
opam install opam-check-npm-deps
```

And then call it from the root folder of the project, where the opam switch and
the `node_modules` folder exist:

```bash
opam-check-npm-deps
```

## Finding and using Melange compatible packages

### opam packages
Expand Down Expand Up @@ -325,12 +358,12 @@ then `reason-react` should be added to the `dune` file under the `src` folder:
(alias react)
(libraries lib reason-react)
(preprocess
(pps reactjs-jsx-ppx))
(pps reason-react-ppx))
(module_systems es6))
```

Some libraries will only work after being processed by an accompanying PPX,
e.g., `reason-react` requires preprocessing with `reactjs-jsx-ppx`. These
e.g., `reason-react` requires preprocessing with `reason-react-ppx`. These
preprocessors may be installed together with the library as part of the same
package, or they might be part of a different package, in which case they need
to be installed separately.
Expand Down Expand Up @@ -363,7 +396,7 @@ file:
(alias react)
(libraries lib reason-react melange-fetch)
(preprocess
(pps reactjs-jsx-ppx))
(pps reason-react-ppx))
(module_systems es6))
```

Expand Down
4 changes: 2 additions & 2 deletions documentation-site.opam
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ dev-repo: "git+https://github.com/melange-re/melange-re.github.io.git"
pin-depends: [
[ "reason-react.dev" "git+https://github.com/reasonml/reason-react.git#0ccff71796b60d6c32ab6cf01e31beccca4698b9" ]
[ "reason-react-ppx.dev" "git+https://github.com/reasonml/reason-react.git#0ccff71796b60d6c32ab6cf01e31beccca4698b9" ]
[ "melange.dev" "git+https://github.com/melange-re/melange.git#465101328e0e1ec90e246b0a2e8622e6cbdc0584" ]
[ "melange-playground.dev" "git+https://github.com/melange-re/melange.git#465101328e0e1ec90e246b0a2e8622e6cbdc0584" ]
[ "melange.dev" "git+https://github.com/melange-re/melange.git#3a5aec1548067122e99eeaf6a08fc555415421dc" ]
[ "melange-playground.dev" "git+https://github.com/melange-re/melange.git#3a5aec1548067122e99eeaf6a08fc555415421dc" ]
[ "cmarkit.dev" "git+https://github.com/dbuenzli/cmarkit.git#f37c8ea86fd0be8dba7a8babcee3682e0e047d91" ]
]
build: [
Expand Down
1 change: 0 additions & 1 deletion playground/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ button:hover {
}

.Editor {
overflow: auto;
height: 100%;
}

Expand Down
117 changes: 105 additions & 12 deletions playground/src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -420,15 +420,36 @@ const compile = (language, code) => {
}
if (problems) {
return {
typeHints: [],
problems: problems,
}
} else {
return {
typeHints: compilation.type_hints.sort((a, b) => {
let aLineGap = a.end.line - a.start.line;
let bLineGap = b.end.line - b.start.line;
if (aLineGap < bLineGap) {
return -1;
} else if (aLineGap > bLineGap) {
return 1;
} else {
let aColGap = a.end.col - a.start.col;
let bColGap = b.end.col - b.start.col;
if (aColGap < bColGap) {
return -1;
} else if (aColGap > bColGap) {
return 1;
} else {
return 0;
}
}
}),
javascriptCode: compilation.js_code,
}
}
} else {
return {
typeHints: [],
problems: [
{
js_error_msg: "No result was returned from compilation",
Expand All @@ -443,6 +464,21 @@ const compile = (language, code) => {
}
};

function updateMarkers(monaco, editorRef, compilation) {
if (monaco && editorRef.current) {
const owner = "playground";
if (compilation?.problems) {
monaco.editor.setModelMarkers(
editorRef.current.getModel(),
owner,
compilation.problems.map(toMonaco)
);
} else {
monaco.editor.removeAllMarkers(owner);
}
}
}

function App() {
const defaultState = {
language: languageMap.OCaml,
Expand All @@ -467,8 +503,9 @@ function App() {

const editorRef = React.useRef(null);

function handleEditorDidMount(editor, _monaco) {
function handleEditorDidMount(editor, monaco) {
editorRef.current = editor;
updateMarkers(monaco, editorRef, compilation);
}

function clearLogs() {
Expand All @@ -489,19 +526,75 @@ function App() {
}, [monaco]);

React.useEffect(() => {
// or make sure that it exists by other ways
if (monaco && editorRef.current) {
const owner = "playground";
if (compilation?.problems) {
monaco.editor.setModelMarkers(
editorRef.current.getModel(),
owner,
compilation.problems.map(toMonaco)
);
} else {
monaco.editor.removeAllMarkers(owner);
let hoverProvider = undefined;
if (monaco) {
hoverProvider = monaco.languages.registerHoverProvider(language, {
provideHover: function (model, position) {
const { lineNumber, column } = position;
if (!compilation?.typeHints) {
return null;
} else {
function hintInLoc(item) {
var end = item.end;
var start = item.start;
const result =
lineNumber >= start.line &&
lineNumber <= end.line &&
column >= start.col + 1 &&
column <= end.col + 1;
return result;
};
const result = compilation?.typeHints.find(hintInLoc);
if (result) {
const range = new monaco.Range(
result.start.line,
result.start.col + 1,
result.end.line,
result.end.col + 1
);
let hint = result.hint;
if (language == languageMap.Reason) {
try {
if (hint.substring(0,5) === "type ") {
// No need to mess with the hint as it should be valid AST
hint = ocaml.printRE(ocaml.parseML(hint));
} else {
const prefix = "type t = ";
// Must be something else than a type
hint =
ocaml
/* add prefix so it is valid code */
.printRE(ocaml.parseML(prefix + hint))
/* remove prefix */
.slice(prefix.length)
/* remove last `;` */
.slice(0, -2);
}

} catch (e) {
console.error("Error formatting type hint: ", hint);
}
}
return {
range,
contents: [{ value: `\`\`\`${language}\n${hint}\n\`\`\`` }],
};
} else {
return null;
}
}
},
});
}
return () => {
if (hoverProvider) {
hoverProvider.dispose();
}
}
}, [monaco, compilation?.typeHints]);

React.useEffect(() => {
updateMarkers(monaco, editorRef, compilation)
}, [monaco, compilation?.problems]);

React.useEffect(() => {
Expand Down

0 comments on commit 3fe8249

Please sign in to comment.