Skip to content

Commit d3992ee

Browse files
committed
[playground] Allow (Arrow)FunctionExpressions
This was a pet peeve where our playground could only compile top level FunctionDeclarations. Just synthesize a fake identifier if it doesn't have one. ghstack-source-id: 88342ef Pull Request resolved: #30729
1 parent 4d088d9 commit d3992ee

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

compiler/apps/playground/components/Editor/EditorImpl.tsx

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,14 @@ function parseFunctions(
6666
source: string,
6767
language: 'flow' | 'typescript',
6868
): Array<
69-
NodePath<
70-
t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
71-
>
69+
| NodePath<t.FunctionDeclaration>
70+
| NodePath<t.ArrowFunctionExpression>
71+
| NodePath<t.FunctionExpression>
7272
> {
7373
const items: Array<
74-
NodePath<
75-
t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
76-
>
74+
| NodePath<t.FunctionDeclaration>
75+
| NodePath<t.ArrowFunctionExpression>
76+
| NodePath<t.FunctionExpression>
7777
> = [];
7878
try {
7979
const ast = parseInput(source, language);
@@ -155,22 +155,42 @@ function isHookName(s: string): boolean {
155155
return /^use[A-Z0-9]/.test(s);
156156
}
157157

158-
function getReactFunctionType(
159-
id: NodePath<t.Identifier | null | undefined>,
160-
): ReactFunctionType {
161-
if (id && id.node && id.isIdentifier()) {
162-
if (isHookName(id.node.name)) {
158+
function getReactFunctionType(id: t.Identifier | null): ReactFunctionType {
159+
if (id != null) {
160+
if (isHookName(id.name)) {
163161
return 'Hook';
164162
}
165163

166164
const isPascalCaseNameSpace = /^[A-Z].*/;
167-
if (isPascalCaseNameSpace.test(id.node.name)) {
165+
if (isPascalCaseNameSpace.test(id.name)) {
168166
return 'Component';
169167
}
170168
}
171169
return 'Other';
172170
}
173171

172+
function getFunctionName(
173+
fn:
174+
| NodePath<t.FunctionDeclaration>
175+
| NodePath<t.ArrowFunctionExpression>
176+
| NodePath<t.FunctionExpression>,
177+
): t.Identifier | null {
178+
if (fn.isArrowFunctionExpression()) {
179+
return null;
180+
}
181+
const id = fn.get('id');
182+
return Array.isArray(id) === false && id.isIdentifier() ? id.node : null;
183+
}
184+
185+
let count = 0;
186+
function makeIdentifier(id: t.Identifier | null): t.Identifier {
187+
if (id != null && id.name != null) {
188+
return id;
189+
} else {
190+
return t.identifier(`anonymous_${count++}`);
191+
}
192+
}
193+
174194
function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] {
175195
const results = new Map<string, PrintedCompilerPipelineValue[]>();
176196
const error = new CompilerError();
@@ -194,21 +214,7 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] {
194214
const config = parseConfigPragma(pragma);
195215

196216
for (const fn of parseFunctions(source, language)) {
197-
if (!fn.isFunctionDeclaration()) {
198-
error.pushErrorDetail(
199-
new CompilerErrorDetail({
200-
reason: `Unexpected function type ${fn.node.type}`,
201-
description:
202-
'Playground only supports parsing function declarations',
203-
severity: ErrorSeverity.Todo,
204-
loc: fn.node.loc ?? null,
205-
suggestions: null,
206-
}),
207-
);
208-
continue;
209-
}
210-
211-
const id = fn.get('id');
217+
const id = getFunctionName(fn);
212218
for (const result of run(
213219
fn,
214220
{
@@ -221,7 +227,7 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] {
221227
null,
222228
null,
223229
)) {
224-
const fnName = fn.node.id?.name ?? null;
230+
const fnName = id?.name ?? '(anonymous)';
225231
switch (result.kind) {
226232
case 'ast': {
227233
upsert({
@@ -230,7 +236,7 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] {
230236
name: result.name,
231237
value: {
232238
type: 'FunctionDeclaration',
233-
id: result.value.id,
239+
id: makeIdentifier(result.value.id),
234240
async: result.value.async,
235241
generator: result.value.generator,
236242
body: result.value.body,

0 commit comments

Comments
 (0)