diff --git a/compiler/apps/playground/components/Editor/EditorImpl.tsx b/compiler/apps/playground/components/Editor/EditorImpl.tsx index ebac65dc4b9f2..a730e2af04808 100644 --- a/compiler/apps/playground/components/Editor/EditorImpl.tsx +++ b/compiler/apps/playground/components/Editor/EditorImpl.tsx @@ -66,14 +66,14 @@ function parseFunctions( source: string, language: 'flow' | 'typescript', ): Array< - NodePath< - t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression - > + | NodePath + | NodePath + | NodePath > { const items: Array< - NodePath< - t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression - > + | NodePath + | NodePath + | NodePath > = []; try { const ast = parseInput(source, language); @@ -155,22 +155,42 @@ function isHookName(s: string): boolean { return /^use[A-Z0-9]/.test(s); } -function getReactFunctionType( - id: NodePath, -): ReactFunctionType { - if (id && id.node && id.isIdentifier()) { - if (isHookName(id.node.name)) { +function getReactFunctionType(id: t.Identifier | null): ReactFunctionType { + if (id != null) { + if (isHookName(id.name)) { return 'Hook'; } const isPascalCaseNameSpace = /^[A-Z].*/; - if (isPascalCaseNameSpace.test(id.node.name)) { + if (isPascalCaseNameSpace.test(id.name)) { return 'Component'; } } return 'Other'; } +function getFunctionName( + fn: + | NodePath + | NodePath + | NodePath, +): t.Identifier | null { + if (fn.isArrowFunctionExpression()) { + return null; + } + const id = fn.get('id'); + return Array.isArray(id) === false && id.isIdentifier() ? id.node : null; +} + +let count = 0; +function makeIdentifier(id: t.Identifier | null): t.Identifier { + if (id != null && id.name != null) { + return id; + } else { + return t.identifier(`anonymous_${count++}`); + } +} + function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] { const results = new Map(); const error = new CompilerError(); @@ -194,21 +214,7 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] { const config = parseConfigPragma(pragma); for (const fn of parseFunctions(source, language)) { - if (!fn.isFunctionDeclaration()) { - error.pushErrorDetail( - new CompilerErrorDetail({ - reason: `Unexpected function type ${fn.node.type}`, - description: - 'Playground only supports parsing function declarations', - severity: ErrorSeverity.Todo, - loc: fn.node.loc ?? null, - suggestions: null, - }), - ); - continue; - } - - const id = fn.get('id'); + const id = getFunctionName(fn); for (const result of run( fn, { @@ -221,7 +227,7 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] { null, null, )) { - const fnName = fn.node.id?.name ?? null; + const fnName = id?.name ?? '(anonymous)'; switch (result.kind) { case 'ast': { upsert({ @@ -230,7 +236,7 @@ function compile(source: string): [CompilerOutput, 'flow' | 'typescript'] { name: result.name, value: { type: 'FunctionDeclaration', - id: result.value.id, + id: makeIdentifier(result.value.id), async: result.value.async, generator: result.value.generator, body: result.value.body,