@angular/core 17.2.0-next.1 → 17.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/esm2022/primitives/signals/index.mjs +3 -3
  2. package/esm2022/src/application/application_ngmodule_factory_compiler.mjs +61 -0
  3. package/esm2022/src/application/application_ref.mjs +55 -69
  4. package/esm2022/src/authoring/input/input.mjs +48 -0
  5. package/esm2022/src/authoring/input/input_signal.mjs +40 -0
  6. package/esm2022/src/authoring/input/input_signal_node.mjs +22 -0
  7. package/esm2022/src/authoring/input/input_type_checking.mjs +9 -0
  8. package/esm2022/src/authoring/model/model.mjs +50 -0
  9. package/esm2022/src/authoring/model/model_signal.mjs +68 -0
  10. package/esm2022/src/authoring/model/model_signal_node.mjs +21 -0
  11. package/esm2022/src/authoring/output.mjs +33 -0
  12. package/esm2022/src/authoring/queries.mjs +1 -1
  13. package/esm2022/src/authoring.mjs +3 -2
  14. package/esm2022/src/core.mjs +7 -5
  15. package/esm2022/src/core_reactivity_export_internal.mjs +2 -2
  16. package/esm2022/src/core_render3_private_export.mjs +5 -4
  17. package/esm2022/src/defer/instructions.mjs +13 -6
  18. package/esm2022/src/di/create_injector.mjs +1 -1
  19. package/esm2022/src/di/injector_compatibility.mjs +1 -1
  20. package/esm2022/src/di/injector_token.mjs +1 -1
  21. package/esm2022/src/di/null_injector.mjs +1 -1
  22. package/esm2022/src/di/r3_injector.mjs +1 -1
  23. package/esm2022/src/errors.mjs +1 -1
  24. package/esm2022/src/hydration/utils.mjs +1 -1
  25. package/esm2022/src/platform/platform_ref.mjs +3 -2
  26. package/esm2022/src/render3/after_render_hooks.mjs +2 -6
  27. package/esm2022/src/render3/apply_value_input_field.mjs +1 -1
  28. package/esm2022/src/render3/component_ref.mjs +2 -2
  29. package/esm2022/src/render3/definition.mjs +2 -2
  30. package/esm2022/src/render3/di.mjs +1 -1
  31. package/esm2022/src/render3/errors_di.mjs +2 -2
  32. package/esm2022/src/render3/features/ng_onchanges_feature.mjs +1 -1
  33. package/esm2022/src/render3/i18n/i18n_locale_id.mjs +2 -2
  34. package/esm2022/src/render3/index.mjs +2 -2
  35. package/esm2022/src/render3/instructions/all.mjs +2 -1
  36. package/esm2022/src/render3/instructions/change_detection.mjs +6 -6
  37. package/esm2022/src/render3/instructions/listener.mjs +13 -4
  38. package/esm2022/src/render3/instructions/queries.mjs +3 -5
  39. package/esm2022/src/render3/instructions/queries_signals.mjs +4 -5
  40. package/esm2022/src/render3/instructions/render.mjs +5 -2
  41. package/esm2022/src/render3/instructions/shared.mjs +2 -2
  42. package/esm2022/src/render3/instructions/styling.mjs +1 -1
  43. package/esm2022/src/render3/instructions/two_way.mjs +70 -0
  44. package/esm2022/src/render3/instructions/write_to_directive_input.mjs +2 -2
  45. package/esm2022/src/render3/interfaces/attribute_marker.mjs +9 -0
  46. package/esm2022/src/render3/interfaces/definition.mjs +2 -8
  47. package/esm2022/src/render3/interfaces/input_flags.mjs +15 -0
  48. package/esm2022/src/render3/interfaces/node.mjs +1 -1
  49. package/esm2022/src/render3/interfaces/query.mjs +1 -1
  50. package/esm2022/src/render3/interfaces/view.mjs +1 -1
  51. package/esm2022/src/render3/jit/environment.mjs +5 -2
  52. package/esm2022/src/render3/node_selector_matcher.mjs +1 -1
  53. package/esm2022/src/render3/query.mjs +17 -3
  54. package/esm2022/src/render3/query_reactive.mjs +51 -75
  55. package/esm2022/src/render3/reactivity/signal.mjs +21 -1
  56. package/esm2022/src/render3/styling/static_styling.mjs +1 -1
  57. package/esm2022/src/render3/util/attrs_utils.mjs +1 -1
  58. package/esm2022/src/render3/util/discovery_utils.mjs +1 -1
  59. package/esm2022/src/render3/util/view_utils.mjs +3 -3
  60. package/esm2022/src/render3/view_ref.mjs +1 -1
  61. package/esm2022/src/util/stringify.mjs +2 -2
  62. package/esm2022/src/version.mjs +1 -1
  63. package/esm2022/testing/src/component_fixture.mjs +4 -4
  64. package/esm2022/testing/src/logger.mjs +3 -3
  65. package/fesm2022/core.mjs +14568 -14203
  66. package/fesm2022/core.mjs.map +1 -1
  67. package/fesm2022/primitives/signals.mjs +1 -1
  68. package/fesm2022/rxjs-interop.mjs +1 -1
  69. package/fesm2022/testing.mjs +4 -4
  70. package/fesm2022/testing.mjs.map +1 -1
  71. package/index.d.ts +366 -11
  72. package/package.json +1 -1
  73. package/primitives/signals/index.d.ts +2 -2
  74. package/rxjs-interop/index.d.ts +1 -1
  75. package/schematics/migrations/block-template-entities/bundle.js +413 -91
  76. package/schematics/migrations/block-template-entities/bundle.js.map +4 -4
  77. package/schematics/ng-generate/control-flow-migration/bundle.js +413 -91
  78. package/schematics/ng-generate/control-flow-migration/bundle.js.map +4 -4
  79. package/schematics/ng-generate/standalone-migration/bundle.js +6087 -5623
  80. package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
  81. package/testing/index.d.ts +1 -1
  82. package/esm2022/src/authoring/input.mjs +0 -48
  83. package/esm2022/src/authoring/input_signal.mjs +0 -40
  84. package/esm2022/src/authoring/input_signal_node.mjs +0 -22
  85. package/esm2022/src/authoring/input_type_checking.mjs +0 -9
@@ -1821,6 +1821,7 @@ var ConstantPool = class {
1821
1821
  this.literals = /* @__PURE__ */ new Map();
1822
1822
  this.literalFactories = /* @__PURE__ */ new Map();
1823
1823
  this.sharedConstants = /* @__PURE__ */ new Map();
1824
+ this._claimedNames = /* @__PURE__ */ new Map();
1824
1825
  this.nextNameIndex = 0;
1825
1826
  }
1826
1827
  getConstLiteral(literal2, forceShared) {
@@ -1913,8 +1914,12 @@ var ConstantPool = class {
1913
1914
  }
1914
1915
  return { literalFactory, literalFactoryArguments };
1915
1916
  }
