Repository: angular/angular
File: packages/compiler-cli/src/ngtsc/transform/src/implicit_signal_debug_name_transform.ts (TypeScript)

Code before:
  const debugNameProperty = ts.factory.createPropertyAssignment(
    'debugName',
    ts.factory.createStringLiteral(debugName),
  );

  let newArgs: ts.Expression[];

  if (existingArg !== null) {
    // If there's an existing object literal already, we transform it as follows:
    // `signal(0, {equal})` becomes `signal(0, { ...(ngDevMode ? {debugName: "n"} : {}), equal })`.
    // During minification the spread will be removed since it's pointing to an empty object.
    const transformedArg = ts.factory.createObjectLiteralExpression([
      ts.factory.createSpreadAssignment(
        createNgDevModeConditional(
          ts.factory.createObjectLiteralExpression([debugNameProperty]),
          ts.factory.createObjectLiteralExpression(),
        ),
      ),
      ...existingArg.properties,
    ]);

    newArgs = node.arguments.map((arg) => (arg === existingArg ? transformedArg : arg));
  } else {
    // If there's no existing argument, we transform it as follows:
    // `input(0)` becomes `input(0, ...(ngDevMode ? [{debugName: "n"}] : []))`
    // Spreading into an empty literal allows for the array to be dropped during minifcation.
    const spreadArgs: ts.Expression[] = [];

    // If we're adding an argument, but the function requires a first argument (e.g. `input()`),
    // we have to add `undefined` before the debug literal.
    if (hasNoArgs && !isRequired) {
      spreadArgs.push(ts.factory.createIdentifier('undefined'));
    }

    spreadArgs.push(ts.factory.createObjectLiteralExpression([debugNameProperty]));

    newArgs = [
      ...node.arguments,
      ts.factory.createSpreadElement(
        createNgDevModeConditional(
          ts.factory.createArrayLiteralExpression(spreadArgs),
          ts.factory.createArrayLiteralExpression(),
        ),
      ),
    ];
  }

  return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, newArgs);
}

/**

Review comment (suggestion):
nit
```suggestion
    // Spreading into an empty literal allows for the array to be dropped during minification.
```

Code after:
  const debugNameProperty = ts.factory.createPropertyAssignment(
    'debugName',
    ts.factory.createStringLiteral(debugName),
  );

  let newArgs: ts.Expression[];

  if (existingArg !== null) {
    // If there's an existing object literal already, we transform it as follows:
    // `signal(0, {equal})` becomes `signal(0, { ...(ngDevMode ? {debugName: "n"} : {}), equal })`.
    // During minification the spread will be removed since it's pointing to an empty object.
    const transformedArg = ts.factory.createObjectLiteralExpression([
      ts.factory.createSpreadAssignment(
        createNgDevModeConditional(
          ts.factory.createObjectLiteralExpression([debugNameProperty]),
          ts.factory.createObjectLiteralExpression(),
        ),
      ),
      ...existingArg.properties,
    ]);

    newArgs = node.arguments.map((arg) => (arg === existingArg ? transformedArg : arg));
  } else {
    // If there's no existing argument, we transform it as follows:
    // `input(0)` becomes `input(0, ...(ngDevMode ? [{debugName: "n"}] : []))`
    // Spreading into an empty literal allows for the array to be dropped during minification.
    const spreadArgs: ts.Expression[] = [];

    // If we're adding an argument, but the function requires a first argument (e.g. `input()`),
    // we have to add `undefined` before the debug literal.
    if (hasNoArgs && !isRequired) {
      spreadArgs.push(ts.factory.createIdentifier('undefined'));
    }

    spreadArgs.push(ts.factory.createObjectLiteralExpression([debugNameProperty]));

    newArgs = [
      ...node.arguments,
      ts.factory.createSpreadElement(
        createNgDevModeConditional(
          ts.factory.createArrayLiteralExpression(spreadArgs),
          ts.factory.createArrayLiteralExpression(),
        ),
      ),
    ];
  }

  return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, newArgs);
}

/**