Skip to content

Commit 63670c0

Browse files
authored
Merge pull request rescript-lang#55 from reason-association/playground-ui-improvements
Playground UI improvements
2 parents 9ccf19f + ce398eb commit 63670c0

File tree

12 files changed

+1450
-1164
lines changed

12 files changed

+1450
-1164
lines changed

bindings/Bs_platform_api.re

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// has been loaded, so we'd prefer to protect this
77
// API with the playground compiler manager state
88

9+
[@bs.val] [@bs.scope "performance"] external now: unit => float = "now";
10+
911
module Lang = {
1012
type t =
1113
| Reason
@@ -109,6 +111,32 @@ module LocMsg = {
109111

110112
{j|[$prefix] Line $row, $column: $shortMsg|j};
111113
};
114+
115+
// Creates a somewhat unique id based on the rows / cols of the locMsg
116+
let makeId = t => {
117+
Belt.Int.(
118+
toString(t.row)
119+
++ "-"
120+
++ toString(t.endRow)
121+
++ "-"
122+
++ toString(t.column)
123+
++ "-"
124+
++ toString(t.endColumn)
125+
);
126+
};
127+
128+
let dedupe = (arr: array(t)) => {
129+
let result = Js.Dict.empty();
130+
131+
for (i in 0 to Js.Array.length(arr) - 1) {
132+
let locMsg = Js.Array2.unsafe_get(arr, i);
133+
let id = makeId(locMsg);
134+
135+
// The last element with the same id wins
136+
result->Js.Dict.set(id, locMsg);
137+
};
138+
Js.Dict.values(result);
139+
};
112140
};
113141