1916
- uniqueName(prefix) {
1917
- return `${prefix}${this.nextNameIndex++}`;
1917
+ uniqueName(name, alwaysIncludeSuffix = true) {
1918
+ var _a2;
1919
+ const count = (_a2 = this._claimedNames.get(name)) != null ? _a2 : 0;
1920
+ const result = count === 0 && !alwaysIncludeSuffix ? `${name}` : `${name}${count}`;
1921
+ this._claimedNames.set(name, count + 1);
1922
+ return result;
1918
1923
  }
1919
1924
  freshName() {
1920
1925
  return this.uniqueName(CONSTANT_PREFIX);
@@ -2548,6 +2553,15 @@ var Identifiers = _Identifiers;
2548
2553
  (() => {
2549
2554
  _Identifiers.queryAdvance = { name: "\u0275\u0275queryAdvance", moduleName: CORE };
2550
2555
  })();
2556
+ (() => {
2557
+ _Identifiers.twoWayProperty = { name: "\u0275\u0275twoWayProperty", moduleName: CORE };
2558
+ })();
2559
+ (() => {
2560
+ _Identifiers.twoWayBindingSet = { name: "\u0275\u0275twoWayBindingSet", moduleName: CORE };
2561
+ })();
2562
+ (() => {
2563
+ _Identifiers.twoWayListener = { name: "\u0275\u0275twoWayListener", moduleName: CORE };
2564
+ })();
2551
2565
  (() => {
2552
2566
  _Identifiers.NgOnChangesFeature = { name: "\u0275\u0275NgOnChangesFeature", moduleName: CORE };
2553
2567
  })();
@@ -2617,6 +2631,9 @@ var Identifiers = _Identifiers;
2617
2631
  (() => {
2618
2632
  _Identifiers.UnwrapDirectiveSignalInputs = { name: "\u0275UnwrapDirectiveSignalInputs", moduleName: CORE };
2619
2633
  })();
2634
+ (() => {
2635
+ _Identifiers.unwrapWritableSignal = { name: "\u0275unwrapWritableSignal", moduleName: CORE };
2636
+ })();
2620
2637
 
2621
2638
  // bazel-out/k8-fastbuild/bin/packages/compiler/src/util.mjs
2622
2639
  var DASH_CASE_REGEXP = /-+([a-z0-9])/g;
@@ -4288,7 +4305,9 @@ var CHAINABLE_INSTRUCTIONS = /* @__PURE__ */ new Set([
4288
4305
  Identifiers.textInterpolate7,
4289
4306
  Identifiers.textInterpolate8,
4290
4307
  Identifiers.textInterpolateV,
4291
- Identifiers.templateCreate
4308
+ Identifiers.templateCreate,
4309
+ Identifiers.twoWayProperty,
4310
+ Identifiers.twoWayListener
4292
4311
  ]);
4293
4312
  function invokeInstruction(span, reference2, params) {
4294
4313
  return importExpr(reference2, null, span).callFn(params, span);
@@ -5921,30 +5940,10 @@ var EventHandlerVars = _EventHandlerVars;
5921
5940
  _EventHandlerVars.event = variable("$event");
5922
5941
  })();
5923
5942
  function convertActionBinding(localResolver, implicitReceiver, action, bindingId, baseSourceSpan, implicitReceiverAccesses, globals) {
5924
- if (!localResolver) {
5925
- localResolver = new DefaultLocalResolver(globals);
5926
- }
5927
- const actionWithoutBuiltins = convertPropertyBindingBuiltins({
5928
- createLiteralArrayConverter: (argCount) => {
5929
- return (args) => literalArr(args);
5930
- },
5931
- createLiteralMapConverter: (keys) => {
5932
- return (values) => {
5933
- const entries = keys.map((k, i) => ({
5934
- key: k.key,
5935
- value: values[i],
5936
- quoted: k.quoted
5937
- }));
5938
- return literalMap(entries);
5939
- };
5940
- },
5941
- createPipeConverter: (name) => {
5942
- throw new Error(`Illegal State: Actions are not allowed to contain pipes. Pipe: ${name}`);
5943
- }
5944
- }, action);
5943
+ localResolver != null ? localResolver : localResolver = new DefaultLocalResolver(globals);
5945
5944
  const visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId, false, baseSourceSpan, implicitReceiverAccesses);
5946
5945
  const actionStmts = [];
5947
- flattenStatements(actionWithoutBuiltins.visit(visitor, _Mode.Statement), actionStmts);
5946
+ flattenStatements(convertActionBuiltins(action).visit(visitor, _Mode.Statement), actionStmts);
5948
5947
  prependTemporaryDecls(visitor.temporaryCount, bindingId, actionStmts);
5949
5948
  if (visitor.usesImplicitReceiver) {
5950
5949
  localResolver.notifyImplicitReceiverUse();
@@ -5958,6 +5957,55 @@ function convertActionBinding(localResolver, implicitReceiver, action, bindingId
5958
5957
  }
5959
5958
  return actionStmts;
5960
5959
  }
5960
+ function convertAssignmentActionBinding(localResolver, implicitReceiver, action, bindingId, baseSourceSpan, implicitReceiverAccesses, globals) {
5961
+ localResolver != null ? localResolver : localResolver = new DefaultLocalResolver(globals);
5962
+ const visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId, false, baseSourceSpan, implicitReceiverAccesses);
5963
+ let convertedAction = convertActionBuiltins(action).visit(visitor, _Mode.Statement);
5964
+ if (!(convertedAction instanceof ExpressionStatement)) {
5965
+ throw new Error(`Illegal state: unsupported expression in two-way action binding.`);
5966
+ }
5967
+ convertedAction = wrapAssignmentAction(convertedAction.expr).toStmt();
5968
+ const actionStmts = [];
5969
+ flattenStatements(convertedAction, actionStmts);
5970
+ prependTemporaryDecls(visitor.temporaryCount, bindingId, actionStmts);
5971
+ actionStmts.push(new ReturnStatement(EventHandlerVars.event));
5972
+ implicitReceiverAccesses == null ? void 0 : implicitReceiverAccesses.add(EventHandlerVars.event.name);
5973
+ if (visitor.usesImplicitReceiver) {
5974
+ localResolver.notifyImplicitReceiverUse();
5975
+ }
5976
+ return actionStmts;
5977
+ }
5978
+ function wrapAssignmentReadExpression(ast) {
5979
+ return new ExternalExpr(Identifiers.twoWayBindingSet).callFn([ast, EventHandlerVars.event]).or(ast.set(EventHandlerVars.event));
5980
+ }
5981
+ function isReadExpression(value) {
5982
+ return value instanceof ReadPropExpr || value instanceof ReadKeyExpr;
5983
+ }
5984
+ function wrapAssignmentAction(ast) {
5985
+ if (isReadExpression(ast)) {
5986
+ return wrapAssignmentReadExpression(ast);
5987
+ }
5988
+ if (ast instanceof BinaryOperatorExpr && isReadExpression(ast.rhs)) {
5989
+ return new BinaryOperatorExpr(ast.operator, ast.lhs, wrapAssignmentReadExpression(ast.rhs));
5990
+ }
5991
+ if (ast instanceof ConditionalExpr && isReadExpression(ast.falseCase)) {
5992
+ return new ConditionalExpr(ast.condition, ast.trueCase, wrapAssignmentReadExpression(ast.falseCase));
5993
+ }
5994
+ if (ast instanceof NotExpr) {
5995
+ let expr = ast.condition;
5996
+ while (true) {
5997
+ if (expr instanceof NotExpr) {
5998
+ expr = expr.condition;
5999
+ } else {
6000
+ if (isReadExpression(expr)) {
6001
+ return wrapAssignmentReadExpression(expr);
6002
+ }
6003
+ break;
6004
+ }
6005
+ }
6006
+ }
6007
+ throw new Error(`Illegal state: unsupported expression in two-way action binding.`);
6008
+ }
5961
6009
  function convertPropertyBindingBuiltins(converterFactory, ast) {
5962
6010
  return convertBuiltins(converterFactory, ast);
5963
6011
  }
@@ -6019,6 +6067,27 @@ function convertBuiltins(converterFactory, ast) {
6019
6067
  const visitor = new _BuiltinAstConverter(converterFactory);
6020
6068
  return ast.visit(visitor);
6021
6069
  }
6070
+ function convertActionBuiltins(action) {
6071
+ const converterFactory = {
6072
+ createLiteralArrayConverter: () => {
6073
+ return (args) => literalArr(args);
6074
+ },
6075
+ createLiteralMapConverter: (keys) => {
6076
+ return (values) => {
6077
+ const entries = keys.map((k, i) => ({
6078
+ key: k.key,
6079
+ value: values[i],
6080
+ quoted: k.quoted
6081
+ }));
6082
+ return literalMap(entries);
6083
+ };
6084
+ },
6085
+ createPipeConverter: (name) => {
6086
+ throw new Error(`Illegal State: Actions are not allowed to contain pipes. Pipe: ${name}`);
6087
+ }
6088
+ };
6089
+ return convertPropertyBindingBuiltins(converterFactory, action);
6090
+ }
6022
6091
  function temporaryName(bindingId, temporaryNumber) {
6023
6092
  return `tmp_${bindingId}_${temporaryNumber}`;
6024
6093
  }
@@ -7123,16 +7192,18 @@ var OpKind;
7123
7192
  OpKind2[OpKind2["Projection"] = 33] = "Projection";
7124
7193
  OpKind2[OpKind2["RepeaterCreate"] = 34] = "RepeaterCreate";
7125
7194
  OpKind2[OpKind2["Repeater"] = 35] = "Repeater";
