"use strict"; /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.dev/license */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getKeywords = getKeywords; exports.default = default_1; /** * The name of the Angular class metadata function created by the Angular compiler. */ const SET_CLASS_METADATA_NAME = 'ɵsetClassMetadata'; /** * Name of the asynchronous Angular class metadata function created by the Angular compiler. */ const SET_CLASS_METADATA_ASYNC_NAME = 'ɵsetClassMetadataAsync'; /** * Name of the function that sets debug information on classes. */ const SET_CLASS_DEBUG_INFO_NAME = 'ɵsetClassDebugInfo'; /** * Provides one or more keywords that if found within the content of a source file indicate * that this plugin should be used with a source file. * * @returns An a string iterable containing one or more keywords. */ function getKeywords() { return Object.keys(angularMetadataFunctions); } /** * An object map of function names and related value checks for discovery of Angular generated * metadata calls. */ const angularMetadataFunctions = { [SET_CLASS_METADATA_NAME]: isSetClassMetadataCall, [SET_CLASS_METADATA_ASYNC_NAME]: isSetClassMetadataAsyncCall, [SET_CLASS_DEBUG_INFO_NAME]: isSetClassDebugInfoCall, }; /** * A babel plugin factory function for eliding the Angular class metadata function (`ɵsetClassMetadata`). * * @returns A babel plugin object instance. */ function default_1() { return { visitor: { CallExpression(path) { const callee = path.get('callee'); // The function being called must be the metadata function name let calleeName; if (callee.isMemberExpression()) { const calleeProperty = callee.get('property'); if (calleeProperty.isIdentifier()) { calleeName = calleeProperty.node.name; } } else if (callee.isIdentifier()) { calleeName = callee.node.name; } if (!calleeName) { return; } if (Object.hasOwn(angularMetadataFunctions, calleeName) && angularMetadataFunctions[calleeName](path.get('arguments'))) { // The metadata function is always emitted inside a function expression const parent = path.getFunctionParent(); if (parent && (parent.isFunctionExpression() || parent.isArrowFunctionExpression())) { // Replace the metadata function with `void 0` which is the equivalent return value // of the metadata function. path.replaceWith(path.scope.buildUndefinedNode()); } } }, }, }; } /** Determines if a function call is a call to `setClassMetadata`. */ function isSetClassMetadataCall(callArguments) { // `setClassMetadata` calls have to meet the following criteria: // * First must be an identifier // * Second must be an array literal return (callArguments.length === 4 && callArguments[0].isIdentifier() && callArguments[1].isArrayExpression()); } /** Determines if a function call is a call to `setClassMetadataAsync`. */ function isSetClassMetadataAsyncCall(callArguments) { // `setClassMetadataAsync` calls have to meet the following criteria: // * First argument must be an identifier. // * Second argument must be an inline function. // * Third argument must be an inline function. return (callArguments.length === 3 && callArguments[0].isIdentifier() && isInlineFunction(callArguments[1]) && isInlineFunction(callArguments[2])); } /** Determines if a function call is a call to `setClassDebugInfo`. */ function isSetClassDebugInfoCall(callArguments) { return (callArguments.length === 2 && callArguments[0].isIdentifier() && callArguments[1].isObjectExpression()); } /** Determines if a node is an inline function expression. */ function isInlineFunction(path) { return path.isFunctionExpression() || path.isArrowFunctionExpression(); }