Skip to content
Merged
Show file tree
Hide file tree
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
55 changes: 44 additions & 11 deletions compiler/apps/playground/components/Editor/EditorImpl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ const COMMON_HOOKS: Array<[string, Hook]> = [
],
];

function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] {
function compile(
source: string,
mode: 'compiler' | 'linter',
): [CompilerOutput, 'flow' | 'typescript'] {
const results = new Map<string, Array<PrintedCompilerPipelineValue>>();
const error = new CompilerError();
const otherErrors: Array<CompilerErrorDetail | CompilerDiagnostic> = [];
Expand Down Expand Up @@ -204,6 +207,22 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] {
};
const parsedOptions = parseConfigPragmaForTests(pragma, {
compilationMode: 'infer',
environment:
mode === 'linter'
? {
// enabled in compiler
validateRefAccessDuringRender: false,
// enabled in linter
validateNoSetStateInRender: true,
validateNoSetStateInEffects: true,
validateNoJSXInTryStatements: true,
validateNoImpureFunctionsInRender: true,
validateStaticComponents: true,
validateNoFreezingKnownMutableFunctions: true,
}
: {
/* use defaults for compiler mode */
},
});
const opts: PluginOptions = parsePluginOptions({
...parsedOptions,
Expand Down Expand Up @@ -249,9 +268,12 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] {
otherErrors.forEach(e => error.details.push(e));
}
if (error.hasErrors()) {
return [{kind: 'err', results, error: error}, language];
return [{kind: 'err', results, error}, language];
}
return [{kind: 'ok', results, transformOutput}, language];
return [
{kind: 'ok', results, transformOutput, errors: error.details},
language,
];
}

export default function Editor(): JSX.Element {
Expand All @@ -260,7 +282,11 @@ export default function Editor(): JSX.Element {
const dispatchStore = useStoreDispatch();
const {enqueueSnackbar} = useSnackbar();
const [compilerOutput, language] = useMemo(
() => compile(deferredStore.source),
() => compile(deferredStore.source, 'compiler'),
[deferredStore.source],
);
const [linterOutput] = useMemo(
() => compile(deferredStore.source, 'linter'),
[deferredStore.source],
);

Expand All @@ -286,19 +312,26 @@ export default function Editor(): JSX.Element {
});
});

let mergedOutput: CompilerOutput;
let errors: Array<CompilerErrorDetail | CompilerDiagnostic>;
if (compilerOutput.kind === 'ok') {
errors = linterOutput.kind === 'ok' ? [] : linterOutput.error.details;
mergedOutput = {
...compilerOutput,
errors,
};
} else {
mergedOutput = compilerOutput;
errors = compilerOutput.error.details;
}
return (
<>
<div className="relative flex basis top-14">
<div className={clsx('relative sm:basis-1/4')}>
<Input
language={language}
errors={
compilerOutput.kind === 'err' ? compilerOutput.error.details : []
}
/>
<Input language={language} errors={errors} />
</div>
<div className={clsx('flex sm:flex flex-wrap')}>
<Output store={deferredStore} compilerOutput={compilerOutput} />
<Output store={deferredStore} compilerOutput={mergedOutput} />
</div>
</div>
</>
Expand Down
52 changes: 44 additions & 8 deletions compiler/apps/playground/components/Editor/Output.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import {
InformationCircleIcon,
} from '@heroicons/react/outline';
import MonacoEditor, {DiffEditor} from '@monaco-editor/react';
import {type CompilerError} from 'babel-plugin-react-compiler';
import {
CompilerErrorDetail,
CompilerDiagnostic,
type CompilerError,
} from 'babel-plugin-react-compiler';
import parserBabel from 'prettier/plugins/babel';
import * as prettierPluginEstree from 'prettier/plugins/estree';
import * as prettier from 'prettier/standalone';
Expand Down Expand Up @@ -44,6 +48,7 @@ export type CompilerOutput =
kind: 'ok';
transformOutput: CompilerTransformOutput;
results: Map<string, Array<PrintedCompilerPipelineValue>>;
errors: Array<CompilerErrorDetail | CompilerDiagnostic>;
}
| {
kind: 'err';
Expand Down Expand Up @@ -123,10 +128,36 @@ async function tabify(
parser: transformOutput.language === 'flow' ? 'babel-flow' : 'babel-ts',
plugins: [parserBabel, prettierPluginEstree],
});