7126
- OpKind2[OpKind2["I18nStart"] = 36] = "I18nStart";
7127
- OpKind2[OpKind2["I18n"] = 37] = "I18n";
7128
- OpKind2[OpKind2["I18nEnd"] = 38] = "I18nEnd";
7129
- OpKind2[OpKind2["I18nExpression"] = 39] = "I18nExpression";
7130
- OpKind2[OpKind2["I18nApply"] = 40] = "I18nApply";
7131
- OpKind2[OpKind2["IcuStart"] = 41] = "IcuStart";
7132
- OpKind2[OpKind2["IcuEnd"] = 42] = "IcuEnd";
7133
- OpKind2[OpKind2["IcuPlaceholder"] = 43] = "IcuPlaceholder";
7134
- OpKind2[OpKind2["I18nContext"] = 44] = "I18nContext";
7135
- OpKind2[OpKind2["I18nAttributes"] = 45] = "I18nAttributes";
7195
+ OpKind2[OpKind2["TwoWayProperty"] = 36] = "TwoWayProperty";
7196
+ OpKind2[OpKind2["TwoWayListener"] = 37] = "TwoWayListener";
7197
+ OpKind2[OpKind2["I18nStart"] = 38] = "I18nStart";
7198
+ OpKind2[OpKind2["I18n"] = 39] = "I18n";
7199
+ OpKind2[OpKind2["I18nEnd"] = 40] = "I18nEnd";
7200
+ OpKind2[OpKind2["I18nExpression"] = 41] = "I18nExpression";
7201
+ OpKind2[OpKind2["I18nApply"] = 42] = "I18nApply";
7202
+ OpKind2[OpKind2["IcuStart"] = 43] = "IcuStart";
7203
+ OpKind2[OpKind2["IcuEnd"] = 44] = "IcuEnd";
7204
+ OpKind2[OpKind2["IcuPlaceholder"] = 45] = "IcuPlaceholder";
7205
+ OpKind2[OpKind2["I18nContext"] = 46] = "I18nContext";
7206
+ OpKind2[OpKind2["I18nAttributes"] = 47] = "I18nAttributes";
7136
7207
  })(OpKind || (OpKind = {}));
7137
7208
  var ExpressionKind;
7138
7209
  (function(ExpressionKind2) {
@@ -7162,6 +7233,7 @@ var ExpressionKind;
7162
7233
  ExpressionKind2[ExpressionKind2["ConditionalCase"] = 23] = "ConditionalCase";
7163
7234
  ExpressionKind2[ExpressionKind2["DerivedRepeaterVar"] = 24] = "DerivedRepeaterVar";
7164
7235
  ExpressionKind2[ExpressionKind2["ConstCollected"] = 25] = "ConstCollected";
7236
+ ExpressionKind2[ExpressionKind2["TwoWayBindingSet"] = 26] = "TwoWayBindingSet";
7165
7237
  })(ExpressionKind || (ExpressionKind = {}));
7166
7238
  var VariableFlags;
7167
7239
  (function(VariableFlags2) {
@@ -7195,6 +7267,7 @@ var BindingKind;
7195
7267
  BindingKind2[BindingKind2["Template"] = 4] = "Template";
7196
7268
  BindingKind2[BindingKind2["I18n"] = 5] = "I18n";
7197
7269
  BindingKind2[BindingKind2["Animation"] = 6] = "Animation";
7270
+ BindingKind2[BindingKind2["TwoWayProperty"] = 7] = "TwoWayProperty";
7198
7271
  })(BindingKind || (BindingKind = {}));
7199
7272
  var I18nParamResolutionTime;
7200
7273
  (function(I18nParamResolutionTime2) {
@@ -7349,6 +7422,21 @@ function createPropertyOp(target, name, expression, isAnimationTrigger, security
7349
7422
  sourceSpan
7350
7423
  }, TRAIT_DEPENDS_ON_SLOT_CONTEXT), TRAIT_CONSUMES_VARS), NEW_OP);
7351
7424
  }
