Commit Graph
816 Commits
Author SHA1 Message Date
Pete Bacon Darwin 3c24136b98 fix(compiler): ensure JIT compilation of ɵɵngDeclarePipe() works (#40929)
Previously the compiler was not evaluating the JIT compilation
of `ɵɵngDeclarePipe()` but there was no test to check it.

PR Close #40929
2021-02-24 15:07:08 -08:00
Pete Bacon Darwin 9cb43fb507 refactor(compiler-cli): implement ɵɵngDeclarePipe() (#40803)
This commit implements creating of `ɵɵngDeclarePipe()` calls in partial
compilation, and processing of those calls in the linker and JIT compiler.

See #40677

PR Close #40803
2021-02-12 09:00:16 -08:00
Misko Hevery 1e4b51e9f7 fix(core): improve injector debug information in ngDevMode (#40476)
- `LViewDebug` now properly shows when `TNode` has `NO_NODE_INJECTOR`.
- Provide `injectorResolutionPath` property `DebugNode`

PR Close #40476
2021-01-22 10:21:25 -08:00
JoostK 69385f7df4 test(core): verify that token IDs that exceed the bloom filter size are handled correctly (#40489)
This commits adds additional expectations to verify that the bloom
filter is able to correctly handle token IDs that exceed the size of
the bloom filter (which is currently 256 bits).

PR Close #40489
2021-01-20 17:02:02 -08:00
twerske bfdca0b87f refactor(core): add links to top runtime errors (#40326)
add links to 5 runtime error messages
navigate user to AIO new /errors pages for debugging

PR Close #40326
2021-01-19 10:14:56 -08:00
Misko Hevery d516113803 refactor(core): Remove the need for explicit static query instruction (#40091)
Because the query now has `flags` which specify the mode, the static query
instruction can now be remove. It is simply normal query with `static` flag.

PR Close #40091
2021-01-14 13:55:02 -08:00
Misko Hevery e32b6256ce fix(core): QueryList should not fire changes if the underlying list did not change. (#40091)
Previous implementation would fire changes `QueryList.changes.subscribe`
whenever the `QueryList` was recomputed. This resulted in artificially
high number of change notifications, as it is possible that recomputing
`QueryList` results in the same list. When the `QueryList` gets recomputed
is an implementation detail and it should not be the thing which determines
how often change event should fire.

This change introduces a new `emitDistinctChangesOnly` option for
`ContentChildren` and `ViewChildren`.

```
export class QueryCompWithStrictChangeEmitParent {
  @ContentChildren('foo', {
    // This option will become the default in the future
    emitDistinctChangesOnly: true,
  })
  foos!: QueryList<any>;
}
```

PR Close #40091
2021-01-14 13:55:02 -08:00
JoostK b48eabddb8 refactor(compiler-cli): include template source directly inside declaration object (#40383)
The `template` and `isInline` fields were previously stored in a nested
object, which was initially done to accommodate for additional template
information to support accurate source maps for external templates. In
the meantime the source mapping has been accomplished in a different
way, and I feel this flattened structure is simpler and smaller so is
preferable over the nested object. This change also makes the `isInline`
property optional with a default value of `false`.

PR Close #40383
2021-01-11 15:37:12 -08:00
JoostK da6c739bb6 test(core): update test expectation to account for IE11 anonymous function name (#40342)
The "monitoring" workflow has been failing since #40127 was merged,
due to a Saucelabs test failure in Internet Explorer 11. The issue is
with the test's expectation which does not account for Ivy instruction
invocations to use "anonymous" instead of the instruction's function
name. This commit changes the test expectation to also accept
"anonymous", which was already the case for similar expectations.

PR Close #40342
2021-01-07 13:29:49 -08:00
JoostK d4327d51d1 feat(compiler-cli): JIT compilation of component declarations (#40127)
The `ɵɵngDeclareComponent` calls are designed to be translated to fully
AOT compiled code during a build transform, but in cases this is not
done it is still possible to compile the declaration object in the
browser using the JIT compiler. This commit adds a runtime
implementation of `ɵɵngDeclareComponent` which invokes the JIT compiler
using the declaration object, such that a compiled component definition
is made available to the Ivy runtime.

PR Close #40127
2021-01-06 08:28:03 -08:00
JoostK 826b77b632 test(core): tag render3 test targets as ivy-only (#40127)
The `render3` test targets are currently also executed for ViewEngine
builds, even though the `render3` infrastructure only concerns Ivy
infrastructure. This commit tags the test targets as ivy-only to disable
those tests for View Engine.

PR Close #40127
2021-01-06 08:28:03 -08:00
JoostK 9186f1feea feat(compiler-cli): JIT compilation of directive declarations (#40101)
The `ɵɵngDeclareDirective` calls are designed to be translated to fully
AOT compiled code during a build transform, but in cases this is not
done it is still possible to compile the declaration object in the
browser using the JIT compiler. This commit adds a runtime
implementation of `ɵɵngDeclareDirective` which invokes the JIT compiler
using the declaration object, such that a compiled directive definition
is made available to the Ivy runtime.

PR Close #40101
2020-12-23 09:52:19 -08:00
Kristiyan Kostadinov 11cd37fae3 fix(core): not invoking object's toString when rendering to the DOM (#39843)
Currently we convert objects to strings using `'' + value` which is quickest,
but it stringifies the value using its `valueOf`, rather than `toString`. These
changes switch to using `String(value)` which has identical performance
and calls the `toString` method as expected. Note that another option
was calling `toString` directly, but benchmarking showed it to be slower.

I've included the benchmark I used to verify the performance so we have it
for future reference and we can reuse it when making changes to `renderStringify`
in the future.

Also for reference, here are the results of the benchmark:

```
Benchmark: renderStringify
 concat: 2.006 ns(0%)
 concat with toString: 2.201 ns(-10%)
 toString: 237.494 ns(-11741%)
 toString with toString: 121.072 ns(-5937%)
 constructor: 2.201 ns(-10%)
 constructor with toString: 2.201 ns(-10%)
 toString mono: 14.536 ns(-625%)
 toString with toString mono: 9.757 ns(-386%)
```

Fixes #38839.

PR Close #39843
2020-11-30 15:49:57 -08:00
JoostK e75244ec00 feat(compiler-cli): support for partial compilation of components (#39707)
This commit implements partial compilation of components, together with
linking the partial declaration into its full AOT output.

This commit does not yet enable accurate source maps into external
templates. This requires additional work to account for escape sequences
which is non-trivial. Inline templates that were represented using a
string or template literal are transplated into the partial declaration
output, so their source maps should be accurate. Note, however, that
the accuracy of source maps is not currently verified in tests; this is
also left as future work.

The golden files of partial compilation output have been updated to
reflect the generated code for components. Please note that the current
output should not yet be considered stable.

PR Close #39707
2020-11-24 13:05:49 -08:00
Marcono1234 3e1e5a15ba docs: update links to use HTTPS as protocol (#39718)
PR Close #39718
2020-11-20 12:52:16 -08:00
JiaLiPassion 1cba56e11f refactor(core): remove unused fakeAsyncFallback and asyncFallback (#37879)
`zone.js` 0.8.25 introduces `zone-testing` bundle and move all `fakeAsync/async` logic
from `@angular/core/testing` to `zone.js` package. But in case some user still using the old
version of `zone.js`, an old version of `fakeAsync/async` logic were still kept inside `@angular/core/testing`
package as `fallback` logic. Since now `Angular8+` already use `zone.js 0.9+`, so
those fallback logic is removed.

PR Close #37879
2020-11-20 08:34:59 -08:00
cexbrayat 066126ae2f fix(core): remove duplicated noop function (#39761)
The codebase currently contains several `noop` functions,
and they can end up in the bundle of an application.
A recent commit 6fbe21941d tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating with @petebacondarwin,
we decided to remove the duplicated functions.

This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/noop`.

PR Close #39761
2020-11-19 12:14:12 -08:00
Misko Hevery 3b2e5be6cb refactor(core): clean up circular dependencies (#39722)
Clean up circular dependencies in core by pulling symbols out to their
respective files.

PR Close #39722
2020-11-18 09:15:29 -08:00
Misko Hevery 6d1d3c6a98 refactor(core): Remove circular dependency on render3 and ng_module (#39621)
Extracted `NgModeDef` into a separate file to break the circular dependency.

PR Close #39621
2020-11-16 09:12:46 -08:00
Misko Hevery 739d745eb5 refactor(core): Cleanup circular dependency between ViewEngine and Ivy ViewContainerRef. (#39621)
`ViewContainerRef` is declared in ViewEngine but it sub-classed in Ivy. This creates a circular
dependency between ViewEngine `ViewContainerRef` which needs to declare `__NG_ELEMENT_ID__` and
ivy factory which needs to create it. The workaround used to be to pass the `ViewContainerRef`
through stack but that created a very convoluted code. This refactoring simply bundles the
two files together and removes the stack workaround making the code simpler to follow.

PR Close #39621
2020-11-16 09:12:46 -08:00
Misko Hevery 453f196c4d refactor(core): Cleanup circular dependency between ViewEngine and Ivy TemplateRef. (#39621)
`TemplateRef` is declared in ViewEngine but it sub-classed in Ivy. This creates a circular
dependency between ViewEngine `TemplateRef` which needs to declare `__NG_ELEMENT_ID__` and
ivy factory which needs to create it. The workaround used to be to pass the `TemplateRef`
through stack but that created a very convoluted code. This refactoring simply bundles the
two files together and removes the stack workaround making the code simpler to follow.

PR Close #39621
2020-11-16 09:12:45 -08:00
Misko Hevery aa4924513b refactor(core): Cleanup circular dependency between ViewEngine and Ivy ElementRef. (#39621)
`ElementRef` is declared in ViewEngine but it sub-classed in Ivy. This creates a circular
dependency between ViewEngine `ElementRef` which needs to declare `__NG_ELEMENT_ID__` and
ivy factory which needs to create it. The workaround used to be to pass the `ElementRef`
through stack but that created a very convoluted code. This refactoring simply bundles the
two files together and removes the stack workaround making the code simpler to follow.

PR Close #39621
2020-11-16 09:12:45 -08:00
JoostK 8317042483 perf(core): do not recurse into modules that have already been registered (#39514)
When registering an NgModule based on its id, all transitively imported
NgModules are also registered. This commit introduces a visited set to
avoid traversing into NgModules that are reachable from multiple import
paths multiple times.

Fixes #39487

PR Close #39514
2020-11-02 07:51:18 -08:00
JiaLiPassion 4a8d5ae970 fix(core): markDirty() should only mark flags when really scheduling tick. (#39316)
Close #39296

Fix an issue that `markDirty()` will not trigger change detection.

The case is for example we have the following component.

```
export class AppComponent implements OnInit {
  constructor(private router: Router) {}

  ngOnInit() {
    this.router.events
      .pipe(filter((e) => e instanceof NavigationEnd))
      .subscribe(() => ɵmarkDirty(this));
  }
}

export class CounterComponent implements OnInit, OnDestroy {
  ngOnInit() {
    this.countSubject.pipe(takeUntil(this.destroy)).subscribe((count) => {
      this.count = count;
      ɵmarkDirty(this);
    });
  }
```

Then the app navigate from `AppComponent` to `CounterComponent`,
so there are 2 `markDirty()` call at in a row.

The `1st` call is from `AppComponent` when router changed, the
`2nd` call is from `CounterComponent.ngOnInit()`.

And the `markDirty()->scheduleTick()` code look like this

```
function scheduleTick(rootContext, flags) {
    const nothingScheduled = rootContext.flags === 0 /* Empty */;
    rootContext.flags |= flags;
    if (nothingScheduled && rootContext.clean == _CLEAN_PROMISE) {
      rootContext.schedule(() => {
	...
        if (rootContext.flags & RootContextFlags.DetectChanges)
          rootContext.flags &= ~RootContextFlags.DetectChanges;
          tickContext();

        rootContext.clean = _CLEAN_PROMISE;
        ...
      });
```

So in this case, the `1st` markDirty() will
1. set rootContext.flags = 1
2. before `tickContext()`, reset rootContext.flags = 0
3. inside `tickContext()`, it will call `CounterComponent.ngOnint()`,
   so the `2nd` markDirty() is called.
4. and the `2nd` scheduleTick is called, `nothingScheduled` is true,
   but rootContext.clean is not `_CLEAN_PROMISE` yet, since the `1st` markDirty tick
   is still running.
5. So nowhere will reset the `rootContext.flags`.
6. then in the future, any other `markDirty()` call will not trigger the tick, since
   `nothingScheduled` is always false.

So `nothingScheduled` means no tick is scheduled, `rootContext.clean === _CLEAN_PROMISE`
means no tick is running.
So we should set the flags to `rootContext` only when `no tick is scheudled or running`.

PR Close #39316
2020-10-29 16:07:10 -07:00
twerske e6ca3d3841 refactor(core): add top 10 runtime error codes (#39188)
adds RuntimeError and code enum to improve debugging experience
refactor ExpressionChangedAfterItHasBeenCheckedError to code NG0100
refactor CyclicDependency to code NG0200
refactor No Provider to code NG0201
refactor MultipleComponentsMatch to code NG0300
refactor ExportNotFound to code NG0301
refactor PipeNotFound to code NG0302
refactor BindingNotKnown to code NG0303
refactor NotKnownElement to code NG0304

PR Close #39188
2020-10-28 10:05:01 -07:00
Kristiyan Kostadinov 58408d6a60 fix(compiler): treat i18n attributes with no bindings as static attributes (#39408)
Currently `i18n` attributes are treated the same no matter if they have data bindings or not. This
both generates more code since they have to go through the `ɵɵi18nAttributes` instruction and
prevents the translated attributes from being injected using the `@Attribute` decorator.

These changes makes it so that static translated attributes are treated in the same way as regular
static attributes and all other `i18n` attributes go through the old code path.

Fixes #38231.

PR Close #39408
2020-10-27 13:31:29 -07:00
twerske dcafac1b8f refactor(core): group provider and circular errors (#39251)
group together similar error messages as part of error code efforts
ProviderNotFound & NodeInjector grouped into throwProviderNotFoundError
Cyclic dependency errors grouped into throwCyclicDependencyError

PR Close #39251
2020-10-22 13:42:34 -07:00
Misko Hevery 68d4de6770 refactor(core): Replace ExpandoInstructions with HostBindingOpCodes (#39301)
The `ExpandoInstructions` was unnecessarily convoluted way to solve the
problem of calling the `HostBindingFunction`s on components and
directives. The code was complicated and hard to fallow.

The replacement is a simplified way to achieve the same thing, which
is also more efficient in space and speed.

PR Close #39301
2020-10-22 09:35:48 -07:00
Misko Hevery 54303688fa refactor(core): Consistent use of HEADER_OFFSET (in ɵɵ* instructions only) (#39233)
IMPORTANT: `HEADER_OFFSET` should only be refereed to the in the `ɵɵ*` instructions to translate
instruction index into `LView` index. All other indexes should be in the `LView` index space and
there should be no need to refer to `HEADER_OFFSET` anywhere else.

PR Close #39233
2020-10-21 18:33:00 -07:00
Misko Hevery bc5005e35b refactor(core): cleanup i18n/icu data structures (#39233)
- Made `*OpCodes` array branded for safer type checking.
- Simplify `I18NRemoveOpCodes` encoding.
- Broke out  `IcuCreateOpCodes` from `I18nMutableOpCodes`.

PR Close #39233
2020-10-21 18:33:00 -07:00