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 

![Screenshot 2023-01-27 at 2 18 06 
PM](https://user-images.githubusercontent.com/1390709/215222635-59b42555-f1f3-4fc0-b1cd-3959946df6da.png) 

![Screenshot 2023-01-27 at 2 18 54 
PM](https://user-images.githubusercontent.com/1390709/215222636-4c0275fd-a95b-4f0f-946a-258ad8b27722.png) 

![Screenshot 2023-01-27 at 5 03 02 
PM](https://user-images.githubusercontent.com/1390709/215222637-92a8e459-173a-41ae-be9f-0cc0d54479d0.png)
This commit is contained in:
Lauren Tan
2023-01-30 10:36:35 -05:00
parent be4058057c
commit f0d64064a9
6 changed files with 53 additions and 32 deletions
@@ -37,7 +37,7 @@ export default function RootLayout({
crossOrigin="anonymous"
/>
</head>
<body className="font-sans">{children}</body>
<body className="font-sans h-screen overflow-hidden">{children}</body>
</html>
);
}
@@ -98,7 +98,7 @@ export default function Input({ errors }: Props) {
<div className="relative flex flex-col flex-none border-r border-gray-200">
{/* Restrict MonacoEditor's height, since the config autoLayout:true
will grow the editor to fit within parent element */}
<div className="w-full h-monaco_small sm:h-monaco">
<div className="w-full h-screen">
<MonacoEditor
path={"index.js"}
// .js and .jsx files are specified to be TS so that Monaco can actually
@@ -36,7 +36,11 @@ export type PrintedCompilerPipelineValue =
export type CompilerOutput =
| { kind: "ok"; results: Map<string, PrintedCompilerPipelineValue[]> }
| { kind: "err"; error: CompilerError };
| {
kind: "err";
results: Map<string, PrintedCompilerPipelineValue[]>;
error: CompilerError;
};
type Props = {
store: Store;
@@ -48,7 +52,6 @@ function tabify(source: string, compilerOutput: CompilerOutput) {
const reorderedTabs = new Map<string, React.ReactNode>();
const concattedResults = new Map<string, string>();
let topLevelFnDecls: Array<t.FunctionDeclaration> = [];
if (compilerOutput.kind === "err") return reorderedTabs;
// Concat all top level function declaration results into a single tab for each pass
for (const [passName, results] of compilerOutput.results) {
for (const result of results) {
@@ -152,21 +155,28 @@ function Output({ store, compilerOutput }: Props) {
[store.source, compilerOutput]
);
if (compilerOutput.kind === "err") {
return (
<pre>
<code>{compilerOutput.error.toString()}</code>
</pre>
);
}
return (
<TabbedWindow
defaultTab="HIR"
setTabsOpen={setTabsOpen}
tabsOpen={tabsOpen}
tabs={tabs}
/>
<>
<TabbedWindow
defaultTab="HIR"
setTabsOpen={setTabsOpen}
tabsOpen={tabsOpen}
tabs={tabs}
/>
{compilerOutput.kind === "err" ? (
<div className="flex flex-wrap w-full absolute bottom-0 bg-white grow w-screen border-y border-grey-200 transition-all ease-in">
<div className="w-full p-4 basis-full border-b">
<h2>COMPILER ERRORS</h2>
</div>
<pre
className="p-4 basis-full text-red-600"
style={{ maxHeight: "20vh", overflowY: "scroll" }}
>
{compilerOutput.error.toString()}
</pre>
</div>
) : null}
</>
);
}
@@ -57,16 +57,16 @@ function parseFunctions(
}
function compile(source: string): CompilerOutput {
const results = new Map<string, PrintedCompilerPipelineValue[]>();
const upsert = (result: PrintedCompilerPipelineValue) => {
const entry = results.get(result.name);
if (Array.isArray(entry)) {
entry.push(result);
} else {
results.set(result.name, [result]);
}
};
try {
const results = new Map<string, PrintedCompilerPipelineValue[]>();
const upsert = (result: PrintedCompilerPipelineValue) => {
const entry = results.get(result.name);
if (Array.isArray(entry)) {
entry.push(result);
} else {
results.set(result.name, [result]);
}
};
for (const fn of parseFunctions(source)) {
for (const result of run(fn)) {
const fnName = fn.node.id?.name ?? null;
@@ -112,7 +112,7 @@ function compile(source: string): CompilerOutput {
if (error.details == null) {
error.details = [];
}
return { kind: "err", error };
return { kind: "err", results, error };
}
}
@@ -150,7 +150,7 @@ export default function Editor() {
return (
<>
<div className="flex basis">
<div className="flex basis h-full">
<div
style={{ minWidth: 650 }}
className={clsx("relative sm:basis-1/4")}
@@ -161,7 +161,7 @@ export default function Editor() {
}
/>
</div>
<div className={clsx("flex sm:flex")}>
<div className={clsx("flex sm:flex flex-wrap")}>
<Output store={deferredStore} compilerOutput={compilerOutput} />
</div>
</div>
@@ -15,8 +15,18 @@ export default function TabbedWindow(props: {
tabsOpen: Set<string>;
setTabsOpen: (newTab: Set<string>) => void;
}): React.ReactElement {
if (props.tabs.size === 0) {
return (
<div
className="flex items-center justify-center"
style={{ width: "calc(100vw - 650px)" }}
>
No compiler output detected, see errors below
</div>
);
}
return (
<div className="flex flex-row h-full">
<div className="flex flex-row">
{Array.from(props.tabs.keys()).map((name) => {
return (
<TabbedWindowItem
@@ -58,7 +68,7 @@ function TabbedWindowItem({
return (
<div key={name} className="flex flex-row">
{isShow ? (
<div style={{ minWidth: 550 }}>
<div style={{ minWidth: 550, overflow: "hidden" }}>
<h2
onClick={toggleTabs}
className="p-4 duration-150 ease-in border-b cursor-pointer border-grey-200 text-secondary hover:text-link"
@@ -3,6 +3,7 @@ const colors = require("./colors");
module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx}",
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
"./lib/forgetMonacoDiagnostics.ts",