114142
module Warning = {
@@ -173,12 +201,14 @@ module CompileSuccess = {
173201
type t = {
174202
js_code: string,
175203
warnings: array(Warning.t),
204+
time: float // total compilation time
176205
};
177206

178-
let decode = (json): t => {
207+
let decode = (~time: float, json): t => {
179208
Json.Decode.{
180209
js_code: field("js_code", string, json),
181210
warnings: field("warnings", array(Warning.decode), json),
211+
time,
182212
};
183213
};
184214
};
@@ -213,7 +243,9 @@ module CompileFail = {
213243
switch (field("type", string, json)) {
214244
| "syntax_error" =>
215245
let locMsgs = field("errors", array(LocMsg.decode), json);
216-
SyntaxErr(locMsgs);
246+
// TODO: There seems to be a bug in the ReScript bundle that reports
247+
// back multiple LocMsgs of the same value
248+
locMsgs->LocMsg.dedupe->SyntaxErr;
217249
| "type_error" =>
218250
let locMsgs = field("errors", array(LocMsg.decode), json);
219251
TypecheckErr(locMsgs);
@@ -241,12 +273,12 @@ module CompilationResult = {
241273
| Unknown(string, Js.Json.t);
242274

243275
// TODO: We might change this specific api completely before launching
244-
let decode = (json: Js.Json.t): t => {
276+
let decode = (~time: float, json: Js.Json.t): t => {
245277
open! Json.Decode;
246278

247279
try(
248280
switch (field("type", string, json)) {
249-
| "success" => Success(CompileSuccess.decode(json))
281+
| "success" => Success(CompileSuccess.decode(~time, json))
250282
| "unexpected_error" => UnexpectedError(field("msg", string, json))
251283
| _ => Fail(CompileFail.decode(json))
252284
}
@@ -288,7 +320,6 @@ module Config = {
288320
type t = {
289321
module_system: string,
290322
warn_flags: string,
291-
warn_error_flags: string,
292323
};
293324
};
294325

@@ -299,8 +330,6 @@ module Compiler = {
299330
[@bs.val] [@bs.scope "bs_platform"] external make: unit => t = "make";
300331

301332
[@bs.get] external version: t => string = "version";
302-
[@bs.get]
303-
external version_git_commit: t => option(string) = "version_git_commit";
304333

305334
/*
306335
Res compiler actions
@@ -311,7 +340,11 @@ module Compiler = {
311340
external resCompile: (t, string) => Js.Json.t = "compile";
312341

313342
let resCompile = (t, code): CompilationResult.t => {
314-
resCompile(t, code)->CompilationResult.decode;
343+
let startTime = now();
344+
let json = resCompile(t, code);
345+
let stopTime = now();
346+
347+
CompilationResult.decode(~time=stopTime -. startTime, json);
315348
};
316349

317350
[@bs.send] [@bs.scope "napkin"]
@@ -331,7 +364,11 @@ module Compiler = {
331364
[@bs.send] [@bs.scope "reason"]
332365
external reasonCompile: (t, string) => Js.Json.t = "compile";
333366
let reasonCompile = (t, code): CompilationResult.t => {
334-
reasonCompile(t, code)->CompilationResult.decode;
367+
let startTime = now();
368+
let json = reasonCompile(t, code);
369+
let stopTime = now();
370+
371+
CompilationResult.decode(~time=stopTime -. startTime, json);
335372
};
336373

337374
[@bs.send] [@bs.scope "reason"]
@@ -351,7 +388,11 @@ module Compiler = {
351388
external ocamlCompile: (t, string) => Js.Json.t = "compile";
352389

353390
let ocamlCompile = (t, code): CompilationResult.t => {
354-
ocamlCompile(t, code)->CompilationResult.decode;
391+
let startTime = now();
392+
let json = ocamlCompile(t, code);
393+
let stopTime = now();
394+
395+
CompilationResult.decode(~time=stopTime -. startTime, json);
355396
};
356397

357398
/*
@@ -367,9 +408,6 @@ module Compiler = {
367408

368409
[@bs.send] external setWarnFlags: (t, string) => bool = "setWarnFlags";
369410

370-
[@bs.send]
371-
external setWarnErrorFlags: (t, string) => bool = "setWarnErrorFlags";
372-
373411
let setConfig = (t: t, config: Config.t): unit => {
374412
let moduleSystem =
375413
switch (config.module_system) {
@@ -383,7 +421,6 @@ module Compiler = {
383421
);
384422

385423
t->setWarnFlags(config.warn_flags)->ignore;
386-
t->setWarnErrorFlags(config.warn_error_flags)->ignore;
387424
};
388425

389426
[@bs.send]

common/HighlightJs.re

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,48 @@ type highlightResult = {value: string};
44
[@bs.module "highlight.js/lib/highlight"]
55
external highlight: (~lang: string, ~value: string) => highlightResult =
66
"highlight";
7+
8+
let renderHLJS =
9+
(
10+
~highlightedLines=[||],
11+
~darkmode=false,
12+
~code: string,
13+
~lang: string,
14+
(),
15+
) => {
16+
// If the language couldn't be parsed, we will fall back to text
17+
let (lang, highlighted) =
18+
try((lang, highlight(~lang, ~value=code)->valueGet)) {
19+
| Js.Exn.Error(_) => ("text", code)
20+
};
21+
22+
// Add line highlighting as well
23+
let highlighted =
24+
if (Belt.Array.length(highlightedLines) > 0) {
25+
Js.String2.split(highlighted, "\n")
26+
->Belt.Array.mapWithIndex((i, line) =>
27+
if (Js.Array2.find(highlightedLines, lnum => lnum === i + 1) !== None) {
28+
"<span class=\"hljs-line-highlight\">" ++ line ++ "</span>";
29+
} else {
30+
line;
31+
}
32+
)
33+
->Js.Array2.joinWith("\n");
34+
} else {
35+
highlighted;
36+
};
37+
38+
let dark = darkmode ? "dark" : "";
39+
40+
ReactDOMRe.createElementVariadic(
41+
"code",
42+
~props=
43+
ReactDOMRe.objToDOMProps({
44+
"className": "hljs lang-" ++ lang ++ " " ++ dark,
45+
"dangerouslySetInnerHTML": {
46+
"__html": highlighted,
47+
},
48+
}),
49+
[||],
50+
);
51+
};

components/CodeExample.re

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,5 @@
11
open Util.ReactStuff;
22

3-
let renderHLJS = (~highlightedLines=[||], ~code: string, ~lang: string, ()) => {
4-
// If the language couldn't be parsed, we will fall back to text
5-
let (lang, highlighted) =
6-
try((lang, HighlightJs.(highlight(~lang, ~value=code)->valueGet))) {
7-
| Js.Exn.Error(_) => ("text", code)
8-
};
9-
10-
// Add line highlighting as well
11-
let highlighted =
12-
if (Belt.Array.length(highlightedLines) > 0) {
13-
Js.String2.split(highlighted, "\n")
14-
->Belt.Array.mapWithIndex((i, line) =>
15-
if (Js.Array2.find(highlightedLines, lnum => lnum === i + 1) !== None) {
16-
"<span class=\"hljs-line-highlight\">" ++ line ++ "</span>";
17-
} else {
18-
line;
19-
}
20-
)
21-
->Js.Array2.joinWith("\n");
22-
} else {
23-
highlighted;
24-
};
25-
26-
ReactDOMRe.createElementVariadic(
27-
"code",
28-
~props=
29-
ReactDOMRe.objToDOMProps({
30-
"className": "wrap hljs lang-" ++ lang,
31-
"dangerouslySetInnerHTML": {
32-
"__html": highlighted,
33-
},
34-
}),
35-
[||],
36-
);
37-
};
38-
393
let langShortname = (lang: string) => {
404
switch (lang) {
415
| "ocaml" => "ml"
@@ -49,7 +13,7 @@ let langShortname = (lang: string) => {
4913

5014
[@react.component]
5115
let make = (~highlightedLines=[||], ~code: string, ~showLabel=true, ~lang="text") => {
52-
let children = renderHLJS(~highlightedLines, ~code, ~lang, ());
16+
let children = HighlightJs.renderHLJS(~highlightedLines, ~code, ~lang, ());
5317

5418
let label = if(showLabel) {
5519
let label = langShortname(lang);
@@ -136,7 +100,7 @@ module Toggle = {
136100
Belt.Array.get(multiple, selected)
137101
->Belt.Option.map(tab => {
138102
let lang = Belt.Option.getWithDefault(tab.lang, "text");
139-
renderHLJS(
103+
HighlightJs.renderHLJS(
140104
~highlightedLines=?tab.highlightedLines,
141105
~code=tab.code,
142106
~lang,

components/CodeMirror.re

Lines changed: 0 additions & 66 deletions
This file was deleted.

0 commit comments

Comments
 (0)