Support partial compilation in playground
This adds support in the playground for best effort compilation: if any passes have errors, we'll try to render as many successful tabs leading up to the pass with an error. Also contains some styling updates   
Lauren Tan committed
Jan 30, 2023 at 10:36 UTC
f0d64064a98c5b391b3cb8a68d22ee9220f24f5d
6 files changed
+53
-32
compiler/forget/packages/playground/app/layout.tsx
+1
-1
@@ -37,7 +37,7 @@ export default function RootLayout({
37
crossOrigin="anonymous"
38
/>
39
</head>
40
- <body className="font-sans">{children}</body>
40
+ <body className="font-sans h-screen overflow-hidden">{children}</body>
41
</html>
42
);
43
}
compiler/forget/packages/playground/components/Editor/Input.tsx
+1
-1
@@ -98,7 +98,7 @@ export default function Input({ errors }: Props) {
98
<div className="relative flex flex-col flex-none border-r border-gray-200">
99
{/* Restrict MonacoEditor's height, since the config autoLayout:true
100
will grow the editor to fit within parent element */}
101
- <div className="w-full h-monaco_small sm:h-monaco">
101
+ <div className="w-full h-screen">
102
<MonacoEditor
103
path={"index.js"}
104
// .js and .jsx files are specified to be TS so that Monaco can actually
compiler/forget/packages/playground/components/Editor/Output.tsx
+26
-16
@@ -36,7 +36,11 @@ export type PrintedCompilerPipelineValue =
36
37
export type CompilerOutput =
38
| { kind: "ok"; results: Map<string, PrintedCompilerPipelineValue[]> }
39
- | { kind: "err"; error: CompilerError };
39
+ | {
40
+ kind: "err";
41
+ results: Map<string, PrintedCompilerPipelineValue[]>;
42
+ error: CompilerError;
43
+ };
44
45
type Props = {
46
store: Store;
@@ -48,7 +52,6 @@ function tabify(source: string, compilerOutput: CompilerOutput) {
52
const reorderedTabs = new Map<string, React.ReactNode>();
53
const concattedResults = new Map<string, string>();
54
let topLevelFnDecls: Array<t.FunctionDeclaration> = [];
51
- if (compilerOutput.kind === "err") return reorderedTabs;
55
// Concat all top level function declaration results into a single tab for each pass
56
for (const [passName, results] of compilerOutput.results) {
57
for (const result of results) {
@@ -152,21 +155,28 @@ function Output({ store, compilerOutput }: Props) {
155
[store.source, compilerOutput]
156
);
157
155
- if (compilerOutput.kind === "err") {
156
- return (
157
- <pre>
158
- <code>{compilerOutput.error.toString()}</code>
159
- </pre>
160
- );
161
- }
162
-
158
return (
164
- <TabbedWindow
165
- defaultTab="HIR"
166
- setTabsOpen={setTabsOpen}
167
- tabsOpen={tabsOpen}
168
- tabs={tabs}
169
- />
159
+ <>
160
+ <TabbedWindow
161
+ defaultTab="HIR"
162
+ setTabsOpen={setTabsOpen}
163
+ tabsOpen={tabsOpen}
164
+ tabs={tabs}
165
+ />
166
+ {compilerOutput.kind === "err" ? (
167
+ <div className="flex flex-wrap w-full absolute bottom-0 bg-white grow w-screen border-y border-grey-200 transition-all ease-in">
168
+ <div className="w-full p-4 basis-full border-b">
169
+ <h2>COMPILER ERRORS</h2>
170
+ </div>
171
+ <pre
172
+ className="p-4 basis-full text-red-600"
173
+ style={{ maxHeight: "20vh", overflowY: "scroll" }}
174
+ >
175
+ {compilerOutput.error.toString()}
176
+ </pre>
177
+ </div>
178
+ ) : null}
179
+ </>
180
);
181
}
182
compiler/forget/packages/playground/components/Editor/index.tsx
+12
-12
@@ -57,16 +57,16 @@ function parseFunctions(
57
}
58
59
function compile(source: string): CompilerOutput {
60
+ const results = new Map<string, PrintedCompilerPipelineValue[]>();
61
+ const upsert = (result: PrintedCompilerPipelineValue) => {
62
+ const entry = results.get(result.name);
63
+ if (Array.isArray(entry)) {
64
+ entry.push(result);
65
+ } else {
66
+ results.set(result.name, [result]);
67
+ }
68
+ };
69
try {
61
- const results = new Map<string, PrintedCompilerPipelineValue[]>();
62
- const upsert = (result: PrintedCompilerPipelineValue) => {
63
- const entry = results.get(result.name);
64
- if (Array.isArray(entry)) {
65
- entry.push(result);
66
- } else {
67
- results.set(result.name, [result]);
68
- }
69
- };
70
for (const fn of parseFunctions(source)) {
71
for (const result of run(fn)) {
72
const fnName = fn.node.id?.name ?? null;
@@ -112,7 +112,7 @@ function compile(source: string): CompilerOutput {
112
if (error.details == null) {
113
error.details = [];
114
}
115
- return { kind: "err", error };
115
+ return { kind: "err", results, error };
116
}
117
}
118
@@ -150,7 +150,7 @@ export default function Editor() {
150
151
return (
152
<>
153
- <div className="flex basis">
153
+ <div className="flex basis h-full">
154
<div
155
style={{ minWidth: 650 }}
156
className={clsx("relative sm:basis-1/4")}
@@ -161,7 +161,7 @@ export default function Editor() {
161
}
162
/>
163
</div>
164
- <div className={clsx("flex sm:flex")}>
164
+ <div className={clsx("flex sm:flex flex-wrap")}>
165
<Output store={deferredStore} compilerOutput={compilerOutput} />
166
</div>
167
</div>
compiler/forget/packages/playground/components/TabbedWindow.tsx
+12
-2
@@ -15,8 +15,18 @@ export default function TabbedWindow(props: {
15
tabsOpen: Set<string>;
16
setTabsOpen: (newTab: Set<string>) => void;
17
}): React.ReactElement {
18
+ if (props.tabs.size === 0) {
19
+ return (
20
+ <div
21
+ className="flex items-center justify-center"
22
+ style={{ width: "calc(100vw - 650px)" }}
23
+ >
24
+ No compiler output detected, see errors below
25
+ </div>
26
+ );
27
+ }
28
return (
19
- <div className="flex flex-row h-full">
29
+ <div className="flex flex-row">
30
{Array.from(props.tabs.keys()).map((name) => {
31
return (
32
<TabbedWindowItem
@@ -58,7 +68,7 @@ function TabbedWindowItem({
68
return (
69
<div key={name} className="flex flex-row">
70
{isShow ? (
61
- <div style={{ minWidth: 550 }}>
71
+ <div style={{ minWidth: 550, overflow: "hidden" }}>
72
<h2
73
onClick={toggleTabs}
74
className="p-4 duration-150 ease-in border-b cursor-pointer border-grey-200 text-secondary hover:text-link"
compiler/forget/packages/playground/tailwind.config.js
+1
@@ -3,6 +3,7 @@ const colors = require("./colors");
3
4
module.exports = {
5
content: [
6
+ "./app/**/*.{js,ts,jsx,tsx}",
7
"./pages/**/*.{js,ts,jsx,tsx}",
8
"./components/**/*.{js,ts,jsx,tsx}",
9
"./lib/forgetMonacoDiagnostics.ts",