Commit Graph

15337 Commits

Author SHA1 Message Date
Pawel Kozlowski 53bfa7c6d6 perf(ivy): improve NaN checks in change detection (#32212)
This commit drops our custom, change-detection specific, equality comparison util
in favour of the standard Object.is which has desired semantics.

There are multiple advantages of this approach:
- less code to maintain on our end;
- avoid NaN checks if both values are equal;
- re-write NaN checks so we don't trigger V8 deoptimizations.

PR Close #32212
2019-08-21 11:45:51 -07:00
Pawel Kozlowski 53f33c1cec perf(ivy): read selected index only when need in prop bindings (#32212)
PR Close #32212
2019-08-21 11:45:51 -07:00
Pawel Kozlowski 10629600c5 perf(ivy): split hooks processing into init and check phases (#32131)
Angular hooks come after 2 flavours:
- init hooks (OnInit, AfterContentInit, AfterViewInit);
- check hooks (OnChanges, DoChanges, AfterContentChecked, AfterViewChecked).

We need to do more processing for init hooks to ensure that those hooks
are run once and only once for a given directive (even in case of errors).
As soon as all init hooks execute to completion we are only left with the
checks to execute.

It turns out that keeping track of the remaining init hooks to execute is
rather expensive (multiple LView flags reads, writes and checks). But we can
observe that non of this tracking is needed as soon as all init hooks are
completed.

This PR takes advantage of the above observations and splits hooks processing
functions into:
- init-specific (slower but less common);
- check-specific (faster and more common).

NOTE: there is code duplication in this PR and it is left like this intentinally:
hand-inlining this perf-critical code makes the view refresh process substentially
faster.

PR Close #32131
2019-08-21 11:44:27 -07:00
Pawel Kozlowski 4d549f69f8 perf(ivy): auto-call select(0) for non-empty views only (#32131)
PR Close #32131
2019-08-21 11:44:27 -07:00
Kara Erickson de8ebbdfd0 feat(ivy): make Hammer support tree-shakable (#32203)
Currently, it's not possible to tree-shake away the
coordination layer between HammerJS and Angular's
EventManager. This means that you get the HammerJS
support code in your production bundle whether or
not you actually use the library.

This commit removes the Hammer providers from the
default platform_browser providers list and instead
provides them as part of a `HammerModule`. Apps on
Ivy just need to import the `HammerModule` at root
to turn on Hammer support. Otherwise all Hammer code
will tree-shake away. View Engine apps will require
no change.

BREAKING CHANGE

Previously, in Ivy applications, Hammer providers
were included by default. With this commit, apps
that want Hammer support must import `HammerModule`
in their root module.

PR Close #32203
2019-08-21 11:43:51 -07:00
Alex Rickabaugh 0287b234ea feat(ivy): convert all ngtsc diagnostics to ts.Diagnostics (#31952)
Historically, the Angular Compiler has produced both native TypeScript
diagnostics (called ts.Diagnostics) and its own internal Diagnostic format
(called an api.Diagnostic). This was done because TypeScript ts.Diagnostics
cannot be produced for files not in the ts.Program, and template type-
checking diagnostics are naturally produced for external .html template
files.

This design isn't optimal for several reasons:

1) Downstream tooling (such as the CLI) must support multiple formats of
diagnostics, adding to the maintenance burden.

2) ts.Diagnostics have gotten a lot better in recent releases, with support
for suggested changes, highlighting of the code in question, etc. None of
these changes have been of any benefit for api.Diagnostics, which have
continued to be reported in a very primitive fashion.

3) A future plugin model will not support anything but ts.Diagnostics, so
generating api.Diagnostics is a blocker for ngtsc-as-a-plugin.

4) The split complicates both the typings and the testing of ngtsc.

To fix this issue, this commit changes template type-checking to produce
ts.Diagnostics instead. Instead of reporting a special kind of diagnostic
for external template files, errors in a template are always reported in
a ts.Diagnostic that highlights the portion of the template which contains
the error. When this template text is distinct from the source .ts file
(for example, when the template is parsed from an external resource file),
additional contextual information links the error back to the originating
component.

A template error can thus be reported in 3 separate ways, depending on how
the template was configured:

1) For inline template strings which can be directly mapped to offsets in
the TS code, ts.Diagnostics point to real ranges in the source.

This is the case if an inline template is used with a string literal or a
"no-substitution" string. For example:

```typescript
@Component({..., template: `
<p>Bar: {{baz}}</p>
`})
export class TestCmp {
  bar: string;
}
```

The above template contains an error (no 'baz' property of `TestCmp`). The
error produced by TS will look like:

```
<p>Bar: {{baz}}</p>
          ~~~

test.ts:2:11 - error TS2339: Property 'baz' does not exist on type 'TestCmp'. Did you mean 'bar'?
```

2) For template strings which cannot be directly mapped to offsets in the
TS code, a logical offset into the template string will be included in
the error message. For example:

