angular-cn/packages/core/test
JoostK 9514fd9080 fix(compiler): evaluate safe navigation expressions in correct binding order (#37911)
When using the safe navigation operator in a binding expression, a temporary
variable may be used for storing the result of a side-effectful call.
For example, the following template uses a pipe and a safe property access:

```html
<app-person-view [enabled]="enabled" [firstName]="(person$ | async)?.name"></app-person-view>
```

The result of the pipe evaluation is stored in a temporary to be able to check
whether it is present. The temporary variable needs to be declared in a separate
statement and this would also cause the full expression itself to be pulled out
into a separate statement. This would compile into the following
pseudo-code instructions:

```js
var temp = null;
var firstName = (temp = pipe('async', ctx.person$)) == null ? null : temp.name;
property('enabled', ctx.enabled)('firstName', firstName);
```

Notice that the pipe evaluation happens before evaluating the `enabled` binding,
such that the runtime's internal binding index would correspond with `enabled`,
not `firstName`. This introduces a problem when the pipe uses `WrappedValue` to
force a change to be detected, as the runtime would then mark the binding slot
corresponding with `enabled` as dirty, instead of `firstName`. This results
in the `enabled` binding to be updated, triggering setters and affecting how
`OnChanges` is called.

In the pseudo-code above, the intermediate `firstName` variable is not strictly
necessary---it only improved readability a bit---and emitting it inline with
the binding itself avoids the out-of-order execution of the pipe:

```js
var temp = null;
property('enabled', ctx.enabled)
  ('firstName', (temp = pipe('async', ctx.person$)) == null ? null : temp.name);
```

This commit introduces a new `BindingForm` that results in the above code to be
generated and adds compiler and acceptance tests to verify the proper behavior.

Fixes #37194

PR Close #37911
2020-08-11 09:51:10 -07:00
..
acceptance fix(compiler): evaluate safe navigation expressions in correct binding order (#37911) 2020-08-11 09:51:10 -07:00
animation build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
bundling refactor(forms): get rid of duplicate functions (#38371) 2020-08-07 11:40:04 -07:00
change_detection refactor(core): remove `looseIdentical` in favor of built-in `Object.is` (#37191) 2020-06-01 17:19:17 -04:00
debug feat(core): update reference and doc to change `async` to `waitAsync`. (#37583) 2020-08-03 12:54:13 -07:00
di build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
dom build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
i18n build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
linker feat(core): update reference and doc to change `async` to `waitAsync`. (#37583) 2020-08-03 12:54:13 -07:00
metadata build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
reflection build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
render3 refactor(core): break `i18n.ts` into smaller files (#38368) 2020-08-10 15:07:42 -07:00
sanitization fix(core): determine required DOMParser feature availability (#36578) (#36578) 2020-06-26 14:54:09 -07:00
strict_types build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
testability feat(core): update reference and doc to change `async` to `waitAsync`. (#37583) 2020-08-03 12:54:13 -07:00
util build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
view build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
zone feat(core): update reference and doc to change `async` to `waitAsync`. (#37583) 2020-08-03 12:54:13 -07:00
BUILD.bazel test(core): re-enable IE 10/11 test on SauceLabs (#35962) 2020-03-24 10:14:47 -07:00
application_init_spec.ts feat(core): update reference and doc to change `async` to `waitAsync`. (#37583) 2020-08-03 12:54:13 -07:00
application_module_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
application_ref_integration_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
application_ref_spec.ts feat(core): update reference and doc to change `async` to `waitAsync`. (#37583) 2020-08-03 12:54:13 -07:00
component_fixture_spec.ts feat(core): update reference and doc to change `async` to `waitAsync`. (#37583) 2020-08-03 12:54:13 -07:00
dev_mode_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
directive_lifecycle_integration_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
error_handler_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
event_emitter_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
fake_async_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
forward_ref_integration_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
spies.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
test_bed_async_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
test_bed_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
testing_internal_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
util_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00