360 Commits

Author SHA1 Message Date
Alex Rickabaugh
13c2fad240 fix(ivy): throw a better error when DI can't inject a ctor param ()
Occasionally a factory function needs to be generated for an "invalid"
constructor (one with parameters types which aren't injectable). Typically
this happens in JIT mode where understanding of parameters cannot be done in
the same "up-front" way that the AOT compiler can.

This commit changes the JIT compiler to generate a new `invalidFactoryDep`
call for each invalid parameter. This instruction will error at runtime if
called, indicating both the index of the invalid parameter as well as (via
the stack trace) the factory function which was generated for the type being
constructed.

Fixes 

PR Close 
2019-12-09 11:37:10 -08:00
Danny Skoog
c60d7563a8 style: enforce disallowance of object constructor ()
Applying the `prefer-literal` tslint rule to object enforces the style guide rule https://google.github.io/styleguide/jsguide.html#features-objects-ctor

PR Close 
2019-12-03 10:08:25 -08:00
crisbeto
953365d090 refactor(ivy): remove tsickle workaround in chainable instruction ()
Previously if a type was returning itself it would cause an infinite loop in tsickle. We worked around it with a type that alises to `any`. Now that the issue has been resolved in tsickle, we can clean up the workaround.

PR Close 
2019-11-25 22:36:00 -05:00
Igor Minar
ed55355363 fix(core): remove deprecated and defunct wtf* apis ()
These apis have been deprecated in v8, so they should stick around till v10,
but since they are defunct we are removing them early so that they don't take up payload size.

PR Close 
2019-11-25 18:39:18 -05:00
Alex Rickabaugh
bb290cefae fix(core): make QueryList implement Iterable in the type system ()
Originally, QueryList implemented Iterable and provided a Symbol.iterator
on its prototype. This caused issues with tree-shaking, so QueryList was
refactored and the Symbol.iterator added in its constructor instead. As
part of this change, QueryList no longer implemented Iterable directly.

Unfortunately, this meant that QueryList was no longer assignable to
Iterable or, consequently, NgIterable. NgIterable is used for NgFor's input,
so this meant that QueryList was not usable (in a type sense) for NgFor
iteration. View Engine's template type checking would not catch this, but
Ivy's did.

As a fix, this commit adds the declaration (but not the implementation) of
the Symbol.iterator function back to QueryList. This has no runtime effect,
so it doesn't affect tree-shaking of QueryList, but it ensures that
QueryList is assignable to NgIterable and thus usable with NgFor.

Fixes 

PR Close 
2019-11-19 13:43:53 -08:00
Kristiyan Kostadinov
8a052dc858 perf(ivy): chain styling instructions ()
Adds support for chaining of `styleProp`, `classProp` and `stylePropInterpolateX` instructions whenever possible which should help generate less code. Note that one complication here is for `stylePropInterpolateX` instructions where we have to break into multiple chains if there are other styling instructions inbetween the interpolations which helps maintain the execution order.

PR Close 
2019-11-19 11:44:29 -08:00
crisbeto
e31f62045d perf(ivy): chain listener instructions ()
Chains multiple listener instructions on a particular element into a single call which results in less generated code. Also handles listeners on templates, host listeners and synthetic host listeners.

PR Close 
2019-11-12 09:59:13 -08:00
JiaLiPassion
44623a1161 feat: add a flag in bootstrap to enable coalesce event change detection to improve performance ()
PR Close 
2019-11-05 18:58:25 +00:00
crisbeto
66725b7b37 perf(ivy): move local references into consts array ()
Follow-up from . Moves the local references array into the component def's `consts` in order to make it compress better.

Before:
```
const _c0 = ['foo', ''];

SomeComp.ngComponentDef = defineComponent({
  template: function() {
    element(0, 'div', null, _c0);
  }
});
```

After:
```
SomeComp.ngComponentDef = defineComponent({
  consts: [['foo', '']],
  template: function() {
    element(0, 'div', null, 0);
  }
});
```

PR Close 
2019-11-04 16:30:53 +00:00
crisbeto
c3e93564d0 perf(ivy): avoid generating selectors array for directives without a selector ()
Now that we've replaced `ngBaseDef` with an abstract directive definition, there are a lot more cases where we generate a directive definition without a selector. These changes make it so that we don't generate the `selectors` array if it's going to be empty.

PR Close 
2019-10-29 12:06:15 -07:00
crisbeto
14c4b1b205 refactor(ivy): remove ngBaseDef ()
Removes `ngBaseDef` from the compiler and any runtime code that was still referring to it. In the cases where we'd previously generate a base def we now generate a definition for an abstract directive.

PR Close 
2019-10-25 13:11:34 -07:00
JoostK
8d15bfa6ee fix(ivy): allow abstract directives to have an invalid constructor ()
For abstract directives, i.e. directives without a selector, it may
happen that their constructor is called explicitly from a subclass,
hence its parameters are not required to be valid for Angular's DI
purposes. Prior to this commit however, having an abstract directive
with a constructor that has parameters that are not eligible for
Angular's DI would produce a compilation error.

A similar scenario may occur for `@Injectable`s, where an explicit
`use*` definition allows for the constructor to be irrelevant. For
example, the situation where `useFactory` is specified allows for the
constructor to be called explicitly with any value, so its constructor
parameters are not required to be valid. For `@Injectable`s this is
handled by generating a DI factory function that throws.

This commit implements the same solution for abstract directives, such
that a compilation error is avoided while still producing an error at
runtime if the type is instantiated implicitly by Angular's DI
mechanism.

Fixes 

PR Close 
2019-10-25 12:13:23 -07:00
Alex Rickabaugh
818c514968 feat(ivy): add a runtime feature to copy cmp/dir definitions ()
This commit adds CopyDefinitionFeature, which supports the case where an
entire decorator (@Component or @Directive) is inherited from parent to
child.

The existing inheritance feature, InheritDefinitionFeature, supports merging
of parent and child definitions when both were originally present. This
merges things like inputs, outputs, host bindings, etc.

CopyDefinitionFeature, on the other hand, compensates for a definition that
was missing entirely on the child class, by copying fields that aren't
ordinarily inherited (like the template function itself).

This feature is intended to only be used as part of ngcc code generation.

PR Close 
2019-10-25 09:16:50 -07:00
crisbeto
1799f621b7 refactor(core): deprecate entryComponents ()
With Ivy the `entryComponents` array isn't necessary anymore. These changes mark it as deprecated so that it can be removed in a future version.

PR Close 
2019-10-18 16:29:23 -04:00
Igor Minar
86e1e6c082 feat: typescript 3.6 support ()
BREAKING CHANGE: typescript 3.4 and 3.5 are no longer supported, please update to typescript 3.6

Fixes 

PR Close 
2019-10-18 13:15:16 -04:00
Matias Niemelä
082aed6e46 revert: feat: add a flag in bootstrap to enable coalesce event change detection to improve performance () ()
This reverts commit 21c1e14385a61b4fdd3c5973abcaa3eace1303c1.

PR Close 
2019-10-17 12:50:04 -04:00
Kara Erickson
86104b82b8 refactor(core): rename ngInjectableDef to ɵprov ()
Injectable defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.

This commit adds the prefix and shortens the name from
ngInjectableDef to "prov" (for "provider", since injector defs
are known as "inj"). This is because property names cannot
be minified by Uglify without turning on property mangling
(which most apps have turned off) and are thus size-sensitive.

PR Close 
2019-10-16 16:36:19 -04:00
Kara Erickson
cda9248b33 refactor(core): rename ngInjectorDef to ɵinj ()
Injector defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.

This commit adds the prefix and shortens the name from
ngInjectorDef to inj. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.

PR Close 
2019-10-16 16:36:19 -04:00
JiaLiPassion
21c1e14385 feat: add a flag in bootstrap to enable coalesce event change detection to improve performance ()
PR Close 
2019-10-16 14:38:36 -04:00
crisbeto
d5b87d32b0 perf(ivy): move attributes array into component def ()
Currently Ivy stores the element attributes into an array above the component def and passes it into the relevant instructions, however the problem is that upon minification the array will get a unique name which won't compress very well. These changes move the attributes array into the component def and pass in the index into the instructions instead.

Before:
```
const _c0 = ['foo', 'bar'];

SomeComp.ngComponentDef = defineComponent({
  template: function() {
    element(0, 'div', _c0);
  }
});
```

After:
```
SomeComp.ngComponentDef = defineComponent({
  consts: [['foo', 'bar']],
  template: function() {
    element(0, 'div', 0);
  }
});
```

A couple of cases that this PR doesn't handle:
* Template references are still in a separate array.
* i18n attributes are still in a separate array.

PR Close 
2019-10-09 13:16:55 -07:00
crisbeto
2265cb5938 refactor(core): remove deprecated Renderer ()
Removes the `Renderer` and related symbols which have been deprecated since version 4.

BREAKING CHANGES:
* `Renderer` has been removed. Use `Renderer2` instead.
* `RenderComponentType` has been removed. Use `RendererType2` instead.
* `RootRenderer` has been removed. Use `RendererFactory2` instead.

PR Close 
2019-10-08 09:23:00 -07:00
Paul Gschwendtner
c1bb88603e fix(common): expand type for "ngForOf" input to work with strict null checks ()
Currently the `ngForOf` input accepts `null` or `undefined` as valid
values. Although when using strict template input type checking
(which will be supported by `ngtsc`), passing `null` or `undefined`
with strict null checks enabled causes a type check failure because
the type for the `ngForOf` input becomes too strict if strict null checks
are enabled. The type of the input needs to be expanded to also accept
`null` or `undefined` to behave consistently regardless of the
`strictNullChecks` flag.

This is necessary because whenever strict input type checking is enabled
by default, most of the Angular projects that use `*ngFor` with the async pipe
will either need to disable template type checking or strict null checks
because the `async` pipe returns `null` if the observable hasn't been
emitted yet.

See for example how this affects the `angular/components` repository and
how much bloat the workaround involves: https://github.com/angular/components/pull/16373/files#r296942696.

PR Close 
2019-10-07 11:01:22 -07:00
crisbeto
900d0055e0 feat(core): make static query flag optional ()
This is a re-submit of .

Switches back to having the static flag be optional on ViewChild and ContentChild queries, in preparation for changing its default value.

PR Close 
2019-10-03 14:02:47 -07:00
George Kalpakas
0f21ae9a74 docs(core): mark EventEmitter#__isAsync as internal to hide from API docs ()
The `__isAsync` property is not part of the public API and should not
appear in the API docs.

PR Close 
2019-10-03 10:24:34 -07:00
atscott
879ad69602 Revert "feat(core): make static query flag optional ()" ()
This reverts commit 25219baeb4ae037527fc367f37ff6453e352d4a1.

PR Close 
2019-10-02 10:39:49 -07:00
crisbeto
25219baeb4 feat(core): make static query flag optional ()
Switches back to having the `static` flag be optional on `ViewChild` and `ContentChild` queries, in preparation for changing its default value.

PR Close 
2019-10-02 09:39:05 -07:00
Matias Niemelä
4f41473048 refactor(ivy): remove styling state storage and introduce direct style writing ()
This patch is a final major refactor in styling Angular.

This PR includes three main fixes:

All temporary state taht is persisted between template style/class application
and style/class application in host bindings is now removed.
Removes the styling() and stylingApply() instructions.
Introduces a "direct apply" mode that is used apply prop-based
style/class in the event that there are no map-based bindings as
well as property collisions.

PR Close 

PR Close 
2019-09-16 14:12:48 -07:00
Carlos Ortiz García
a85eccd6ff feat(core): Deprecate TestBed.get as deprecated ()
From 9.0.0 use TestBed.inject
See 

Fixes 

PR Close 
2019-09-11 20:28:56 -04:00
Matias Niemelä
53dbff66d7 revert: refactor(ivy): remove styling state storage and introduce direct style writing ()
This reverts commit 15aeab16207fd6491e296db02501a14f92ff8e97.
2019-09-11 15:24:10 -07:00
Matias Niemelä
15aeab1620 refactor(ivy): remove styling state storage and introduce direct style writing () ()
This patch is a final major refactor in styling Angular.

This PR includes three main fixes:

All temporary state taht is persisted between template style/class application
and style/class application in host bindings is now removed.
Removes the styling() and stylingApply() instructions.
Introduces a "direct apply" mode that is used apply prop-based
style/class in the event that there are no map-based bindings as
well as property collisions.

PR Close 

PR Close 
2019-09-11 16:27:10 -04:00
Matias Niemelä
c84c27f7f4 revert: refactor(ivy): remove styling state storage and introduce direct style writing () 2019-09-10 18:08:05 -04:00
Matias Niemelä
3b37469735 refactor(ivy): remove styling state storage and introduce direct style writing ()
This patch is a final major refactor in styling Angular.

This PR includes three main fixes:

All temporary state taht is persisted between template style/class application
and style/class application in host bindings is now removed.
Removes the styling() and stylingApply() instructions.
Introduces a "direct apply" mode that is used apply prop-based
style/class in the event that there are no map-based bindings as
well as property collisions.

PR Close 
2019-09-10 15:54:58 -04:00
crisbeto
664e0015d4 perf(ivy): replace select instruction with advance ()
Replaces the `select` instruction with a new one called `advance`. Instead of the jumping to a specific index, the new instruction goes forward X amount of elements. The advantage of doing this is that it should generate code the compresses better.

PR Close 
2019-09-10 06:30:28 -04:00
Pete Bacon Darwin
c024d89448 refactor(ivy): remove i18nLocalize instruction ()
This has been replaced by the `$localize` tag.

PR Close 
2019-08-30 12:53:26 -07:00
Misko Hevery
77c382ccba feat(core): Adds DI support for providedIn: 'platform'|'any' ()
Extend the vocabulary of the `providedIn` to also include  `'platform'` and `'any'`` scope.
```
@Injectable({
  providedId: 'platform', // tree shakable injector for platform injector
})
class MyService {...}
```

PR Close 
2019-08-29 21:51:56 -07:00
Pawel Kozlowski
5635505f2e refactor(ivy): remove unused ɵɵtextBinding instruction ()
PR Close 
2019-08-28 21:37:15 -07:00
Carlos Ortiz García
3aba7ebe6a feat(core): Introduce TestBed.inject to replace TestBed.get ()
TestBed.get is not type safe, fixing it would be a massive breaking
change. The Angular team has proposed replacing it with TestBed.inject
and deprecate TestBed.get.

Deprecation from TestBed.get will come as a separate commit.

Issue 
Fixes 

BREAKING CHANGE: Injector.get now accepts abstract classes to return
type-safe values. Previous implementation returned `any` through the
deprecated implementation.

PR Close 
2019-08-28 21:26:46 -07:00
Pawel Kozlowski
a1e91b00d2 perf(ivy): remove renderStringify calls for text nodes creation ()
Values passed to the `ɵɵtext` instruction are strings (or undefined)
in the generated code so no need to stringify those again.

PR Close 
2019-08-28 17:12:38 -07:00
Kristiyan Kostadinov
c885178d5f refactor(ivy): move directive, component and pipe factories to ngFactoryFn ()
Reworks the compiler to output the factories for directives, components and pipes under a new static field called `ngFactoryFn`, instead of the usual `factory` property in their respective defs. This should eventually allow us to inject any kind of decorated class (e.g. a pipe).

**Note:** these changes are the first part of the refactor and they don't include injectables. I decided to leave injectables for a follow-up PR, because there's some more cases we need to handle when it comes to their factories. Furthermore, directives, components and pipes make up most of the compiler output tests that need to be refactored and it'll make follow-up PRs easier to review if the tests are cleaned up now.

This is part of the larger refactor for FW-1468.

PR Close 
2019-08-27 13:57:00 -07:00
Miško Hevery
2e4d17f3a9 perf(core): make sanitization tree-shakable in Ivy mode ()
In VE the `Sanitizer` is always available in `BrowserModule` because the VE retrieves it using injection.

In Ivy the injection is optional and we have instructions instead of component definition arrays. The implication of this is that in Ivy the instructions can pull in the sanitizer only when they are working with a property which is known to be unsafe. Because the Injection is optional this works even if no Sanitizer is present. So in Ivy we first use the sanitizer which is pulled in by the instruction, unless one is available through the `Injector` then we use that one instead.

This PR does few things:
1) It makes `Sanitizer` optional in Ivy.
2) It makes `DomSanitizer` tree shakable.
3) It aligns the semantics of Ivy `Sanitizer` with that of the Ivy sanitization rules.
4) It refactors `DomSanitizer` to use same functions as Ivy sanitization for consistency.

PR Close 
2019-08-15 10:30:12 -07:00
Alex Rickabaugh
4055150910 feat(compiler): allow selector-less directives as base classes ()
In Angular today, the following pattern works:

```typescript
export class BaseDir {
  constructor(@Inject(ViewContainerRef) protected vcr: ViewContainerRef) {}
}

@Directive({
  selector: '[child]',
})
export class ChildDir extends BaseDir {
  // constructor inherited from BaseDir
}
```

A decorated child class can inherit a constructor from an undecorated base
class, so long as the base class has metadata of its own (for JIT mode).
This pattern works regardless of metadata in AOT.

In Angular Ivy, this pattern does not work: without the @Directive
annotation identifying the base class as a directive, information about its
constructor parameters will not be captured by the Ivy compiler. This is a
result of Ivy's locality principle, which is the basis behind a number of
compilation optimizations.

As a solution, @Directive() without a selector will be interpreted as a
"directive base class" annotation. Such a directive cannot be declared in an
NgModule, but can be inherited from. To implement this, a few changes are
made to the ngc compiler:

* the error for a selector-less directive is now generated when an NgModule
  declaring it is processed, not when the directive itself is processed.
* selector-less directives are not tracked along with other directives in
  the compiler, preventing other errors (like their absence in an NgModule)
  from being generated from them.

PR Close 
2019-08-14 12:03:05 -07:00
Kristiyan Kostadinov
914900a561 refactor(ivy): remove load instruction ()
These changes remove the `ɵɵload` instruction which isn't being generated anymore.

PR Close 
2019-08-12 12:55:18 -07:00
Kristiyan Kostadinov
4ea3e7e000 refactor(ivy): combine query load instructions ()
Combines the `loadViewQuery` and `loadContentQuery` instructions since they have the exact same internal logic. Based on a discussion here: https://github.com/angular/angular/pull/32067#pullrequestreview-273001730

PR Close 
2019-08-12 10:32:08 -07:00
Kara Erickson
37de490e23 Revert "feat(compiler): allow selector-less directives as base classes ()" ()
This reverts commit f90c7a9df014d79a1a4065271c54f3dd4e758eda due to breakages in G3.

PR Close 
2019-08-09 18:20:53 -07:00
Alex Rickabaugh
f90c7a9df0 feat(compiler): allow selector-less directives as base classes ()
In Angular today, the following pattern works:

```typescript
export class BaseDir {
  constructor(@Inject(ViewContainerRef) protected vcr: ViewContainerRef) {}
}

@Directive({
  selector: '[child]',
})
export class ChildDir extends BaseDir {
  // constructor inherited from BaseDir
}
```

A decorated child class can inherit a constructor from an undecorated base
class, so long as the base class has metadata of its own (for JIT mode).
This pattern works regardless of metadata in AOT.

In Angular Ivy, this pattern does not work: without the @Directive
annotation identifying the base class as a directive, information about its
constructor parameters will not be captured by the Ivy compiler. This is a
result of Ivy's locality principle, which is the basis behind a number of
compilation optimizations.

As a solution, @Directive() without a selector will be interpreted as a
"directive base class" annotation. Such a directive cannot be declared in an
NgModule, but can be inherited from. To implement this, a few changes are
made to the ngc compiler:

* the error for a selector-less directive is now generated when an NgModule
  declaring it is processed, not when the directive itself is processed.
* selector-less directives are not tracked along with other directives in
  the compiler, preventing other errors (like their absence in an NgModule)
  from being generated from them.

PR Close 
2019-08-09 10:45:22 -07:00
Igor Minar
6ece7db37a build: TypeScript 3.5 upgrade ()
https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#typescript-35

PR Close 
2019-07-25 17:05:23 -07:00
crisbeto
3d7303efc0 perf(ivy): avoid extra parameter in query instructions ()
Currently we always generate the `read` parameter for the view and content query instructions, however since most of the time the `read` parameter won't be set, we'll end up generating `null` which adds 5 bytes for each query when minified. These changes make it so that the `read` parameter only gets generated if it has a value.

PR Close 
2019-07-24 14:37:51 -07:00
crisbeto
0aff4a6919 fix(ivy): incorrect ChangeDetectorRef injected into pipes used in component inputs ()
When injecting a `ChangeDetectorRef` into a pipe, the expected result is that the ref will be tied to the component in which the pipe is being used. This works for most cases, however when a pipe is used inside a property binding of a component (see test case as an example), the current `TNode` is pointing to component's host so we end up injecting the inner component's view. These changes fix the issue by only looking up the component view of the `TNode` if the `TNode` is a parent.

This PR resolves FW-1419.

PR Close 
2019-07-23 15:46:23 -07:00
Pawel Kozlowski
d52ae7cbab perf(ivy): match query results on the TView level ()
PR Close 
2019-07-19 20:38:08 -07:00
Matias Niemelä
9c954ebc62 refactor(ivy): make styling instructions use the new styling algorithm ()
This commit is the final patch of the ivy styling algorithm refactor.
This patch swaps functionality from the old styling mechanism to the
new refactored code by changing the instruction code the compiler
generates and by pointing the runtime instruction code to the new
styling algorithm.

PR Close 
2019-07-19 16:40:40 -07:00