1575 Commits

Author SHA1 Message Date
JoostK 76d7188872 fix(ngcc): consistently delegate to TypeScript host for typing files (#36089)
When ngcc is compiling an entry-point, it uses a `ReflectionHost` that
is specific to its format, e.g. ES2015, ES5, UMD or CommonJS. During the
compilation of that entry-point however, the reflector may be used to
reflect into external libraries using their declaration files.

Up until now this was achieved by letting all `ReflectionHost` classes
consider their parent class for reflector queries, thereby ending up in
the `TypeScriptReflectionHost` that is a common base class for all
reflector hosts. This approach has proven to be prone to bugs, as
failing to call into the base class would cause incompatibilities with
reading from declaration files.

The observation can be made that there's only two distinct kinds of
reflection host queries:
1. the reflector query is about code that is part of the entry-point
   that is being compiled, or
2. the reflector query is for an external library that the entry-point
   depends on, in which case the information is reflected
   from the declaration files.

The `ReflectionHost` that was chosen for the entry-point should serve
only reflector queries for the first case, whereas a regular
`TypeScriptReflectionHost` should be used for the second case. This
avoids the problem where a format-specific `ReflectionHost` fails to
handle the second case correctly, as it isn't even considered for such
reflector queries.

This commit introduces a `ReflectionHost` that delegates to the
`TypeScriptReflectionHost` for AST nodes within declaration files,
otherwise delegating to the format-specific `ReflectionHost`.

Fixes #35078
Resolves FW-1859

PR Close #36089
2020-03-17 13:34:06 -07:00
JoostK daa2179bb2 test(ngcc): use "module" format property for ES5 bundles (#36089)
The format property for ES5 bundles should be "module" or "es5"/"esm5",
but was "main" instead. The "main" property is appropriate for CommonJS
and UMD bundles, not for ES5 bundles.

PR Close #36089
2020-03-17 13:34:06 -07:00
Andrew Kushnir a6bf31b30e fix(compiler): support directive inputs with interpolations on <ng-template>s (#35984)
Prior to this commit, Ivy compiler didn't handle directive inputs with interpolations located on `<ng-template>` elements (e.g. `<ng-template dir="{{ field }}">`). That was the case for regular inputs as well as inputs that should be processed via i18n subsystem (e.g. `<ng-template i18n-dir dir="Hello {{ name }}">`). This commit adds support for such expressions for explicit `<ng-template>`s as well as a number of tests to confirm the behavior.

Fixes #35752.

PR Close #35984
2020-03-16 10:51:19 -07:00
Pete Bacon Darwin 4ce90985e7 perf(ngcc): store the position of SegmentMarkers to avoid unnecessary computation (#36027)
Previously, calculations related to the position of and difference between
SegmentMarkers required extensive computation based around the line,
line start positions and columns of each segment.

PR Close #36027
2020-03-13 08:00:30 -07:00
Pete Bacon Darwin a0fa63b7ca perf(ngcc): link segment markers for faster traversal (#36027)
The merging algorithm needs to find, for a given segment, what the next
segment in the source file is. This change modifies the `generatedSegment`
properties in the mappings so that they have a link directly to the following
segment.

PR Close #36027
2020-03-13 08:00:30 -07:00
Pete Bacon Darwin daa2a08b99 perf(ngcc): use line start positions for computing offsets in source-map flattening (#36027)
By computing and caching the start of each line, rather than the length
of each line, we can save a lot of duplicated computation in the `segmentDiff()`
and `offsetSegment()` functions.

PR Close #36027
2020-03-13 08:00:30 -07:00
Pete Bacon Darwin e6167cfe57 fix(ngcc): handle multiple original sources when flattening source-maps (#36027)
Previously the list of original segments that was searched for incoming
mappings did not differentiate between different original source files.

Now there is a separate array of segments to search for each of the
original source files.

PR Close #36027
2020-03-13 08:00:30 -07:00
Pete Bacon Darwin 8768fc4de4 perf(ngcc): use binary search when flattening mappings (#36027)
The `@angular/core` package has a large number of source files
and mappings which exposed performance issues in the new source-map
flattening algorithm.

This change uses a binary search (rather than linear) when finding
matching mappings to merge. Initial measurements indicate that this
reduces processing time for `@angular/core` by about 50%.

PR Close #36027
2020-03-13 08:00:30 -07:00
Pete Bacon Darwin d03da9c041 test(ngcc): remove unused FileSystem variable (#36027)
PR Close #36027
2020-03-13 08:00:30 -07:00
Alan Agius 13abbeb289 build: provide full paths to ts_api_guardian_test_npm_package and ts_api_guardian_test (#36034)
ts-api-guardian uses `require.resolve` to resolve the actual and golden files under bazel. In Windows for these files to be resolved correct the full path including the workspace name as per the MANIFEST entries is required.

This used to be the case until the recent changes done to use npm_integration tests

https://github.com/angular/angular/blob/83c74ceacf620535673ec141fc8a1003aed187ef/tools/public_api_guard/public_api_guard.bzl#L19
https://github.com/angular/angular/blob/83c74ceacf620535673ec141fc8a1003aed187ef/tools/public_api_guard/public_api_guard.bzl#L28

```
bazel test //packages/... --test_tag_filters=api_guard

//packages/animations:animations_api                            (cached) PASSED in 18.4s
//packages/common:common_api                                    (cached) PASSED in 25.5s
//packages/compiler-cli:compiler_options_api                    (cached) PASSED in 12.4s
//packages/compiler-cli:error_code_api                          (cached) PASSED in 11.6s
//packages/core:core_api                                        (cached) PASSED in 20.6s
//packages/core:ng_global_utils_api                             (cached) PASSED in 13.5s
//packages/elements:elements_api                                (cached) PASSED in 11.9s
//packages/forms:forms_api                                      (cached) PASSED in 13.9s
//packages/http:http_api                                        (cached) PASSED in 14.8s
//packages/localize:localize_api                                (cached) PASSED in 6.3s
//packages/platform-browser:platform-browser_api                (cached) PASSED in 18.1s
//packages/platform-browser-dynamic:platform-browser-dynamic_api (cached) PASSED in 14.0s
//packages/platform-server:platform-server_api                  (cached) PASSED in 13.9s
//packages/platform-webworker:platform-webworker_api            (cached) PASSED in 13.7s
//packages/platform-webworker-dynamic:platform-webworker-dynamic_api (cached) PASSED in 11.7s
//packages/router:router_api                                    (cached) PASSED in 19.9s
//packages/service-worker:service-worker_api                    (cached) PASSED in 18.1s
//packages/upgrade:upgrade_api                                  (cached) PASSED in 13.5s
```

Reference: DEV-71

PR Close #36034
2020-03-12 09:49:01 -07:00
Pete Bacon Darwin 2c5dd3fe71 refactor(ngcc): remove unused LockFileWithSignalHandlers (#35934)
PR Close #35934
2020-03-11 15:07:10 -07:00
Pete Bacon Darwin 743ce7b964 fix(ngcc): a new LockFile implementation that uses a child-process (#35934)
This version of `LockFile` creates an "unlocker" child-process that monitors
the main ngcc process and deletes the lock file if it exits unexpectedly.

This resolves the issue where the main process could not be killed by pressing
Ctrl-C at the terminal.

Fixes #35761

PR Close #35934
2020-03-11 15:07:09 -07:00
Pete Bacon Darwin f2295448f3 refactor(ngcc): move locking code into its own folder (#35934)
PR Close #35934
2020-03-11 15:07:09 -07:00
Pete Bacon Darwin 3f930fd186 refactor(ngcc): separate SyncLocker and LockFile (#35934)
The previous implementation mixed up the management
of locking a piece of code with the management of writing
and removing the lockFile that is used as the flag for
which process has locked the code.

This change splits these two concepts up, allowing the `LockFile`
implementation to be replaced cleanly.

PR Close #35934
2020-03-11 15:07:09 -07:00
Pete Bacon Darwin 1d04f98170 refactor(ngcc): expose logging level on the logger (#35934)
PR Close #35934
2020-03-11 15:07:09 -07:00
Joey Perrott 04ef34ca10 ci: move public-api goldens to goldens directory (#35768)
Moves the public api .d.ts files from tools/public_api_guard to
goldens/public-api.

Additionally, provides a README in the goldens directory and a script
assist in testing the current state of the repo against the goldens as
well as a command for accepting all changes to the goldens in a single
command.

PR Close #35768
2020-03-10 20:58:40 -04:00
Andrew Kushnir 6f2fd6e4b4 fix(compiler): process imports first and declarations second while calculating scopes (#35850)
Prior to this commit, while calculating the scope for a module, Ivy compiler processed `declarations` field first and `imports` after that. That results in a couple issues:

* for Pipes with the same `name` and present in `declarations` and in an imported module, Pipe from imported module was selected. In View Engine the logic is opposite: Pipes from `declarations` field receive higher priority.
* for Directives with the same selector and present in `declarations` and in an imported module, we first invoked the logic of a Directive from `declarations` field and after that - imported Directive logic. In View Engine, it was the opposite and the logic of a Directive from the `declarations` field was invoked last.

In order to align Ivy and View Engine behavior, this commit updates the logic in which we populate module scope: we first process all imports and after that handle `declarations` field. As a result, in Ivy both use-cases listed above work similar to View Engine.

Resolves #35502.

PR Close #35850
2020-03-10 14:16:59 -04:00
Alex Rickabaugh 0d784e0b00 test(compiler): add a public API guard for the public compiler options (#35885)
This commit adds a public API test which guards against unintentional
changes to the accepted keys in `angularCompilerOptions`.

PR Close #35885
2020-03-10 14:15:29 -04:00
Alex Rickabaugh 8b0e26f786 refactor(compiler): split core/api.ts into multiple files (#35885)
This commit splits the ngtsc `core` package's api entrypoint, which
previously was a single `api.ts` file, into an api/ directory with multiple
files. This is done to isolate the parts of the API definitions pertaining
to the public-facing `angularCompilerOptions` field in tsconfig.json into a
single file, which will enable a public API guard test to be added in a
future commit.

PR Close #35885
2020-03-10 14:15:29 -04:00
Doug Parker d24ce21c45 fix(core): remove side effects from ɵɵNgOnChangesFeature() (#35769) (#35846)
`ɵɵNgOnChangesFeature()` would set `ngInherit`, which is a side effect and also not necessary. This was pulled out to module scope so the function itself can be pure. Since it only curries another function, the call is entirely unnecessary. Updated the compiler to only generate a reference to this function, rather than a call to it, and removed the extra curry indirection.

PR Close #35769

(cherry picked from commit 9cf85d2177)

PR Close #35846
2020-03-06 17:30:47 -05:00
Alan Agius 2eaf420bdf perf(ngcc): reduce directory traversing (#35756)
This reduces the time that `findEntryPoints` takes from 9701.143ms to 4177.278ms, by reducing the file operations done.

Reference: #35717

PR Close #35756
2020-03-05 15:57:31 -05:00
Alex Rickabaugh 12072954de fix(compiler): type-checking error for duplicate variables in templates (#35674)
It's an error to declare a variable twice on a specific template:

```html
<div *ngFor="let i of items; let i = index">
</div>
```

This commit introduces a template type-checking error which helps to detect
and diagnose this problem.

Fixes #35186

PR Close #35674
2020-03-03 13:52:50 -08:00
Alan Agius 3fdd304b03 perf(ngcc): only create tasks for non-processed formats (#35719) (#35832)
Change the behaviour in `analyzeEntryPoints` to only create tasks for non-processed formats.

PR Close #35719

PR Close #35832
2020-03-03 13:35:48 -08:00
Alan Agius 525dc6a036 perf(ngcc): spawn workers lazily (#35719) (#35832)
With this change we spawn workers lazily based on the amount of work that needs to be done.

Before this change we spawned the maximum of workers possible. However, in some cases there are less tasks than the max number of workers which resulted in created unnecessary workers

Reference: #35717

PR Close #35719

PR Close #35832
2020-03-03 13:35:48 -08:00
Andrew Kushnir d1966fc29b fix(compiler): support i18n attributes on <ng-template> tags (#35681)
Prior to this commit, i18n attributes defined on `<ng-template>` tags were not processed by the compiler. This commit adds the necessary logic to handle i18n attributes in the same way how these attrs are processed for regular elements.

PR Close #35681
2020-03-02 08:18:06 -08:00
JoostK fcad075ade fix(ivy): narrow NgIf context variables in template type checker (#35125)
When the `NgIf` directive is used in a template, its context variables
can be used to capture the bound value. This is typically used together
with a pipe or function call, where the resulting value is captured in a
context variable. There's two syntax forms available:

1. Binding to `NgIfContext.ngIf` using the `as` syntax:
```html
<span *ngIf="(user$ | async) as user">{{user.name}}</span>
```

2. Binding to `NgIfContext.$implicit` using the `let` syntax:
```html
<span *ngIf="user$ | async; let user">{{user.name}}</span>
```

Because of the semantics of `ngIf`, it is known that the captured
context variable is non-nullable, however the template type checker
would not consider them as such and still report errors when
`strictNullTypes` is enabled.

This commit updates `NgIf`'s context guard to make the types of the
context variables non-nullable, avoiding the issue.

Fixes #34572

PR Close #35125
2020-02-28 07:39:57 -08:00
JoostK 52fc08754d fix(ivy): support dynamic query tokens in AOT mode (#35307)
For view and content queries, the Ivy compiler attempts to statically
evaluate the predicate token so that string predicates containing
comma-separated reference names can be split into an array of strings
during compilation. When the predicate is a dynamic value that cannot be
statically interpreted at compile time, the compiler would previously
produce an error. This behavior breaks a use-case where an `InjectionToken`
is being used as query predicate, as the usage of the `new` keyword
prevents such predicates from being statically evaluated.

This commit changes the behavior to no longer produce an error for
dynamic values. Instead, the expression is emitted as is into the
generated code, postponing the evaluation to happen at runtime.

Fixes #34267
Resolves FW-1828

PR Close #35307
2020-02-27 16:05:22 -08:00
Pete Bacon Darwin 9b53054ea8 refactor(ngcc): guard against a crash if source-map flattening fails (#35718)
Source-maps in the wild could be badly formatted,
causing the source-map flattening processing to fail
unexpectedly. Rather than causing the whole of ngcc
to crash, we gracefully fallback to just returning the
generated source-map instead.

PR Close #35718
2020-02-27 16:09:37 -05:00
Pete Bacon Darwin bfe7657006 fix(ngcc): handle mappings outside the content when flattening source-maps (#35718)
Previously when rendering flattened source-maps, it was assumed that no
mapping would come from a line that is outside the lines of the actual
source content. It turns out this is not a valid assumption.

Now the code that renders flattened source-maps will handle such
mappings, with the additional benefit that the rendered source-map
will only contain mapping lines up to the last mapping, rather than a
mapping line for every content line.

Fixes #35709

PR Close #35718
2020-02-27 16:09:37 -05:00
Pete Bacon Darwin 7ff845b72f fix(ngcc): handle missing sources when flattening source-maps (#35718)
If a package has a source-map but it does not provide
the actual content of the sources, then the source-map
flattening was crashing.

Now we ignore such mappings that have no source
since we are not able to compute the merged
mapping if there is no source file.

Fixes #35709

PR Close #35718
2020-02-27 16:09:37 -05:00
Pete Bacon Darwin 9064f4ecdb fix(ngcc): allow deep-import warnings to be ignored (#35683)
This commit adds a new ngcc configuration, `ignorableDeepImportMatchers`
for packages. This is a list of regular expressions matching deep imports
that can be safely ignored from that package. Deep imports that are not
ignored cause a warning to be logged.

// FW-1892

Fixes #35615

PR Close #35683
2020-02-27 10:48:49 -08:00
Alex Rickabaugh 4c2bd64642 fix(ivy): better inference for circularly referenced directive types (#35622)
It's possible to pass a directive as an input to itself. Consider:

```html
<some-cmp #ref [value]="ref">
```

Since the template type-checker attempts to infer a type for `<some-cmp>`
using the values of its inputs, this creates a circular reference where the
type of the `value` input is used in its own inference:

```typescript
var _t0 = SomeCmp.ngTypeCtor({value: _t0});
```

Obviously, this doesn't work. To resolve this, the template type-checker
used to generate a `null!` expression when a reference would otherwise be
circular:

```typescript
var _t0 = SomeCmp.ngTypeCtor({value: null!});
```

This effectively asks TypeScript to infer a value for this context, and
works well to resolve this simple cycle. However, if the template
instead tries to use the circular value in a larger expression:

```html
<some-cmp #ref [value]="ref.prop">
```

The checker would generate:

```typescript
var _t0 = SomeCmp.ngTypeCtor({value: (null!).prop});
```

In this case, TypeScript can't figure out any way `null!` could have a
`prop` key, and so it infers `never` as the type. `(never).prop` is thus a
type error.

This commit implements a better fallback pattern for circular references to
directive types like this. Instead of generating a `null!` in place for the
reference, a type is inferred by calling the type constructor again with
`null!` as its input. This infers the widest possible type for the directive
which is then used to break the cycle:

```typescript
var _t0 = SomeCmp.ngTypeCtor(null!);
var _t1 = SomeCmp.ngTypeCtor({value: _t0.prop});
```

This has the desired effect of validating that `.prop` is legal for the
directive type (the type of `#ref`) while also avoiding a cycle.

Fixes #35372
Fixes #35603
Fixes #35522

PR Close #35622
2020-02-26 12:57:10 -08:00
Alex Rickabaugh e6c416fe74 fix(ivy): provide a more detailed error message for NG6002/NG6003 (#35620)
NG6002/NG6003 are errors produced when an NgModule being compiled has an
imported or exported type which does not have the proper metadata (that is,
it doesn't appear to be an @NgModule, or @Directive, etc. depending on
context).

Previously this error message was a bit sparse. However, Github issues show
that this is the most common error users receive when for whatever reason
ngcc wasn't able to handle one of their libraries, or they just didn't run
it. So this commit changes the error message to offer a bit more useful
context, instructing users differently depending on whether the class in
question is from their own project, from NPM, or from a monorepo-style local
dependency.

PR Close #35620
2020-02-26 12:56:48 -08:00
Pete Bacon Darwin 0a8e8cd1f3 feat(ngcc): implement source-map flattening (#35132)
The library used by ngcc to update the source files (MagicString) is able
to generate a source-map but it is not able to account for any previous
source-map that the input text is already associated with.

There have been various attempts to fix this but none have been very
successful, since it is not a trivial problem to solve.

This commit contains a novel approach that is able to load up a tree of
source-files connected by source-maps and flatten them down into a single
source-map that maps directly from the final generated file to the original
sources referenced by the intermediate source-maps.

PR Close #35132
2020-02-26 12:51:36 -08:00
Felix Becker c9cac92628 build(packaging): add repository.directory field to package.jsons (#27544)
PR Close #27544
2020-02-25 13:12:46 -08:00
Pete Bacon Darwin d83f62d30a fix(ngcc): capture path-mapped entry-points that start with same string (#35592)
Previously if there were two path-mapped libraries that are in
different directories but the path of one started with same string
as the path of the other, we would incorrectly return the shorter
path - e.g. `dist/my-lib` and `dist/my-lib-second`. This was because
the list of `basePaths` was searched in ascending alphabetic order and
we were using `startsWith()` to match the path.

Now the `basePaths` are searched in reverse alphabetic order so the
longer path will be matched correctly.

// FW-1873

Fixes #35536

PR Close #35592
2020-02-24 09:11:44 -08:00
Greg Magolan 2f572772b0 build: add npm_integration_test && angular_integration_test (#33927)
* it's tricky to get out of the runfiles tree with `bazel test` as `BUILD_WORKSPACE_DIRECTORY` is not set but I employed a trick to read the `DO_NOT_BUILD_HERE` file that is one level up from `execroot` and that contains the workspace directory. This is experimental and if `bazel test //:test.debug` fails than `bazel run` is still guaranteed to work as  `BUILD_WORKSPACE_DIRECTORY` will be set in that context

* test //integration:bazel_test and //integration:bazel-schematics_test exclusively

* run "exclusive" and "manual" bazel-in-bazel integration tests in their own CI job as they take 8m+ to execute

```
//integration:bazel-schematics_test                                      PASSED in 317.2s
//integration:bazel_test                                                 PASSED in 167.8s
```

* Skip all integration tests that are now handled by angular_integration_test except the tests that are tracked for payload size; these are:
- cli-hello-world*
- hello_world__closure

* add & pin @babel deps as newer versions of babel break //packages/localize/src/tools/test:test

@babel/core dep had to be pinned to 7.6.4 or else //packages/localize/src/tools/test:test failed. Also //packages/localize uses @babel/generator, @babel/template, @babel/traverse & @babel/types so these deps were added to package.json as they were not being hoisted anymore from @babel/core transitive.

NB: integration/hello_world__systemjs_umd test must run with systemjs 0.20.0
NB: systemjs must be at 0.18.10 for legacy saucelabs job to pass
NB: With Bazel 2.0, the glob for the files to test `"integration/bazel/**"` is empty if integation/bazel is in .bazelignore. This glob worked under these conditions with 1.1.0. I did not bother testing with 1.2.x as not having integration/bazel in .bazelignore is correct.

PR Close #33927
2020-02-24 08:59:20 -08:00
Alex Rickabaugh 628f957c4a fix(ivy): add strictLiteralTypes to align Ivy + VE checking of literals (#35462)
Under View Engine's default (non-fullTemplateTypeCheck) checking, object and
array literals which appear in templates are treated as having type `any`.
This allows a number of patterns which would not otherwise compile, such as
indexing an object literal by a string:

```html
{{ {'a': 1, 'b': 2}[value] }}
```

(where `value` is `string`)

Ivy, meanwhile, has always inferred strong types for object literals, even
in its compatibility mode. This commit fixes the bug, and adds the
`strictLiteralTypes` flag to specifically control this inference. When the
flag is `false` (in compatibility mode), object and array literals receive
the `any` type.

PR Close #35462
2020-02-21 12:36:12 -08:00
Alex Rickabaugh 02599e452a fix(ivy): emulate a View Engine type-checking bug with safe navigation (#35462)
In its default compatibility mode, the Ivy template type-checker attempts to
emulate the View Engine default mode as accurately as is possible. This
commit addresses a gap in this compatibility that stems from a View Engine
type-checking bug.

Consider two template expressions:

```html
{{ obj?.field }}
{{ fn()?.field }}
```

and suppose that the type of `obj` and `fn()` are the same - both return
either `null` or an object with a `field` property.

Under View Engine, these type-check differently. The `obj` case will catch
if the object type (when not null) does not have a `field` property, while
the `fn()` case will not. This is due to how View Engine represents safe
navigations:

```typescript
// for the 'obj' case
(obj == null ? null as any : obj.field)

// for the 'fn()' case
let tmp: any;
((tmp = fn()) == null ? null as any : tmp.field)
```

Because View Engine uses the same code generation backend as it does to
produce the runtime code for this expression, it uses a ternary for safe
navigation, with a temporary variable to avoid invoking 'fn()' twice. The
type of this temporary variable is 'any', however, which causes the
`tmp.field` check to be meaningless.

Previously, the Ivy template type-checker in compatibility mode assumed that
`fn()?.field` would always check for the presence of 'field' on the non-null
result of `fn()`. This commit emulates the View Engine bug in Ivy's
compatibility mode, so an 'any' type will be inferred under the same
conditions.

As part of this fix, a new format for safe navigation operations in template
type-checking code is introduced. This is based on the realization that
ternary based narrowing is unnecessary.

For the `fn()` case in strict mode, Ivy now generates:

```typescript
(null as any ? fn()!.field : undefined)
```

This effectively uses the ternary operator as a type "or" operation. The
resulting type will be a union of the type of `fn()!.field` with
`undefined`.

For the `fn()` case in compatibility mode, Ivy now emulates the bug with:

```typescript
(fn() as any).field
```

The cast expression includes the call to `fn()` and allows it to be checked
while still returning a type of `any` from the expression.

For the `obj` case in compatibility mode, Ivy now generates:

```typescript
(obj!.field as any)
```

This cast expression still returns `any` for its type, but will check for
the existence of `field` on the type of `obj!`.

PR Close #35462
2020-02-21 12:36:12 -08:00
George Kalpakas af4fe3aa4e fix(ngcc): correctly detect emitted TS helpers in ES5 (#35191)
In ES5 code, TypeScript requires certain helpers (such as
`__spreadArrays()`) to be able to support ES2015+ features. These
helpers can be either imported from `tslib` (by setting the
`importHelpers` TS compiler option to `true`) or emitted inline (by
setting the `importHelpers` and `noEmitHelpers` TS compiler options to
`false`, which is the default value for both).

Ngtsc's `StaticInterpreter` (which is also used during ngcc processing)
is able to statically evaluate some of these helpers (currently
`__assign()`, `__spread()` and `__spreadArrays()`), as long as
`ReflectionHost#getDefinitionOfFunction()` correctly detects the
declaration of the helper. For this to happen, the left-hand side of the
corresponding call expression (i.e. `__spread(...)` or
`tslib.__spread(...)`) must be evaluated as a function declaration for
`getDefinitionOfFunction()` to be called with.

In the case of imported helpers, the `tslib.__someHelper` expression was
resolved to a function declaration of the form
`export declare function __someHelper(...args: any[][]): any[];`, which
allows `getDefinitionOfFunction()` to correctly map it to a TS helper.

In contrast, in the case of emitted helpers (and regardless of the
module format: `CommonJS`, `ESNext`, `UMD`, etc.)), the `__someHelper`
identifier was resolved to a variable declaration of the form
`var __someHelper = (this && this.__someHelper) || function () { ... }`,
which upon further evaluation was categorized as a `DynamicValue`
(prohibiting further evaluation by the `getDefinitionOfFunction()`).

As a result of the above, emitted TypeScript helpers were not evaluated
in ES5 code.

---
This commit changes the detection of TS helpers to leverage the existing
`KnownFn` feature (previously only used for built-in functions).
`Esm5ReflectionHost` is changed to always return `KnownDeclaration`s for
TS helpers, both imported (`getExportsOfModule()`) as well as emitted
(`getDeclarationOfIdentifier()`).

Similar changes are made to `CommonJsReflectionHost` and
`UmdReflectionHost`.

The `KnownDeclaration`s are then mapped to `KnownFn`s in
`StaticInterpreter`, allowing it to statically evaluate call expressions
involving any kind of TS helpers.

Jira issue: https://angular-team.atlassian.net/browse/FW-1689

PR Close #35191
2020-02-21 09:06:47 -08:00
George Kalpakas 6faaec60b1 refactor(compiler-cli): rename the BuiltinFn type to the more generic KnownFn (#35191)
This is in preparation of using the `KnownFn` type for known TypeScript
helpers (in addition to built-in functions/methods). This will in turn
allow simplifying the detection of both imported and emitted TypeScript
helpers.

PR Close #35191
2020-02-21 09:06:47 -08:00
George Kalpakas 12e3db8d6f fix(ngcc): handle imports in dts files when processing CommonJS (#35191)
When statically evaluating CommonJS code it is possible to find that we
are looking for the declaration of an identifier that actually came from
a typings file (rather than a CommonJS file).

Previously, the CommonJS reflection host would always try to use a
CommonJS specific algorithm for finding identifier declarations, but
when the id is actually in a typings file this resulted in the returned
declaration being the containing file of the declaration rather than the
declaration itself.

Now the CommonJS reflection host will check to see if the file
containing the identifier is a typings file and use the appropriate
stategy.

(Note: This is the equivalent of #34356 but for CommonJS.)

PR Close #35191
2020-02-21 09:06:47 -08:00
crisbeto 8a531e2917 fix(ivy): incorrectly generating shared pure function between null and object literal (#35481)
In #33705 we made it so that we generate pure functions for object/array literals in order to avoid having them be shared across elements/views. The problem this introduced is that further down the line the `ContantPool` uses the generated literal in order to figure out whether to share an existing factory or to create a new one. `ConstantPool` determines whether to share a factory by creating a key from the AST node and using it to look it up in the factory cache, however the key generation function didn't handle function invocations and replaced them with `null`. This means that the key for `{foo: pureFunction0(...)}` and `{foo: null}` are the same.

These changes rework the logic so that instead of generating a `null` key
for function invocations, we generate a variable called `<unknown>` which
shouldn't be able to collide with anything.

Fixes #35298.

PR Close #35481
2020-02-20 15:23:59 -08:00
Kristiyan Kostadinov afc5b3eede perf(ivy): remove unused event argument in listener instructions (#35097)
Currently Ivy always generates the `$event` function argument, even if it isn't being used by the listener expressions. This can lead to unnecessary bytes being generated, because optimizers won't remove unused arguments by default. These changes add some logic to avoid adding the argument when it isn't required.

PR Close #35097
2020-02-20 15:22:14 -08:00
Miško Hevery d63ba9cfd3 fix(ivy): Add style="{{exp}}" based interpolation (#34202)
Fixes #33575

Add support for interpolation in styles as shown:
```
<div style="color: {{exp1}}; width: {{exp2}};">
```

PR Close #34202
2020-02-20 15:13:11 -08:00
George Kalpakas aebd6620d7 fix(ngcc): add default config for angular2-highcharts (#35527)
The package is deprecated (and thus not going to have a new release),
but still has ~7000 weekly downloads.

Fixes #35399

PR Close #35527
2020-02-20 15:12:09 -08:00
George Kalpakas 39bd9a7c94 fix(ngcc): correctly detect outer aliased class identifiers in ES5 (#35527)
In ES5 and ES2015, class identifiers may have aliases. Previously, the
`NgccReflectionHost`s recognized the following formats:
- ES5:
    ```js
    var MyClass = (function () {
      function InnerClass() {}
      InnerClass_1 = InnerClass;
      ...
    }());
    ```
- ES2015:
    ```js
    let MyClass = MyClass_1 = class MyClass { ... };
    ```

In addition to the above, this commit adds support for recognizing an
alias outside the IIFE in ES5 classes (which was previously not
supported):
```js
var MyClass = MyClass_1 = (function () { ... }());
```

Jira issue: [FW-1869](https://angular-team.atlassian.net/browse/FW-1869)

Partially addresses #35399.

PR Close #35527
2020-02-20 15:12:09 -08:00
George Kalpakas 4b93df06e0 refactor(ngcc): tighten method parameter type to avoid redundant check (#35527)
`Esm5ReflectionHost#getInnerFunctionDeclarationFromClassDeclaration()`
was already called with `ts.Declaration`, not `ts.Node`, so we can
tighten its parameter type and get rid of a redundant check.
`getIifeBody()` (called inside
`getInnerFunctionDeclarationFromClassDeclaration()`) will check whether
the given `ts.Declaration` is a `ts.VariableDeclaration`.

PR Close #35527
2020-02-20 15:12:08 -08:00
Andrew Kushnir 72664cac19 fix(compiler): use FatalDiagnosticError to generate better error messages (#35244)
Prior to this commit, decorator handling logic in Ngtsc used `Error` to throw errors. This commit replaces most of these instances with `FatalDiagnosticError` class, which provider a better diagnostics error (including location of the problematic code).

PR Close #35244
2020-02-20 11:25:24 -08:00
Paul Gschwendtner 5bec534bfc build: remove dependency on @types/chokidar (#35371)
We recently updated chokidar to `3.0.0`. The latest version of
chokidar provides TypeScript types on its own and makes the extra
dependency on the `@types` unnecessary.

This seems to have caused the `build-packages-dist` script to fail with
an error like:

```
[strictDeps] transitive dependency on external/npm/node_modules/chokidar/types/index.d.ts
   not allowed. Please add the BUILD target to your rule's deps.
```

It's unclear why that happens, but a reasonable theory would be that
the TS compilation accidentally picked up the types from `chokidar`
instead of `@types/chokidar`, and the strict deps `@bazel/typescript`
check reported this as issue because it's not an explicit target dependency.

PR Close #35371
2020-02-19 12:49:53 -08:00