Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,7 @@ export function pass7__migrateTemplateReferences<D extends ClassFieldDescriptor>
continue;
}

const parent = reference.from.readAstPath.at(-2);
let readEndPos: number;

if (reference.from.isWrite && parent) {
readEndPos = parent.sourceSpan.end;
} else {
readEndPos = reference.from.read.sourceSpan.end;
}

const readEndPos = reference.from.read.sourceSpan.end;
// Skip duplicate references. E.g. if a template is shared.
const fileReferenceId = `${reference.from.templateFile.id}:${readEndPos}`;
if (seenFileReferences.has(fileReferenceId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,7 @@ export function pass8__migrateHostBindings<D extends ClassFieldDescriptor>(

const bindingField = reference.from.hostPropertyNode;
const expressionOffset = bindingField.getStart() + 1; // account for quotes.
const parent = reference.from.readAstPath.at(-2);
let readEndPos: number;

if (reference.from.isWrite && parent) {
readEndPos = expressionOffset + parent.sourceSpan.end;
} else {
readEndPos = expressionOffset + reference.from.read.sourceSpan.end;
}

const readEndPos = expressionOffset + reference.from.read.sourceSpan.end;
// Skip duplicate references. Can happen if the host object is shared.
if (seenReferences.get(bindingField)?.has(readEndPos)) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ export class TemplateExpressionReferenceVisitor<
private activeTmplAstNode: ExprContext | null = null;
private detectedInputReferences: TmplInputExpressionReference<ExprContext, D>[] = [];
private isInsideObjectShorthandExpression = false;
private isInsideAssignment = false;
private insideConditionalExpressionsWithReads: AST[] = [];

constructor(
Expand Down Expand Up @@ -285,17 +286,20 @@ export class TemplateExpressionReferenceVisitor<
}

override visitPropertyRead(ast: PropertyRead, context: AST[]) {
this._inspectPropertyAccess(ast, false, context);
this._inspectPropertyAccess(ast, context);
super.visitPropertyRead(ast, context);
}
override visitSafePropertyRead(ast: SafePropertyRead, context: AST[]) {
this._inspectPropertyAccess(ast, false, context);
this._inspectPropertyAccess(ast, context);
super.visitPropertyRead(ast, context);
}

override visitBinary(ast: Binary, context: AST[]) {
if (ast.operation === '=' && ast.left instanceof PropertyRead) {
this._inspectPropertyAccess(ast.left, true, [...context, ast, ast.left]);
if (ast.operation === '=') {
this.isInsideAssignment = true;
this.visit(ast.left, [...context, ast]);
this.isInsideAssignment = false;
this.visit(ast.right, [...context, ast]);
} else {
super.visitBinary(ast, context);
}
Expand All @@ -313,7 +317,7 @@ export class TemplateExpressionReferenceVisitor<
* Inspects the property access and attempts to resolve whether they access
* a known field. If so, the result is captured.
*/
private _inspectPropertyAccess(ast: PropertyRead, isAssignment: boolean, astPath: AST[]) {
private _inspectPropertyAccess(ast: PropertyRead, astPath: AST[]) {
if (
this.fieldNamesToConsiderForReferenceLookup !== null &&
!this.fieldNamesToConsiderForReferenceLookup.has(ast.name)
Expand All @@ -322,7 +326,7 @@ export class TemplateExpressionReferenceVisitor<
}

const isWrite = !!(
isAssignment ||
this.isInsideAssignment ||
(this.activeTmplAstNode && isTwoWayBindingNode(this.activeTmplAstNode))
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ import {Component, Input} from '@angular/core';
@Component({
template: `
<input [(ngModel)]="inputA" />
<div (click)="inputB = false"></div>
<input [(ngModel)]="inputB.prop.prop" />
<input (ngModelChange)="inputC = $event" />
<input (ngModelChange)="inputD.prop = $event + inputF" />
`,
host: {
'(click)': 'inputC = true',
'(click)': 'inputE = true',
},
})
class TwoWayBinding {
@Input() inputA = '';
@Input() inputB = true;
@Input() inputC = false;
@Input() inputD = false;
@Input() inputB = {prop: {prop: ''}};
@Input() inputC = '';
@Input() inputD = {prop: ''};
@Input() inputE = false;
@Input() inputF = '';
}
Original file line number Diff line number Diff line change
Expand Up @@ -1299,10 +1299,12 @@ import {Component, Input, input} from '@angular/core';
@Component({
template: `
<input [(ngModel)]="inputA" />
<div (click)="inputB = false"></div>
<input [(ngModel)]="inputB.prop.prop" />
<input (ngModelChange)="inputC = $event" />
<input (ngModelChange)="inputD.prop = $event + inputF()" />
`,
host: {
'(click)': 'inputC = true',
'(click)': 'inputE = true',
},
})
class TwoWayBinding {
Expand All @@ -1311,11 +1313,17 @@ class TwoWayBinding {
@Input() inputA = '';
// TODO: Skipped for migration because:
// Your application code writes to the input. This prevents migration.
@Input() inputB = true;
@Input() inputB = {prop: {prop: ''}};
// TODO: Skipped for migration because:
// Your application code writes to the input. This prevents migration.
@Input() inputC = false;
readonly inputD = input(false);
@Input() inputC = '';
// TODO: Skipped for migration because:
// Your application code writes to the input. This prevents migration.
@Input() inputD = {prop: ''};
// TODO: Skipped for migration because:
// Your application code writes to the input. This prevents migration.
@Input() inputE = false;
readonly inputF = input('');
}
@@@@@@ temporary_variables.ts @@@@@@

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1253,17 +1253,21 @@ import {Component, input} from '@angular/core';
@Component({
template: `
<input [(ngModel)]="inputA()" />
<div (click)="inputB = false()"></div>
<input [(ngModel)]="inputB().prop.prop" />
<input (ngModelChange)="inputC() = $event" />
<input (ngModelChange)="inputD().prop = $event + inputF()" />
`,
host: {
'(click)': 'inputC = true()',
'(click)': 'inputE() = true',
},
})
class TwoWayBinding {
readonly inputA = input('');
readonly inputB = input(true);
readonly inputC = input(false);
readonly inputD = input(false);
readonly inputB = input({ prop: { prop: '' } });
readonly inputC = input('');
readonly inputD = input({ prop: '' });
readonly inputE = input(false);
readonly inputF = input('');
}
@@@@@@ temporary_variables.ts @@@@@@

Expand Down
Loading