7425
+ function createTwoWayPropertyOp(target, name, expression, securityContext, isStructuralTemplateAttribute, templateKind, i18nContext, i18nMessage, sourceSpan) {
7426
+ return __spreadValues(__spreadValues(__spreadValues({
7427
+ kind: OpKind.TwoWayProperty,
7428
+ target,
7429
+ name,
7430
+ expression,
7431
+ securityContext,
7432
+ sanitizer: null,
7433
+ isStructuralTemplateAttribute,
7434
+ templateKind,
7435
+ i18nContext,
7436
+ i18nMessage,
7437
+ sourceSpan
7438
+ }, TRAIT_DEPENDS_ON_SLOT_CONTEXT), TRAIT_CONSUMES_VARS), NEW_OP);
7439
+ }
7352
7440
  function createStylePropOp(xref, name, expression, unit, sourceSpan) {
7353
7441
  return __spreadValues(__spreadValues(__spreadValues({
7354
7442
  kind: OpKind.StyleProp,
@@ -7656,6 +7744,31 @@ var ResetViewExpr = class extends ExpressionBase {
7656
7744
  return new ResetViewExpr(this.expr.clone());
7657
7745
  }
7658
7746
  };
7747
+ var TwoWayBindingSetExpr = class extends ExpressionBase {
7748
+ constructor(target, value) {
7749
+ super();
7750
+ this.target = target;
7751
+ this.value = value;
7752
+ this.kind = ExpressionKind.TwoWayBindingSet;
7753
+ }
7754
+ visitExpression(visitor, context) {
7755
+ this.target.visitExpression(visitor, context);
7756
+ this.value.visitExpression(visitor, context);
7757
+ }
7758
+ isEquivalent(other) {
7759
+ return this.target.isEquivalent(other.target) && this.value.isEquivalent(other.value);
7760
+ }
7761
+ isConstant() {
7762
+ return false;
7763
+ }
7764
+ transformInternalExpressions(transform2, flags) {
7765
+ this.target = transformExpressionsInExpression(this.target, transform2, flags);
7766
+ this.value = transformExpressionsInExpression(this.value, transform2, flags);
7767
+ }
7768
+ clone() {
7769
+ return new TwoWayBindingSetExpr(this.target, this.value);
7770
+ }
7771
+ };
7659
7772
  var ReadVariableExpr = class extends ExpressionBase {
7660
7773
  constructor(xref) {
7661
7774
  super();
@@ -8107,6 +8220,10 @@ function transformExpressionsInOp(op, transform2, flags) {
8107
8220
  }
8108
8221
  op.sanitizer = op.sanitizer && transformExpressionsInExpression(op.sanitizer, transform2, flags);
8109
8222
  break;
8223
+ case OpKind.TwoWayProperty:
8224
+ op.expression = transformExpressionsInExpression(op.expression, transform2, flags);
8225
+ op.sanitizer = op.sanitizer && transformExpressionsInExpression(op.sanitizer, transform2, flags);
8226
+ break;
8110
8227
  case OpKind.I18nExpression:
8111
8228
  op.expression = transformExpressionsInExpression(op.expression, transform2, flags);
8112
8229
  break;
@@ -8134,6 +8251,7 @@ function transformExpressionsInOp(op, transform2, flags) {
8134
8251
  }
8135
8252
  break;
8136
8253
  case OpKind.Listener:
8254
+ case OpKind.TwoWayListener:
8137
8255
  for (const innerOp of op.handlerOps) {
8138
8256
  transformExpressionsInOp(innerOp, transform2, flags | VisitorContextFlag.InChildOperation);
8139
8257
  }
@@ -8615,6 +8733,20 @@ function createListenerOp(target, targetSlot, name, tag, handlerOps, animationPh
8615
8733
  sourceSpan
8616
8734
  }, NEW_OP);
8617
8735
  }
8736
+ function createTwoWayListenerOp(target, targetSlot, name, tag, handlerOps, sourceSpan) {
8737
+ const handlerList = new OpList();
8738
+ handlerList.push(handlerOps);
8739
+ return __spreadValues({
8740
+ kind: OpKind.TwoWayListener,
8741
+ target,
8742
+ targetSlot,
8743
+ tag,
8744
+ name,
8745
+ handlerOps: handlerList,
8746
+ handlerFnName: null,
8747
+ sourceSpan
8748
+ }, NEW_OP);
8749
+ }
8618
8750
  function createPipeOp(xref, slot, name) {
8619
8751
  return __spreadValues(__spreadValues({
8620
8752
  kind: OpKind.Pipe,
@@ -8865,7 +8997,7 @@ var CompilationUnit = class {
8865
8997
  *ops() {
8866
8998
  for (const op of this.create) {
8867
8999
  yield op;
8868
- if (op.kind === OpKind.Listener) {
9000
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
8869
9001
  for (const listenerOp of op.handlerOps) {
8870
9002
  yield listenerOp;
8871
9003
  }
@@ -9060,6 +9192,18 @@ function extractAttributes(job) {
9060
9192
  );
9061
9193
  }
9062
9194
  break;
9195
+ case OpKind.TwoWayProperty:
9196
+ OpList.insertBefore(createExtractedAttributeOp(
9197
+ op.target,
9198
+ BindingKind.TwoWayProperty,
9199
+ null,
9200
+ op.name,
9201
+ null,
9202
+ null,
9203
+ null,
9204
+ op.securityContext
9205
+ ), lookupElement(elements, op.target));
9206
+ break;
9063
9207
  case OpKind.StyleProp:
9064
9208
  case OpKind.ClassProp:
9065
9209
  if (unit.job.compatibility === CompatibilityMode.TemplateDefinitionBuilder && op.expression instanceof EmptyExpr2) {
@@ -9097,6 +9241,21 @@ function extractAttributes(job) {
9097
9241
  }
9098
9242
  }
9099
9243
  break;
9244
+ case OpKind.TwoWayListener:
9245
+ if (job.kind !== CompilationJobKind.Host) {
9246
+ const extractedAttributeOp = createExtractedAttributeOp(
9247
+ op.target,
9248
+ BindingKind.Property,
9249
+ null,
9250
+ op.name,
9251
+ null,
9252
+ null,
9253
+ null,
9254
+ SecurityContext.NONE
9255
+ );
9256
+ OpList.insertBefore(extractedAttributeOp, lookupElement(elements, op.target));
9257
+ }
9258
+ break;
9100
9259
  }
9101
9260
  }
9102
9261
  }
@@ -9170,6 +9329,12 @@ function specializeBindings(job) {
9170
9329
  OpList.replace(op, createPropertyOp(op.target, op.name, op.expression, op.bindingKind === BindingKind.Animation, op.securityContext, op.isStructuralTemplateAttribute, op.templateKind, op.i18nContext, op.i18nMessage, op.sourceSpan));
9171
9330
  }
9172
9331
  break;
9332
+ case BindingKind.TwoWayProperty:
9333
+ if (!(op.expression instanceof Expression)) {
9334
+ throw new Error(`Expected value of two-way property binding "${op.name}" to be an expression`);
9335
+ }
9336
+ OpList.replace(op, createTwoWayPropertyOp(op.target, op.name, op.expression, op.securityContext, op.isStructuralTemplateAttribute, op.templateKind, op.i18nContext, op.i18nMessage, op.sourceSpan));
9337
+ break;
9173
9338
  case BindingKind.I18n:
9174
9339
  case BindingKind.ClassName:
9175
9340
  case BindingKind.StyleProperty:
@@ -9206,7 +9371,9 @@ var CHAINABLE = /* @__PURE__ */ new Set([
9206
9371
  Identifiers.stylePropInterpolateV,
9207
9372
  Identifiers.syntheticHostListener,
9208
9373
  Identifiers.syntheticHostProperty,
9209
- Identifiers.templateCreate
9374
+ Identifiers.templateCreate,
9375
+ Identifiers.twoWayProperty,
9376
+ Identifiers.twoWayListener
9210
9377
  ]);
9211
9378
  function chain(job) {
9212
9379
  for (const unit of job.units) {
@@ -9415,7 +9582,7 @@ var ElementAttributes = class {
9415
9582
  }
9416
9583
  get bindings() {
9417
9584
  var _a2;
9418
- return (_a2 = this.byKind.get(BindingKind.Property)) != null ? _a2 : FLYWEIGHT_ARRAY;
9585
+ return (_a2 = this.propertyBindings) != null ? _a2 : FLYWEIGHT_ARRAY;
9419
9586
  }
9420
9587
  get template() {
9421
9588
  var _a2;
@@ -9429,6 +9596,7 @@ var ElementAttributes = class {
9429
9596
  this.compatibility = compatibility;
9430
9597
  this.known = /* @__PURE__ */ new Map();
9431
9598
  this.byKind = /* @__PURE__ */ new Map();
9599
+ this.propertyBindings = null;
9432
9600
  this.projectAs = null;
9433
9601
  }
9434
9602
  isKnown(kind, name, value) {
@@ -9470,10 +9638,16 @@ var ElementAttributes = class {
9470
9638
  }
9471
9639
  }
9472
9640
  arrayFor(kind) {
9473
- if (!this.byKind.has(kind)) {
9474
- this.byKind.set(kind, []);
9641
+ var _a2;
9642
+ if (kind === BindingKind.Property || kind === BindingKind.TwoWayProperty) {
9643
+ (_a2 = this.propertyBindings) != null ? _a2 : this.propertyBindings = [];
9644
+ return this.propertyBindings;
9645
+ } else {
9646
+ if (!this.byKind.has(kind)) {
9647
+ this.byKind.set(kind, []);
9648
+ }
9649
+ return this.byKind.get(kind);
9475
9650
  }
9476
- return this.byKind.get(kind);
9477
9651
  }
9478
9652
  };
9479
9653
  function getAttributeNameLiterals(namespace, name) {
@@ -9563,7 +9737,10 @@ function createDeferDepsFns(job) {
9563
9737
  const dependencies = [];
9564
9738
  for (const dep of op.metadata.deps) {
9565
9739
  if (dep.isDeferrable) {
9566
- const innerFn = arrowFn([new FnParam("m", DYNAMIC_TYPE)], variable("m").prop(dep.symbolName));
9740
+ const innerFn = arrowFn(
9741
+ [new FnParam("m", DYNAMIC_TYPE)],
9742
+ variable("m").prop(dep.isDefaultImport ? "default" : dep.symbolName)
9743
+ );
9567
9744
  const importExpr2 = new DynamicImportExpr(dep.importPath).prop("then").callFn([innerFn]);
9568
9745
  dependencies.push(importExpr2);
9569
9746
  } else {
@@ -10169,6 +10346,7 @@ function recursivelyProcessView(view, parentScope) {
10169
10346
  }
10170
10347
  break;
10171
10348
  case OpKind.Listener:
10349
+ case OpKind.TwoWayListener:
10172
10350
  op.handlerOps.prepend(generateVariablesInScopeForView(view, scope));
10173
10351
  break;
10174
10352
  }
@@ -10740,15 +10918,11 @@ var Parser = class {
10740
10918
  this._lexer = _lexer;
10741
10919
  this.errors = [];
10742
10920
  }
10743
- parseAction(input, isAssignmentEvent, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
10921
+ parseAction(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
10744
10922
  this._checkNoInterpolation(input, location, interpolationConfig);
10745
10923
  const sourceToLex = this._stripComments(input);
10746
10924
  const tokens = this._lexer.tokenize(sourceToLex);
10747
- let flags = 1;
10748
- if (isAssignmentEvent) {
10749
- flags |= 2;
10750
- }
10751
- const ast = new _ParseAST(input, location, absoluteOffset, tokens, flags, this.errors, 0).parseChain();
10925
+ const ast = new _ParseAST(input, location, absoluteOffset, tokens, 1, this.errors, 0).parseChain();
10752
10926
  return new ASTWithSource(ast, input, location, absoluteOffset, this.errors);
10753
10927
  }
10754
10928
  parseBinding(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
@@ -11101,7 +11275,7 @@ var _ParseAST = class {
11101
11275
  let result = this.parseExpression();
11102
11276
  if (this.consumeOptionalOperator("|")) {
11103
11277
  if (this.parseFlags & 1) {
11104
- this.error("Cannot have a pipe in an action expression");
11278
+ this.error(`Cannot have a pipe in an action expression`);
11105
11279
  }
11106
11280
  do {
11107
11281
  const nameStart = this.inputIndex;
@@ -11395,14 +11569,14 @@ var _ParseAST = class {
11395
11569
  const nameSpan = this.sourceSpan(nameStart);
11396
11570
  let receiver;
11397
11571
  if (isSafe) {
11398
- if (this.consumeOptionalAssignment()) {
11572
+ if (this.consumeOptionalOperator("=")) {
11399
11573
  this.error("The '?.' operator cannot be used in the assignment");
11400
11574
  receiver = new EmptyExpr(this.span(start), this.sourceSpan(start));
11401
11575
  } else {
11402
11576
  receiver = new SafePropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
11403
11577
  }
11404
11578
  } else {
11405
- if (this.consumeOptionalAssignment()) {
11579
+ if (this.consumeOptionalOperator("=")) {
11406
11580
  if (!(this.parseFlags & 1)) {
11407
11581
  this.error("Bindings cannot contain assignments");
11408
11582
  return new EmptyExpr(this.span(start), this.sourceSpan(start));
@@ -11426,14 +11600,6 @@ var _ParseAST = class {
11426
11600
  const sourceSpan = this.sourceSpan(start);
11427
11601
  return isSafe ? new SafeCall(span, sourceSpan, receiver, args, argumentSpan) : new Call(span, sourceSpan, receiver, args, argumentSpan);
11428
11602
  }
11429
- consumeOptionalAssignment() {
11430
- if (this.parseFlags & 2 && this.next.isOperator("!") && this.peek(1).isOperator("=")) {
11431
- this.advance();
11432
- this.advance();
11433
- return true;
11434
- }
11435
- return this.consumeOptionalOperator("=");
11436
- }
11437
11603
  parseCallArguments() {
11438
11604
  if (this.next.isCharacter($RPAREN))
11439
11605
  return [];
@@ -16641,7 +16807,7 @@ function nameFunctionsAndVariables(job) {
16641
16807
  }
16642
16808
  function addNamesToView(unit, baseName, state, compatibility) {
16643
16809
  if (unit.fnName === null) {
16644
- unit.fnName = sanitizeIdentifier(`${baseName}_${unit.job.fnSuffix}`);
16810
+ unit.fnName = unit.job.pool.uniqueName(sanitizeIdentifier(`${baseName}_${unit.job.fnSuffix}`), false);
16645
16811
  }
16646
16812
  const varNames = /* @__PURE__ */ new Map();
16647
16813
  for (const op of unit.ops()) {
@@ -16671,6 +16837,15 @@ function addNamesToView(unit, baseName, state, compatibility) {
16671
16837
  }
16672
16838
  op.handlerFnName = sanitizeIdentifier(op.handlerFnName);
16673
16839
  break;
16840
+ case OpKind.TwoWayListener:
16841
+ if (op.handlerFnName !== null) {
16842
+ break;
16843
+ }
16844
+ if (op.targetSlot.slot === null) {
16845
+ throw new Error(`Expected a slot to be assigned`);
16846
+ }
16847
+ op.handlerFnName = sanitizeIdentifier(`${unit.fnName}_${op.tag.replace("-", "_")}_${op.name}_${op.targetSlot.slot}_listener`);
16848
+ break;
16674
16849
  case OpKind.Variable:
16675
16850
  varNames.set(op.xref, getVariableName(unit, op.variable, state));
16676
16851
  break;
@@ -16759,7 +16934,7 @@ function stripImportant(name) {
16759
16934
  function mergeNextContextExpressions(job) {
16760
16935
  for (const unit of job.units) {
16761
16936
  for (const op of unit.create) {
16762
- if (op.kind === OpKind.Listener) {
16937
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
16763
16938
  mergeNextContextsInOps(op.handlerOps);
16764
16939
  }
16765
16940
  }
@@ -16873,9 +17048,15 @@ function kindWithInterpolationTest(kind, interpolation) {
16873
17048
  return op.kind === kind && interpolation === op.expression instanceof Interpolation2;
16874
17049
  };
16875
17050
  }
17051
+ function basicListenerKindTest(op) {
17052
+ return op.kind === OpKind.Listener && !(op.hostListener && op.isAnimationListener) || op.kind === OpKind.TwoWayListener;
17053
+ }
17054
+ function nonInterpolationPropertyKindTest(op) {
17055
+ return (op.kind === OpKind.Property || op.kind === OpKind.TwoWayProperty) && !(op.expression instanceof Interpolation2);
17056
+ }
16876
17057
  var CREATE_ORDERING = [
16877
17058
  { test: (op) => op.kind === OpKind.Listener && op.hostListener && op.isAnimationListener },
16878
- { test: (op) => op.kind === OpKind.Listener && !(op.hostListener && op.isAnimationListener) }
17059
+ { test: basicListenerKindTest }
16879
17060
  ];
16880
17061
  var UPDATE_ORDERING = [
16881
17062
  { test: kindTest(OpKind.StyleMap), transform: keepLast },
@@ -16884,7 +17065,7 @@ var UPDATE_ORDERING = [
16884
17065
  { test: kindTest(OpKind.ClassProp) },
16885
17066
  { test: kindWithInterpolationTest(OpKind.Attribute, true) },
16886
17067
  { test: kindWithInterpolationTest(OpKind.Property, true) },
16887
- { test: kindWithInterpolationTest(OpKind.Property, false) },
17068
+ { test: nonInterpolationPropertyKindTest },
16888
17069
  { test: kindWithInterpolationTest(OpKind.Attribute, false) }
16889
17070
  ];
16890
17071
  var UPDATE_HOST_ORDERING = [
@@ -16898,11 +17079,13 @@ var UPDATE_HOST_ORDERING = [
16898
17079
  ];
16899
17080
  var handledOpKinds = /* @__PURE__ */ new Set([
16900
17081
  OpKind.Listener,
17082
+ OpKind.TwoWayListener,
16901
17083
  OpKind.StyleMap,
16902
17084
  OpKind.ClassMap,
16903
17085
  OpKind.StyleProp,
16904
17086
  OpKind.ClassProp,
16905
17087
  OpKind.Property,
17088
+ OpKind.TwoWayProperty,
16906
17089
  OpKind.HostProperty,
16907
17090
  OpKind.Attribute
16908
17091
  ]);
@@ -17282,6 +17465,12 @@ function listener(name, handlerFn, eventTargetResolver, syntheticHost, sourceSpa
17282
17465
  }
17283
17466
  return call(syntheticHost ? Identifiers.syntheticHostListener : Identifiers.listener, args, sourceSpan);
17284
17467
  }
17468
+ function twoWayBindingSet(target, value) {
17469
+ return importExpr(Identifiers.twoWayBindingSet).callFn([target, value]);
17470
+ }
17471
+ function twoWayListener(name, handlerFn, sourceSpan) {
17472
+ return call(Identifiers.twoWayListener, [literal(name), handlerFn], sourceSpan);
17473
+ }
17285
17474
  function pipe(slot, name) {
17286
17475
  return call(Identifiers.pipe, [
17287
17476
  literal(slot),
@@ -17442,6 +17631,13 @@ function property(name, expression, sanitizer, sourceSpan) {
17442
17631
  }
17443
17632
  return call(Identifiers.property, args, sourceSpan);
17444
17633
  }
17634
+ function twoWayProperty(name, expression, sanitizer, sourceSpan) {
17635
+ const args = [literal(name), expression];
17636
+ if (sanitizer !== null) {
17637
+ args.push(sanitizer);
17638
+ }
17639
+ return call(Identifiers.twoWayProperty, args, sourceSpan);
17640
+ }
17445
17641
  function attribute(name, expression, sanitizer, namespace) {
17446
17642
  const args = [literal(name), expression];
17447
17643
  if (sanitizer !== null || namespace !== null) {
@@ -17818,6 +18014,9 @@ function reifyCreateOperations(unit, ops) {
17818
18014
  }
17819
18015
  OpList.replace(op, listener(op.name, listenerFn, eventTargetResolver, op.hostListener && op.isAnimationListener, op.sourceSpan));
17820
18016
  break;
18017
+ case OpKind.TwoWayListener:
18018
+ OpList.replace(op, twoWayListener(op.name, reifyListenerHandler(unit, op.handlerFnName, op.handlerOps, true), op.sourceSpan));
18019
+ break;
17821
18020
  case OpKind.Variable:
17822
18021
  if (op.variable.name === null) {
17823
18022
  throw new Error(`AssertionError: unnamed variable ${op.xref}`);
@@ -17924,6 +18123,9 @@ function reifyUpdateOperations(_unit, ops) {
17924
18123
  OpList.replace(op, property(op.name, op.expression, op.sanitizer, op.sourceSpan));
17925
18124
  }
17926
18125
  break;
18126
+ case OpKind.TwoWayProperty:
18127
+ OpList.replace(op, twoWayProperty(op.name, op.expression, op.sanitizer, op.sourceSpan));
18128
+ break;
17927
18129
  case OpKind.StyleProp:
17928
18130
  if (op.expression instanceof Interpolation2) {
17929
18131
  OpList.replace(op, stylePropInterpolate(op.name, op.expression.strings, op.expression.expressions, op.unit, op.sourceSpan));
@@ -18014,6 +18216,8 @@ function reifyIrExpression(expr) {
18014
18216
  return reference(expr.targetSlot.slot + 1 + expr.offset);
18015
18217
  case ExpressionKind.LexicalRead:
18016
18218
  throw new Error(`AssertionError: unresolved LexicalRead of ${expr.name}`);
18219
+ case ExpressionKind.TwoWayBindingSet:
18220
+ throw new Error(`AssertionError: unresolved TwoWayBindingSet`);
18017
18221
  case ExpressionKind.RestoreView:
18018
18222
  if (typeof expr.view === "number") {
18019
18223
  throw new Error(`AssertionError: unresolved RestoreView`);
@@ -18150,6 +18354,7 @@ function processLexicalScope(view, ops) {
18150
18354
  }
18151
18355
  break;
18152
18356
  case OpKind.Listener:
18357
+ case OpKind.TwoWayListener:
18153
18358
  processLexicalScope(view, op.handlerOps);
18154
18359
  break;
18155
18360
  }
@@ -18180,10 +18385,12 @@ function resolveDollarEvent(job) {
18180
18385
  }
18181
18386
  function transformDollarEvent(unit, ops) {
18182
18387
  for (const op of ops) {
18183
- if (op.kind === OpKind.Listener) {
18388
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18184
18389
  transformExpressionsInOp(op, (expr) => {
18185
18390
  if (expr instanceof LexicalReadExpr && expr.name === "$event") {
18186
- op.consumesDollarEvent = true;
18391
+ if (op.kind === OpKind.Listener) {
18392
+ op.consumesDollarEvent = true;
18393
+ }
18187
18394
  return new ReadVarExpr(expr.name);
18188
18395
  }
18189
18396
  return expr;
@@ -18453,12 +18660,13 @@ function processLexicalScope2(unit, ops, savedView) {
18453
18660
  }
18454
18661
  break;
18455
18662
  case OpKind.Listener:
18663
+ case OpKind.TwoWayListener:
18456
18664
  processLexicalScope2(unit, op.handlerOps, savedView);
18457
18665
  break;
18458
18666
  }
18459
18667
  }
18460
18668
  for (const op of ops) {
18461
- if (op.kind == OpKind.Listener) {
18669
+ if (op.kind == OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18462
18670
  continue;
18463
18671
  }
18464
18672
  transformExpressionsInOp(op, (expr, flags) => {
@@ -18558,6 +18766,53 @@ function getOnlySecurityContext(securityContext) {
18558
18766
  return securityContext;
18559
18767
  }
18560
18768
 
18769
+ // bazel-out/k8-fastbuild/bin/packages/compiler/src/template/pipeline/src/phases/transform_two_way_binding_set.mjs
18770
+ function transformTwoWayBindingSet(job) {
18771
+ for (const unit of job.units) {
18772
+ for (const op of unit.create) {
18773
+ if (op.kind === OpKind.TwoWayListener) {
18774
+ transformExpressionsInOp(op, (expr) => {
18775
+ if (expr instanceof TwoWayBindingSetExpr) {
18776
+ return wrapAction(expr.target, expr.value);
18777
+ }
18778
+ return expr;
18779
+ }, VisitorContextFlag.InChildOperation);
18780
+ }
18781
+ }
18782
+ }
18783
+ }
18784
+ function wrapSetOperation(target, value) {
18785
+ return twoWayBindingSet(target, value).or(target.set(value));
18786
+ }
18787
+ function isReadExpression2(value) {
18788
+ return value instanceof ReadPropExpr || value instanceof ReadKeyExpr;
18789
+ }
18790
+ function wrapAction(target, value) {
18791
+ if (isReadExpression2(target)) {
18792
+ return wrapSetOperation(target, value);
18793
+ }
18794
+ if (target instanceof BinaryOperatorExpr && isReadExpression2(target.rhs)) {
18795
+ return new BinaryOperatorExpr(target.operator, target.lhs, wrapSetOperation(target.rhs, value));
18796
+ }
18797
+ if (target instanceof ConditionalExpr && isReadExpression2(target.falseCase)) {
18798
+ return new ConditionalExpr(target.condition, target.trueCase, wrapSetOperation(target.falseCase, value));
18799
+ }
18800
+ if (target instanceof NotExpr) {
18801
+ let expr = target.condition;
18802
+ while (true) {
18803
+ if (expr instanceof NotExpr) {
18804
+ expr = expr.condition;
18805
+ } else {
18806
+ if (isReadExpression2(expr)) {
18807
+ return wrapSetOperation(expr, value);
18808
+ }
18809
+ break;
18810
+ }
18811
+ }
18812
+ }
18813
+ throw new Error(`Unsupported expression in two-way action binding.`);
18814
+ }
18815
+
18561
18816
  // bazel-out/k8-fastbuild/bin/packages/compiler/src/template/pipeline/src/phases/save_restore_view.mjs
18562
18817
  function saveAndRestoreView(job) {
18563
18818
  for (const unit of job.units) {
@@ -18569,7 +18824,7 @@ function saveAndRestoreView(job) {
18569
18824
  }, new GetCurrentViewExpr(), VariableFlags.None)
18570
18825
  ]);
18571
18826
  for (const op of unit.create) {
18572
- if (op.kind !== OpKind.Listener) {
18827
+ if (op.kind !== OpKind.Listener && op.kind !== OpKind.TwoWayListener) {
18573
18828
  continue;
18574
18829
  }
18575
18830
  let needsRestoreView = unit !== job.root;
@@ -18702,7 +18957,7 @@ function generateTemporaries(ops) {
18702
18957
  });
18703
18958
  generatedStatements.push(...Array.from(new Set(defs.values())).map((name) => createStatementOp(new DeclareVarStmt(name))));
18704
18959
  opCount++;
18705
- if (op.kind === OpKind.Listener) {
18960
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18706
18961
  op.handlerOps.prepend(generateTemporaries(op.handlerOps));
18707
18962
  }
18708
18963
  }
@@ -18882,6 +19137,8 @@ function varsUsedByOp(op) {
18882
19137
  slots += op.expression.expressions.length;
18883
19138
  }
18884
19139
  return slots;
19140
+ case OpKind.TwoWayProperty:
19141
+ return 1;
18885
19142
  case OpKind.StyleProp:
18886
19143
  case OpKind.ClassProp:
18887
19144
  case OpKind.StyleMap:
@@ -18931,14 +19188,14 @@ function optimizeVariables(job) {
18931
19188
  inlineAlwaysInlineVariables(unit.create);
18932
19189
  inlineAlwaysInlineVariables(unit.update);
18933
19190
  for (const op of unit.create) {
18934
- if (op.kind === OpKind.Listener) {
19191
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18935
19192
  inlineAlwaysInlineVariables(op.handlerOps);
18936
19193
  }
18937
19194
  }
18938
19195
  optimizeVariablesInOpList(unit.create, job.compatibility);
18939
19196
  optimizeVariablesInOpList(unit.update, job.compatibility);
18940
19197
  for (const op of unit.create) {
18941
- if (op.kind === OpKind.Listener) {
19198
+ if (op.kind === OpKind.Listener || op.kind === OpKind.TwoWayListener) {
18942
19199
  optimizeVariablesInOpList(op.handlerOps, job.compatibility);
18943
19200
  }
18944
19201
  }
@@ -19239,6 +19496,7 @@ var phases = [
19239
19496
  { kind: CompilationJobKind.Tmpl, fn: generateTrackVariables },
19240
19497
  { kind: CompilationJobKind.Both, fn: resolveNames },
19241
19498
  { kind: CompilationJobKind.Tmpl, fn: resolveDeferTargetNames },
19499
+ { kind: CompilationJobKind.Tmpl, fn: transformTwoWayBindingSet },
19242
19500
  { kind: CompilationJobKind.Tmpl, fn: optimizeTrackFns },
19243
19501
  { kind: CompilationJobKind.Both, fn: resolveContexts },
19244
19502
  { kind: CompilationJobKind.Both, fn: resolveSanitizers },
@@ -19897,7 +20155,7 @@ function convertAstWithInterpolation(job, value, i18nMeta, sourceSpan) {
19897
20155
  }
19898
20156
  var BINDING_KINDS = /* @__PURE__ */ new Map([
19899
20157
  [0, BindingKind.Property],
19900
- [5, BindingKind.Property],
20158
+ [5, BindingKind.TwoWayProperty],
19901
20159
  [1, BindingKind.Attribute],
19902
20160
  [2, BindingKind.ClassName],
19903
20161
  [3, BindingKind.StyleProperty],
@@ -19919,11 +20177,18 @@ function asMessage(i18nMeta) {
19919
20177
  function ingestElementBindings(unit, op, element2) {
19920
20178
  var _a2;
19921
20179
  let bindings = new Array();
20180
+ let i18nAttributeBindingNames = /* @__PURE__ */ new Set();
19922
20181
  for (const attr of element2.attributes) {
19923
20182
  const securityContext = domSchema.securityContext(element2.name, attr.name, true);
19924
20183
  bindings.push(createBindingOp(op.xref, BindingKind.Attribute, attr.name, convertAstWithInterpolation(unit.job, attr.value, attr.i18n), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
20184
+ if (attr.i18n) {
20185
+ i18nAttributeBindingNames.add(attr.name);
20186
+ }
19925
20187
  }
19926
20188
  for (const input of element2.inputs) {
20189
+ if (i18nAttributeBindingNames.has(input.name)) {
20190
+ console.error(`On component ${unit.job.componentName}, the binding ${input.name} is both an i18n attribute and a property. You may want to remove the property binding. This will become a compilation error in future versions of Angular.`);
20191
+ }
19927
20192
  bindings.push(createBindingOp(op.xref, BINDING_KINDS.get(input.type), input.name, convertAstWithInterpolation(unit.job, astOf(input.value), input.i18n), input.unit, input.securityContext, false, false, null, (_a2 = asMessage(input.i18n)) != null ? _a2 : null, input.sourceSpan));
19928
20193
  }
19929
20194
  unit.create.push(bindings.filter((b) => (b == null ? void 0 : b.kind) === OpKind.ExtractedAttribute));
@@ -19932,7 +20197,11 @@ function ingestElementBindings(unit, op, element2) {
19932
20197
  if (output.type === 1 && output.phase === null) {
19933
20198
  throw Error("Animation listener should have a phase");
19934
20199
  }
19935
- unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
20200
+ if (output.type === 2) {
20201
+ unit.create.push(createTwoWayListenerOp(op.xref, op.handle, output.name, op.tag, makeTwoWayListenerHandlerOps(unit, output.handler, output.handlerSpan), output.sourceSpan));
20202
+ } else {
20203
+ unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
20204
+ }
19936
20205
  }
19937
20206
  if (bindings.some((b) => b == null ? void 0 : b.i18nMessage) !== null) {
19938
20207
  unit.create.push(createI18nAttributesOp(unit.job.allocateXrefId(), new SlotHandle(), op.xref));
@@ -19962,7 +20231,11 @@ function ingestTemplateBindings(unit, op, template2, templateKind) {
19962
20231
  throw Error("Animation listener should have a phase");
19963
20232
  }
19964
20233
  if (templateKind === TemplateKind.NgTemplate) {
19965
- unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
20234
+ if (output.type === 2) {
20235
+ unit.create.push(createTwoWayListenerOp(op.xref, op.handle, output.name, op.tag, makeTwoWayListenerHandlerOps(unit, output.handler, output.handlerSpan), output.sourceSpan));
20236
+ } else {
20237
+ unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
20238
+ }
19966
20239
  }
19967
20240
  if (templateKind === TemplateKind.Structural && output.type !== 1) {
19968
20241
  const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, output.name, false);
@@ -19976,8 +20249,15 @@ function ingestTemplateBindings(unit, op, template2, templateKind) {
19976
20249
  function createTemplateBinding(view, xref, type, name, value, unit, securityContext, isStructuralTemplateAttribute, templateKind, i18nMessage, sourceSpan) {
19977
20250
  const isTextBinding = typeof value === "string";
19978
20251
  if (templateKind === TemplateKind.Structural) {
19979
- if (!isStructuralTemplateAttribute && (type === 0 || type === 5 || type === 2 || type === 3)) {
19980
- return createExtractedAttributeOp(xref, BindingKind.Property, null, name, null, null, i18nMessage, securityContext);
20252
+ if (!isStructuralTemplateAttribute) {
20253
+ switch (type) {
20254
+ case 0:
20255
+ case 2:
20256
+ case 3:
20257
+ return createExtractedAttributeOp(xref, BindingKind.Property, null, name, null, null, i18nMessage, securityContext);
20258
+ case 5:
20259
+ return createExtractedAttributeOp(xref, BindingKind.TwoWayProperty, null, name, null, null, i18nMessage, securityContext);
20260
+ }
19981
20261
  }
19982
20262
  if (!isTextBinding && (type === 1 || type === 4)) {
19983
20263
  return null;
@@ -20004,6 +20284,23 @@ function makeListenerHandlerOps(unit, handler, handlerSpan) {
20004
20284
  handlerOps.push(createStatementOp(new ReturnStatement(returnExpr, returnExpr.sourceSpan)));
20005
20285
  return handlerOps;
20006
20286
  }
20287
+ function makeTwoWayListenerHandlerOps(unit, handler, handlerSpan) {
20288
+ handler = astOf(handler);
20289
+ const handlerOps = new Array();
20290
+ if (handler instanceof Chain) {
20291
+ if (handler.expressions.length === 1) {
20292
+ handler = handler.expressions[0];
20293
+ } else {
20294
+ throw new Error("Expected two-way listener to have a single expression.");
20295
+ }
20296
+ }
20297
+ const handlerExpr = convertAst(handler, unit.job, handlerSpan);
20298
+ const eventReference = new LexicalReadExpr("$event");
20299
+ const twoWaySetExpr = new TwoWayBindingSetExpr(handlerExpr, eventReference);
20300
+ handlerOps.push(createStatementOp(new ExpressionStatement(twoWaySetExpr)));
20301
+ handlerOps.push(createStatementOp(new ReturnStatement(eventReference)));
20302
+ return handlerOps;
20303
+ }
20007
20304
  function astOf(ast) {
20008
20305
  return ast instanceof ASTWithSource ? ast.ast : ast;
20009
20306
  }
@@ -20370,7 +20667,7 @@ var BindingParser = class {
20370
20667
  if (keySpan !== void 0) {
20371
20668
  keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
20372
20669
  }
20373
- this._parseAnimationEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetEvents, keySpan);
20670
+ this._parseAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan);
20374
20671
  } else {
20375
20672
  this._parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan);
20376
20673
  }
@@ -20379,11 +20676,11 @@ var BindingParser = class {
20379
20676
  const prop = this._schemaRegistry.getMappedPropName(propName);
20380
20677
  return calcPossibleSecurityContexts(this._schemaRegistry, selector, prop, isAttribute);
20381
20678
  }
20382
- _parseAnimationEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetEvents, keySpan) {
20679
+ _parseAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan) {
20383
20680
  const matches = splitAtPeriod(name, [name, ""]);
20384
20681
  const eventName = matches[0];
20385
20682
  const phase = matches[1].toLowerCase();
20386
- const ast = this._parseAction(expression, isAssignmentEvent, handlerSpan);
20683
+ const ast = this._parseAction(expression, handlerSpan);
20387
20684
  targetEvents.push(new ParsedEvent(eventName, phase, 1, ast, sourceSpan, handlerSpan, keySpan));
20388
20685
  if (eventName.length === 0) {
20389
20686
  this._reportError(`Animation event name is missing in binding`, sourceSpan);
@@ -20398,15 +20695,20 @@ var BindingParser = class {
20398
20695
  }
20399
20696
  _parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
20400
20697
  const [target, eventName] = splitAtColon(name, [null, name]);
20401
- const ast = this._parseAction(expression, isAssignmentEvent, handlerSpan);
20698
+ const prevErrorCount = this.errors.length;
20699
+ const ast = this._parseAction(expression, handlerSpan);
20700
+ const isValid = this.errors.length === prevErrorCount;
20402
20701
  targetMatchableAttrs.push([name, ast.source]);
20702
+ if (isAssignmentEvent && isValid && !this._isAllowedAssignmentEvent(ast)) {
20703
+ this._reportError("Unsupported expression in a two-way binding", sourceSpan);
20704
+ }
20403
20705
  targetEvents.push(new ParsedEvent(eventName, target, isAssignmentEvent ? 2 : 0, ast, sourceSpan, handlerSpan, keySpan));
20404
20706
  }
20405
- _parseAction(value, isAssignmentEvent, sourceSpan) {
20707
+ _parseAction(value, sourceSpan) {
20406
20708
  const sourceInfo = (sourceSpan && sourceSpan.start || "(unknown").toString();
20407
20709
  const absoluteOffset = sourceSpan && sourceSpan.start ? sourceSpan.start.offset : 0;
20408
20710
  try {
20409
- const ast = this._exprParser.parseAction(value, isAssignmentEvent, sourceInfo, absoluteOffset, this._interpolationConfig);
20711
+ const ast = this._exprParser.parseAction(value, sourceInfo, absoluteOffset, this._interpolationConfig);
20410
20712
  if (ast) {
20411
20713
  this._reportExpressionParserErrors(ast.errors, sourceSpan);
20412
20714
  }
@@ -20434,6 +20736,21 @@ var BindingParser = class {
20434
20736
  this._reportError(report.msg, sourceSpan, ParseErrorLevel.ERROR);
20435
20737
  }
20436
20738
  }
20739
+ _isAllowedAssignmentEvent(ast) {
20740
+ if (ast instanceof ASTWithSource) {
20741
+ return this._isAllowedAssignmentEvent(ast.ast);
20742
+ }
20743
+ if (ast instanceof NonNullAssert) {
20744
+ return this._isAllowedAssignmentEvent(ast.expression);
20745
+ }
20746
+ if (ast instanceof PropertyRead || ast instanceof KeyedRead) {
20747
+ return true;
20748
+ }
20749
+ if (ast instanceof Binary) {
20750
+ return (ast.operation === "&&" || ast.operation === "||" || ast.operation === "??") && (ast.right instanceof PropertyRead || ast.right instanceof KeyedRead);
20751
+ }
20752
+ return ast instanceof Conditional || ast instanceof PrefixNot;
20753
+ }
20437
20754
  };
20438
20755
  function isAnimationLabel(name) {
20439
20756
  return name[0] == "@";
@@ -21598,7 +21915,7 @@ var HtmlAstToIvyAst = class {
21598
21915
  }
21599
21916
  parseAssignmentEvent(name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan) {
21600
21917
  const events = [];
21601
- this.bindingParser.parseEvent(`${name}Change`, `${expression} =$event`, true, sourceSpan, valueSpan || sourceSpan, targetMatchableAttrs, events, keySpan);
21918
+ this.bindingParser.parseEvent(`${name}Change`, expression, true, sourceSpan, valueSpan || sourceSpan, targetMatchableAttrs, events, keySpan);
21602
21919
  addEvents(events, boundEvents);
21603
21920
  }
21604
21921
  reportError(message, sourceSpan, level = ParseErrorLevel.ERROR) {
@@ -22171,7 +22488,7 @@ function prepareEventListenerParameters(eventAst, handlerName = null, scope = nu
22171
22488
  const eventArgumentName = "$event";
22172
22489
  const implicitReceiverAccesses = /* @__PURE__ */ new Set();
22173
22490
  const implicitReceiverExpr = scope === null || scope.bindingLevel === 0 ? variable(CONTEXT_NAME) : scope.getOrCreateSharedContextVar(0);
22174
- const bindingStatements = convertActionBinding(scope, implicitReceiverExpr, handler, "b", eventAst.handlerSpan, implicitReceiverAccesses, EVENT_BINDING_SCOPE_GLOBALS);
22491
+ const bindingStatements = eventAst.type === 2 ? convertAssignmentActionBinding(scope, implicitReceiverExpr, handler, "b", eventAst.handlerSpan, implicitReceiverAccesses, EVENT_BINDING_SCOPE_GLOBALS) : convertActionBinding(scope, implicitReceiverExpr, handler, "b", eventAst.handlerSpan, implicitReceiverAccesses, EVENT_BINDING_SCOPE_GLOBALS);
22175
22492
  const statements = [];
22176
22493
  const variableDeclarations = scope == null ? void 0 : scope.variableDeclarations();
22177
22494
  const restoreViewStatement = scope == null ? void 0 : scope.restoreViewStatement();
@@ -22597,7 +22914,7 @@ var TemplateDefinitionBuilder = class {
22597
22914
  }
22598
22915
  if (element2.outputs.length > 0) {
22599
22916
  for (const outputAst of element2.outputs) {
22600
- this.creationInstruction(outputAst.sourceSpan, Identifiers.listener, this.prepareListenerParameter(element2.name, outputAst, elementIndex));
22917
+ this.creationInstruction(outputAst.sourceSpan, outputAst.type === 2 ? Identifiers.twoWayListener : Identifiers.listener, this.prepareListenerParameter(element2.name, outputAst, elementIndex));
22601
22918
  }
22602
22919
  }
22603
22920
  if (isI18nRootElement) {
@@ -22621,6 +22938,7 @@ var TemplateDefinitionBuilder = class {
22621
22938
  this.allocateBindingSlots(value);
22622
22939
  propertyBindings.push({
22623
22940
  span: input.sourceSpan,
22941
+ reference: Identifiers.property,
22624
22942
  paramsOrFn: getBindingFunctionParams(() => hasValue ? this.convertPropertyBinding(value) : emptyValueBindInstruction, prepareSyntheticPropertyName(input.name))
22625
22943
  });
22626
22944
  } else {
@@ -22655,6 +22973,7 @@ var TemplateDefinitionBuilder = class {
22655
22973
  } else {
22656
22974
  propertyBindings.push({
22657
22975
  span: input.sourceSpan,
22976
+ reference: inputType === 5 ? Identifiers.twoWayProperty : Identifiers.property,
22658
22977
  paramsOrFn: getBindingFunctionParams(() => this.convertPropertyBinding(value), attrName, params)
22659
22978
  });
22660
22979
  }
@@ -22682,7 +23001,7 @@ var TemplateDefinitionBuilder = class {
22682
23001
  }
22683
23002
  });
22684
23003
  for (const propertyBinding of propertyBindings) {
22685
- this.updateInstructionWithAdvance(elementIndex, propertyBinding.span, Identifiers.property, propertyBinding.paramsOrFn);
23004
+ this.updateInstructionWithAdvance(elementIndex, propertyBinding.span, propertyBinding.reference, propertyBinding.paramsOrFn);
22686
23005
  }
22687
23006
  for (const attributeBinding of attributeBindings) {
22688
23007
  this.updateInstructionWithAdvance(elementIndex, attributeBinding.span, Identifiers.attribute, attributeBinding.paramsOrFn);
@@ -22712,7 +23031,7 @@ var TemplateDefinitionBuilder = class {
22712
23031
  }
22713
23032
  }
22714
23033
  const contextName = `${this.contextName}${contextNameSuffix}_${index}`;
22715
- const name = `${contextName}_Template`;
23034
+ const name = this.constantPool.uniqueName(`${contextName}_Template`, false);
22716
23035
  const visitor = new TemplateDefinitionBuilder(this.constantPool, this._bindingScope, this.level + 1, contextName, this.i18n, index, name, this._namespace, this.fileBasedI18nSuffix, this.i18nUseExternalIds, this.deferBlocks, this.elementLocations, this.allDeferrableDepsFn, this._constants);
22717
23036
  this._nestedTemplateFns.push(() => {
22718
23037
  const templateFunctionExpr = visitor.buildTemplateFunction(children, variables, this._ngContentReservedSlots.length + this._ngContentSelectorsOffset, i18nMeta, variableAliases);
@@ -22758,7 +23077,7 @@ var TemplateDefinitionBuilder = class {
22758
23077
  this.templatePropertyBindings(templateIndex, inputs);
22759
23078
  }
22760
23079
  for (const outputAst of template2.outputs) {
22761
- this.creationInstruction(outputAst.sourceSpan, Identifiers.listener, this.prepareListenerParameter("ng_template", outputAst, templateIndex));
23080
+ this.creationInstruction(outputAst.sourceSpan, outputAst.type === 2 ? Identifiers.twoWayListener : Identifiers.listener, this.prepareListenerParameter("ng_template", outputAst, templateIndex));
22762
23081
  }
22763
23082
  }
22764
23083
  }
@@ -22921,7 +23240,10 @@ var TemplateDefinitionBuilder = class {
22921
23240
  const dependencyExp = [];
22922
23241
  for (const deferredDep of metadata.deps) {
22923
23242
  if (deferredDep.isDeferrable) {
22924
- const innerFn = arrowFn([new FnParam("m", DYNAMIC_TYPE)], variable("m").prop(deferredDep.symbolName));
23243
+ const innerFn = arrowFn(
23244
+ [new FnParam("m", DYNAMIC_TYPE)],
23245
+ variable("m").prop(deferredDep.isDefaultImport ? "default" : deferredDep.symbolName)
23246
+ );
22925
23247
  const importExpr2 = new DynamicImportExpr(deferredDep.importPath).prop("then").callFn([innerFn]);
22926
23248
  dependencyExp.push(importExpr2);
22927
23249
  } else {
@@ -24035,8 +24357,8 @@ function compileDirectiveFromMetadata(meta, constantPool, bindingParser) {
24035
24357
  }
24036
24358
  function createDeferredDepsFunction(constantPool, name, deps) {
24037
24359
  const dependencyExp = [];
24038
- for (const [symbolName, importPath] of deps) {
24039
- const innerFn = arrowFn([new FnParam("m", DYNAMIC_TYPE)], variable("m").prop(symbolName));
24360
+ for (const [symbolName, { importPath, isDefaultImport }] of deps) {
24361
+ const innerFn = arrowFn([new FnParam("m", DYNAMIC_TYPE)], variable("m").prop(isDefaultImport ? "default" : symbolName));
24040
24362
  const importExpr2 = new DynamicImportExpr(importPath).prop("then").callFn([innerFn]);
24041
24363
  dependencyExp.push(importExpr2);
24042
24364
  }
@@ -25739,7 +26061,7 @@ function publishFacade(global) {
25739
26061
  }
25740
26062
 
25741
26063
  // bazel-out/k8-fastbuild/bin/packages/compiler/src/version.mjs
25742
- var VERSION2 = new Version("17.2.0-next.1");
26064
+ var VERSION2 = new Version("17.2.0-rc.1");
25743
26065
 
25744
26066
  // bazel-out/k8-fastbuild/bin/packages/compiler/src/i18n/extractor_merger.mjs
25745
26067
  var _VisitorMode;