let output: string;
let language: string;
if (compilerOutput.errors.length === 0) {
output = code;
language = 'javascript';
} else {
language = 'markdown';
output = `
# Output

React Compiler compiled this function sucessfully, but there are lint errors that indicate potential issues with the original code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small nit: sucessfully -> successfully


## ${compilerOutput.errors.length} Lint Errors

${compilerOutput.errors.map(e => e.printErrorMessage(source, {eslint: false})).join('\n\n')}

## Output

\`\`\`js
${code}
\`\`\`
`.trim();
}

reorderedTabs.set(
'JS',
'Output',
<TextTabContent
output={code}
output={output}
language={language}
diff={null}
showInfoPanel={false}></TextTabContent>,
);
Expand All @@ -147,9 +178,10 @@ async function tabify(
eslint: false,
});
reorderedTabs.set(
'Errors',
'Output',
<TextTabContent
output={errors}
language="plaintext"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should the language be markdown?

diff={null}
showInfoPanel={false}></TextTabContent>,
);
Expand All @@ -173,7 +205,9 @@ function getSourceMapUrl(code: string, map: string): string | null {
}

function Output({store, compilerOutput}: Props): JSX.Element {
const [tabsOpen, setTabsOpen] = useState<Set<string>>(() => new Set(['JS']));
const [tabsOpen, setTabsOpen] = useState<Set<string>>(
() => new Set(['Output']),
);
const [tabs, setTabs] = useState<Map<string, React.ReactNode>>(
() => new Map(),
);
Expand All @@ -187,7 +221,7 @@ function Output({store, compilerOutput}: Props): JSX.Element {
);
if (compilerOutput.kind !== previousOutputKind) {
setPreviousOutputKind(compilerOutput.kind);
setTabsOpen(new Set([compilerOutput.kind === 'ok' ? 'JS' : 'Errors']));
setTabsOpen(new Set(['Output']));
}

useEffect(() => {
Expand All @@ -196,7 +230,7 @@ function Output({store, compilerOutput}: Props): JSX.Element {
});
}, [store.source, compilerOutput]);

const changedPasses: Set<string> = new Set(['JS', 'HIR']); // Initial and final passes should always be bold
const changedPasses: Set<string> = new Set(['Output', 'HIR']); // Initial and final passes should always be bold
let lastResult: string = '';
for (const [passName, results] of compilerOutput.results) {
for (const result of results) {
Expand Down Expand Up @@ -228,10 +262,12 @@ function TextTabContent({
output,
diff,
showInfoPanel,
language,
}: {
output: string;
diff: string | null;
showInfoPanel: boolean;
language: string;
}): JSX.Element {
const [diffMode, setDiffMode] = useState(false);
return (
Expand Down Expand Up @@ -282,7 +318,7 @@ function TextTabContent({
/>
) : (
<MonacoEditor
defaultLanguage="javascript"
language={language ?? 'javascript'}
value={output}
options={{
...monacoOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,13 @@ function* splitPragma(
*/
function parseConfigPragmaEnvironmentForTest(
pragma: string,
defaultConfig: PartialEnvironmentConfig,
): EnvironmentConfig {
const maybeConfig: Partial<Record<keyof EnvironmentConfig, unknown>> = {};
// throw early if the defaults are invalid
EnvironmentConfigSchema.parse(defaultConfig);

const maybeConfig: Partial<Record<keyof EnvironmentConfig, unknown>> =
defaultConfig;

for (const {key, value: val} of splitPragma(pragma)) {
if (!hasOwnProperty(EnvironmentConfigSchema.shape, key)) {
Expand Down Expand Up @@ -174,9 +179,13 @@ export function parseConfigPragmaForTests(
pragma: string,
defaults: {
compilationMode: CompilationMode;
environment?: PartialEnvironmentConfig;
},
): PluginOptions {
const environment = parseConfigPragmaEnvironmentForTest(pragma);
const environment = parseConfigPragmaEnvironmentForTest(
pragma,
defaults.environment ?? {},
);
const options: Record<keyof PluginOptions, unknown> = {
...defaultOptions,
panicThreshold: 'all_errors',
Expand Down
Loading