Skip to content

Commit 612ce99

Browse files
hawkgskirjs
authored andcommitted
refactor(compiler-cli): include linkedSignal in the signal debugName transformer (#64106)
Add support for `linkedSignal`s in the signal `debugName` transformer. Continuation of #63346 PR Close #64106
1 parent 8e80083 commit 612ce99

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

goldens/public-api/core/index.api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,7 @@ export class KeyValueDiffers {
11461146
// @public
11471147
export function linkedSignal<D>(computation: () => D, options?: {
11481148
equal?: ValueEqualityFn<NoInfer<D>>;
1149+
debugName?: string;
11491150
}): WritableSignal<D>;
11501151

11511152
// @public

packages/compiler-cli/src/ngtsc/transform/src/implicit_signal_debug_name_transform.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,26 @@ function insertDebugNameIntoCallExpression(
1212
callExpression: ts.CallExpression,
1313
debugName: string,
1414
): ts.CallExpression {
15-
const signalExpressionHasNoArguments = callExpression.arguments.length === 0;
1615
const signalExpressionIsRequired = isRequiredSignalFunction(callExpression.expression);
1716
let configPosition = signalExpressionIsRequired ? 0 : 1;
1817

19-
// If the call expression has no arguments, we pretend that the config object is at position 0.
18+
const nodeArgs = Array.from(callExpression.arguments);
19+
20+
// 1. If the call expression has no arguments, we pretend that the config object is at position 0.
2021
// We do this so that we can insert a spread element at the start of the args list in a way where
2122
// undefined can be the first argument but still get tree-shaken out in production builds.
22-
if (signalExpressionHasNoArguments) {
23+
// or
24+
// 2. Since `linkedSignal` with computation uses a single object for both computation logic
25+
// and options (unlike other signal-based primitives), we set the argument position to 0, i.e.
26+
// reusing the computation logic object.
27+
const signalExpressionHasNoArguments = callExpression.arguments.length === 0;
28+
const isLinkedSignal = callExpression.expression.getText() === 'linkedSignal';
29+
const isComputationLinkedSignal =
30+
isLinkedSignal && nodeArgs[0].kind === ts.SyntaxKind.ObjectLiteralExpression;
31+
if (signalExpressionHasNoArguments || isComputationLinkedSignal) {
2332
configPosition = 0;
2433
}
2534

26-
const nodeArgs = Array.from(callExpression.arguments);
2735
let existingArgument = nodeArgs[configPosition];
2836

2937
if (existingArgument === undefined) {
@@ -96,12 +104,15 @@ function insertDebugNameIntoCallExpression(
96104

97105
let transformedSignalArgs: ts.NodeArray<ts.Expression>;
98106

99-
if (signalExpressionIsRequired || signalExpressionHasNoArguments) {
107+
if (signalExpressionIsRequired || signalExpressionHasNoArguments || isComputationLinkedSignal) {
100108
// 1. If the call expression is a required signal function, there is no args other than the config object.
101109
// So we just use the spread element as the only argument.
102110
// or
103111
// 2. If the call expression has no arguments (ex. input(), model(), etc), we already added the undefined
104112
// identifier in the spread element above. So we use that spread Element as is.
113+
// or
114+
// 3. We are transforming a `linkedSignal` with computation (i.e. we have a single object for both
115+
// logic and options).
105116
transformedSignalArgs = ts.factory.createNodeArray([spreadElementContainingUpdatedOptions]);
106117
} else {
107118
// 3. Signal expression is not required and has arguments.
@@ -280,6 +291,7 @@ function expressionIsUsingAngularCoreImportedSymbol(
280291
const signalFunctions: ReadonlySet<string> = new Set([
281292
'signal',
282293
'computed',
294+
'linkedSignal',
283295
'input',
284296
'model',
285297
'viewChild',

packages/core/src/render3/reactivity/linked_signal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const identityFn = <T>(v: T) => v;
2727
*/
2828
export function linkedSignal<D>(
2929
computation: () => D,
30-
options?: {equal?: ValueEqualityFn<NoInfer<D>>},
30+
options?: {equal?: ValueEqualityFn<NoInfer<D>>; debugName?: string},
3131
): WritableSignal<D>;
3232

3333
/**

0 commit comments

Comments
 (0)