```typescript
const SOME_TEMPLATE = '<p>Bar: {{baz}}</p>';

@Component({..., template: SOME_TEMPLATE})
export class TestCmp {
  bar: string;
}
```

Because the template is a reference to another variable and is not an
inline string constant, the compiler will not be able to use "absolute"
positions when parsing the template. As a result, errors will report logical
offsets into the template string:

```
<p>Bar: {{baz}}</p>
          ~~~

test.ts (TestCmp template):2:15 - error TS2339: Property 'baz' does not exist on type 'TestCmp'.

  test.ts:3:28
    @Component({..., template: TEMPLATE})
                               ~~~~~~~~

    Error occurs in the template of component TestCmp.
```

This error message uses logical offsets into the template string, and also
gives a reference to the `TEMPLATE` expression from which the template was
parsed. This helps in locating the component which contains the error.

3) For external templates (templateUrl), the error message is delivered
within the HTML template file (testcmp.html) instead, and additional
information contextualizes the error on the templateUrl expression from
which the template file was determined:

```
<p>Bar: {{baz}}</p>
          ~~~

testcmp.html:2:15 - error TS2339: Property 'baz' does not exist on type 'TestCmp'.

  test.ts:10:31
    @Component({..., templateUrl: './testcmp.html'})
                                  ~~~~~~~~~~~~~~~~

    Error occurs in the template of component TestCmp.
```

