diff --git a/compiler/forget/src/MiddleEnd/SketchyCodeCheck.ts b/compiler/forget/src/MiddleEnd/SketchyCodeCheck.ts index 904e3e676d..341e5a4a13 100644 --- a/compiler/forget/src/MiddleEnd/SketchyCodeCheck.ts +++ b/compiler/forget/src/MiddleEnd/SketchyCodeCheck.ts @@ -53,17 +53,18 @@ export function run( const funcBody = func.get("body"); if (context.opts.flags.bailOnCapitalizedFunctionCalls) { + function isValidFunctionCallName(name: string): boolean { + return ( + ALLOWED_CAPITALIZED_STDLIB_FUNCTIONS.has(name) || + context.opts.allowedCapitalizedUserFunctions.has(name) || + !/^[A-Z]/.test(name) + ); + } + funcBody.traverse({ CallExpression(path) { const callee = path.get("callee"); if (t.isIdentifier(callee.node)) { - const name = callee.node.name; - if ( - ALLOWED_CAPITALIZED_STDLIB_FUNCTIONS.has(name) || - context.opts.allowedCapitalizedUserFunctions.has(name) - ) { - return; - } // Allow `Module().method()`; if ( t.isMemberExpression(path.parent) || @@ -71,13 +72,28 @@ export function run( ) { return; } - if (/^[A-Z]/.test(name)) { + const name = callee.node.name; + if (!isValidFunctionCallName(name)) { context.bailout("BailOnCapitalizedFunctionCalls", { code: "E0018", path: callee, context: null, }); } + } else if ( + t.isMemberExpression(callee.node) || + t.isOptionalMemberExpression(callee.node) + ) { + const { object, property } = callee.node; + if (t.isIdentifier(object) && t.isIdentifier(property)) { + if (!isValidFunctionCallName(`${object.name}.${property.name}`)) { + context.bailout("BailOnCapitalizedFunctionCalls", { + code: "E0018", + path: callee, + context: null, + }); + } + } } }, });