PR Close #31952
2019-08-21 10:51:59 -07:00
Alex Rickabaugh bfc26bcd8c fix(ivy): run template type-checking for all components (#31952)
PR Close #31952
2019-08-21 10:51:59 -07:00
Paul Gschwendtner daac386f4d ci: update material-unit-tests commit (#32243)
Updates the SHA that will be tested against in the `material-unit-tests` job
to the latest commit in the components repository. SHA 18b9ef3f5529f0fa8f034944681486447af7b879
is needed in order to make the newly introduced material-ci test blocklist effective.

PR Close #32243
2019-08-21 10:41:51 -07:00
JoostK 0db1b5d8f1 fix(ivy): handle empty bindings in template type checker (#31594)
When a template contains a binding without a value, the template parser
creates an `EmptyExpr` node. This would previously be translated into
an `undefined` value, which would cause a crash downstream as `undefined`
is not included in the allowed type, so it was not handled properly.

This commit prevents the crash by returning an actual expression for empty
bindings.

Fixes #30076
Fixes #30929

PR Close #31594
2019-08-21 10:14:44 -07:00
George Kalpakas 8e1a725462 build(docs-infra): upgrade cli command docs sources to d2489aeda (#32236)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](6aae7f563...d2489aeda):

**Modified**
- help/generate.json

##

PR Close #32236
2019-08-21 10:09:35 -07:00
Alan 424ab48672 fix(compiler): return enableIvy true when using `readConfiguration` (#32234)
PR Close #32234
2019-08-21 10:06:25 -07:00
Paul Gschwendtner 62f4140634 build: add blocklist for material unit tests (#32239)
Initially the blocklist has been removed because there were
no remaining disabled tests that failed. Also the blocklist
logic didn't work anymore because the `material-unit-tests` CI
job now runs against `angular/components#master` with Bazel.

388578fec9 tried to revert the removal
of the blocklist in favor of a new upcoming breaking change with
HammerJS, but the revert doesn't help since the blocklist still
doesn't work with Bazel.

In order to make the blocklist work with the unit tests running
with Bazel, a PR has been submitted on the components repository.
See: https://github.com/angular/components/pull/16833.

This commit updates the blocklist logic on the framework side to
work with the new logic on the components repo side.

PR Close #32239
2019-08-21 10:03:01 -07:00
Miško Hevery 64770571b2 perf: don't create holey arrays (#32155)
Don't use `Array` constructor with the size value (ex. `new Array(5)`) - this will create a `HOLEY_ELEMENTS` array (even if this array is filled in later on!);

https://v8.dev/blog/elements-kinds
https://stackoverflow.com/questions/32054170/how-to-resize-an-array

PR Close #32155
2019-08-21 08:27:43 -07:00
Kara Erickson c957dfc167 docs: update collaborators page (#32229)
PR Close #32229
2019-08-21 08:26:43 -07:00
jenniferfell 10ea3a9f4d docs: change to global approvers (#31940)
PR Close #31940
2019-08-20 16:47:16 -07:00
Alex Rickabaugh ec4381dd40 feat: make the Ivy compiler the default for ngc (#32219)
This commit switches the default value of the enableIvy flag to true.
Applications that run ngc will now by default receive an Ivy build!

This does not affect the way Bazel builds in the Angular repo work, since
those are still switched based on the value of the --define=compile flag.
Additionally, projects using @angular/bazel still use View Engine builds
by default.

Since most of the Angular repo tests are still written against View Engine
(particularly because we still publish VE packages to NPM), this switch
also requires lots of `enableIvy: false` flags in tsconfigs throughout the
repo.

Congrats to the team for reaching this milestone!

PR Close #32219
2019-08-20 16:41:08 -07:00
Alex Rickabaugh 2b64031ddc refactor(ivy): remove the tsc passthrough option (#32219)
This option makes ngc behave as tsc, and was originally implemented before
ngtsc existed. It was designed so we could build JIT-only versions of
Angular packages to begin testing Ivy early, and is not used at all in our
current setup.

PR Close #32219
2019-08-20 16:41:08 -07:00
Kara Erickson 388578fec9 Revert "ci: remove material-unit-tests failure blocklist (#32138)" (#32226)
This reverts commit 0660903784 so we
can add some tests to the blocklist.

PR Close #32226
2019-08-20 16:39:54 -07:00
Kara Erickson dd6070a49b ci: update material commit we use to run integration tests (#32220)
We need to update the commit so we can make Hammer support optional in 32203.

PR Close #32220
2019-08-20 14:26:16 -07:00
Andrew Scott 3dbc4ab572 fix(ivy): get name directly from nativeNode (#32198)
nativeElement can return null so an error can occur when accessing
nodeName from nativeElement.

PR Close #32198
2019-08-20 09:57:17 -07:00
atscott cfed0c0cf1 fix(ivy): Support selector-less directive as base classes (#32125)
Following #31379, this adds support for directives without a selector to
Ivy.

PR Close #32125
2019-08-20 09:56:54 -07:00
Igor Minar bb3c684b98 ci: exclude the upstream g3 branch from building on CI (#32202)
We don't need to build this branch as it's informative for the purposes of figuring out
the diff between the master and what's synced into google3.

PR Close #32202
2019-08-20 09:55:55 -07:00
Elvis Begovic f8b995dbf9 fix(ngcc): ignore format properties that exist but are undefined (#32205)
Previously, `ngcc` assumed that if a format property was defined in
`package.json` it would point to a valid format-path (i.e. a file that
is an entry-point for a specific format). This is generally the case,
except if a format property is set to a non-string value (such as
`package.json`) - either directly in the `package.json` (which is unusual)
or in ngcc.config.js (which is a valid usecase, when one wants a
format property to be ignored by `ngcc`).

For example, the following config file would cause `ngcc` to throw:

```
module.exports = {
  packages: {
    'test-package': {
      entryPoints: {
        '.': {
          override: {
            fesm2015: undefined,
          },
        },
      },
    },
  },
};
```

This commit fixes it by ensuring that only format properties whose value
is a string are considered by `ngcc`.

For reference, this regression was introduced in #32052.

Fixes #32188

PR Close #32205
2019-08-20 09:55:25 -07:00
Paul Gschwendtner 639b732024 refactor(core): remove disabled injectable-pipe migration (#32184)
Initially the plan was to have a migration that adds `@Injectable()` to
all pipes in a CLI project so that the pipes can be injected in Ivy
similarly to how it worked in view engine.

Due to the planned refactorings which ensure that `@Directive`, `@Component`
and `@Pipe` also have a factory definition, this migration is no longer
needed for Ivy. Additionally since it is already disabled (due to
572b54967c) and we have a more generic
migration (known as `missing-injectable)` that could do the same as
`injectable-pipe`, we remove the migration from the code-base.

PR Close #32184
2019-08-19 15:44:02 -07:00
Alan Agius 5da5ca5c23 fix(bazel): pin `@microsoft/api-extractor` (#32187)
The API of `@microsoft/api-extractor` changed in a minor version which is causes an error when using dts flattening downstream.

API wil be updated on master https://github.com/angular/angular/pull/32185

PR Close #32187
2019-08-19 15:42:44 -07:00
Filipe Silva 0b1bf14cd8 ci: use circleci windows preview (#31266)
PR Close #31266
2019-08-19 13:32:14 -07:00
Filipe Silva d1cc7a0b26 ci: use no_output_timeout for long jobs (#31266)
PR Close #31266
2019-08-19 13:32:13 -07:00
Filipe Silva 431ddb9a45 test(bazel): use cross-platform file read of golden file (#31266)
PR Close #31266
2019-08-19 13:32:13 -07:00
Filipe Silva 7c2cd97e60 build: add reminder to keep engines in sync (#31266)
PR Close #31266
2019-08-19 13:32:13 -07:00
Kristiyan Kostadinov c2868de25a fix(ivy): ngTemplateOutlet error when switching between null and template value (#32160)
Fixes an error that is thrown by `ngTemplateOutlet` under Ivy when switching from a template to null and back to a template. The error is thrown because the reference to the previous ViewRef is never cleared and the directive tries to detach a view that has already been detached.

Fixes #32060.

PR Close #32160
2019-08-19 10:13:10 -07:00
Misko Hevery 994264c0ba refactor(ivy): simplify `walkTNodeTree` method for readability (#31065)
PR Close #31065
2019-08-19 10:12:38 -07:00
JoostK 4bbf16e654 fix(ngcc): handle deep imports that already have an extension (#32181)
During the dependency analysis phase of ngcc, imports are resolved to
files on disk according to certain module resolution rules. Since module
specifiers are typically missing extensions, or can refer to index.js
barrel files within a directory, the module resolver attempts several
postfixes when searching for a module import on disk. Module  specifiers
that already include an extension, however, would fail to be resolved as
ngcc's module resolver failed to check the location on disk without
adding any postfixes.

Closes #32097

PR Close #32181
2019-08-19 10:12:03 -07:00
JoostK ae142a6827 refactor(ngcc): avoid repeated file resolution during dependency scan (#32181)
During the recursive processing of dependencies, ngcc resolves the
requested file to an actual location on disk, by testing various
extensions. For recursive calls however, the path is known to have been
resolved in the module resolver. Therefore, it is safe to move the path
resolution to the initial caller into the recursive process.

Note that this is not expected to improve the performance of ngcc, as
the call to `resolveFileWithPostfixes` is known to succeed immediately,
as the provided path is known to exist without needing to add any
postfixes. Furthermore, the FileSystem caches whether files exist, so
the additional check that we used to do was cheap.

PR Close #32181
2019-08-19 10:12:03 -07:00
Judy Bogart e85ec23037 docs(service-worker): mention that dataGroups only cache non-mutating requests (#32142)
Fixes #28988

PR Close #32142
2019-08-19 10:11:28 -07:00
Pawel Kozlowski 172bb76964 docs(ivy): update micro-benchmark instructions (#32190)
PR Close #32190
2019-08-19 10:10:39 -07:00
George Kalpakas adb4f7c7cb build(docs-infra): upgrade cli command docs sources to 6aae7f563 (#32174)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](fe88669c9...6aae7f563):

**Modified**
- help/generate.json
- help/new.json

##

PR Close #32174
2019-08-19 10:09:42 -07:00
Keen Yee Liau 5f76de1d71 test(language-service): Fix diagnostic tests (#32161)
This commit fixes many diagnostic tests have have incorrect/uncaught assertions.
Also added more assertions to make sure TS diagnostics are clear.
A few test util methods are removed to reduce clutter and improve readability.

PR Close #32161
2019-08-16 15:26:05 -07:00
Keen Yee Liau 71ada483bf refactor(language-service): Omit typechecking for finding directives (#32156)
Remove unnecessary private method `getDeclarationFromNode` and moved
some logic to utils instead so that it can be tested in isolation of the
Language Service infrastructure.
The use of typechecker to check the directive is also not necessary,
since resolve.getNonNormalizedDirectiveMetadata() will check if the
directive is actually an Angular entity.

PR Close #32156
2019-08-16 09:58:28 -07:00
Andrew Kushnir abb44f7db0 perf(ivy): avoid for-of loops at runtime (#32157)
TypeScript downlevels `for-of` loops for ES5 targets. As a result, generated output contains extra code, including a try-catch block, which has code size and performance implications. This is especially important for runtime code where we want to keep it as small as possible. This commit changes `for-of` loops in runtime code to regular `for` loops.

PR Close #32157
2019-08-16 09:58:00 -07:00
Joey Perrott 43163523f6 ci: move bazel saucelabs execution to script to be used across all Angular repos (#32141)
PR Close #32141
2019-08-16 09:57:23 -07:00
JiaLiPassion ee486233e9 build(zone.js): update zone.js to 0.10.2 (#31975)
Bundle size changed in both zone.js(legacy) and zone-evergreen.js

- zone.js(legacy) package increased a little because the following feature and fixes.
1. #31699, handle MSPointer events PR
2. https://github.com/angular/zone.js/pull/1219 to add __zone_symbol__ customization support

- zone-evergreen.js package decreased because
1. the MSPointer PR only for legacy
2. the Object.defineProperty patch is moved to legacy #31660

PR Close #31975
2019-08-16 09:56:41 -07:00
Pawel Kozlowski 4c3b791ff3 perf(ivy): avoid first template pass checks during view creation (#32120)
PR Close #32120
2019-08-15 14:46:26 -07:00
Alex Rickabaugh 964d72610f fix(ivy): ngcc should only index .d.ts exports within the package (#32129)
ngcc needs to solve a unique problem when compiling typings for an
entrypoint: it must resolve a declaration within a .js file to its
representation in a .d.ts file. Since such .d.ts files can be used in deep
imports without ever being referenced from the "root" .d.ts, it's not enough
to simply match exported types to the root .d.ts. ngcc must build an index
of all .d.ts files.

Previously, this operation had a bug: it scanned all .d.ts files in the
.d.ts program, not only those within the package. Thus, if a class in the
program happened to share a name with a class exported from a dependency's
.d.ts, ngcc might accidentally modify the wrong .d.ts file, causing a
variety of issues downstream.

To fix this issue, ngcc's .d.ts scanner now limits the .d.ts files it
indexes to only those declared in the current package.

PR Close #32129
2019-08-15 14:46:00 -07:00
Alex Rickabaugh 02bab8cf90 fix(ivy): in ngcc, handle inline exports in commonjs code (#32129)
One of the compiler's tasks is to enumerate the exports of a given ES
module. This can happen for example to resolve `foo.bar` where `foo` is a
namespace import:

```typescript
import * as foo from './foo';

@NgModule({
  directives: [foo.DIRECTIVES],
})
```

In this case, the compiler must enumerate the exports of `foo.ts` in order
to evaluate the expression `foo.DIRECTIVES`.

When this operation occurs under ngcc, it must deal with the different
module formats and types of exports that occur. In commonjs code, a problem
arises when certain exports are downleveled.

```typescript
export const DIRECTIVES = [
  FooDir,
  BarDir,
];
```

can be downleveled to:

```javascript
exports.DIRECTIVES = [
  FooDir,
  BarDir,
```

Previously, ngtsc and ngcc expected that any export would have an associated
`ts.Declaration` node. `export class`, `export function`, etc. all retain
`ts.Declaration`s even when downleveled. But the `export const` construct
above does not. Therefore, ngcc would not detect `DIRECTIVES` as an export
of `foo.ts`, and the evaluation of `foo.DIRECTIVES` would therefore fail.

To solve this problem, the core concept of an exported `Declaration`
according to the `ReflectionHost` API is split into a `ConcreteDeclaration`
which has a `ts.Declaration`, and an `InlineDeclaration` which instead has
a `ts.Expression`. Differentiating between these allows ngcc to return an
`InlineDeclaration` for `DIRECTIVES` and correctly keep track of this
export.

PR Close #32129
2019-08-15 14:45:59 -07:00
Keen Yee Liau 69ce1c2d41 refactor(language-service): Cleanup diagnostics (#32152)
PR Close #32152
2019-08-15 12:51:46 -07:00
Keen Yee Liau 6a0b1d58ba fix(language-service): Instantiate MetadataResolver once (#32145)
Instead of destroying and recreating MetadataResolver every time the
program changes, create one instance and reuse it throughout the
lifetime of the language service.
Since Angular StaticSymbols are invalidated when program gets
out-of-date, this should be safe.
This should make the language service more more performant.

PR Close #32145
2019-08-15 12:51:02 -07:00
Kapunahele Wong 373d9660d0 docs: fix typo of Typescript to TypeScript (#32153)
PR Close #32153
2019-08-15 12:44:41 -07:00
Kapunahele Wong 1c6516199e docs: clarify hierarchical injectors (#28700)
PR Close #28700
2019-08-15 12:43:51 -07:00
George Kalpakas 3cf2005a93 build: add `ngcc` as a valid commit message scope (#32144)
PR Close #32144
2019-08-15 10:33:36 -07:00
Miško Hevery 2e4d17f3a9 perf(core): make sanitization tree-shakable in Ivy mode (#31934)
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 #31934
2019-08-15 10:30:12 -07:00