Commit Graph

412 Commits

Author SHA1 Message Date
George Kalpakas 3cc812711b 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:07 -08:00
George Kalpakas fde89156fa 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:07 -08:00
George Kalpakas 2baf90209b 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:07 -08:00
Pete Bacon Darwin eef07539a6 feat(ngcc): pause async ngcc processing if another process has the lockfile (#35131)
ngcc uses a lockfile to prevent two ngcc instances from executing at the
same time. Previously, if a lockfile was found the current process would
error and exit.

Now, when in async mode, the current process is able to wait for the previous
process to release the lockfile before continuing itself.

PR Close #35131
2020-02-18 17:20:41 -08:00
George Kalpakas 5f57376899 test(ngcc): add missing `UmdReflectionHost#getExportsOfModule()` tests (#35312)
Support for re-exports in UMD were added in e9fb5fdb8. This commit adds
some tests for re-exports (similar to the ones used for
`CommonJsReflectionHost`).

PR Close #35312
2020-02-10 16:13:41 -08:00
Pete Bacon Darwin 54c3a5da3f fix(ngcc): ensure that path-mapped secondary entry-points are processed correctly (#35227)
The `TargetedEntryPointFinder` must work out what the
containing package is for each entry-point that it finds.

The logic for doing this was flawed in the case that the
package was in a path-mapped directory and not in a
node_modules folder. This meant that secondary entry-points
were incorrectly setting their own path as the package
path, rather than the primary entry-point path.

Fixes #35188

PR Close #35227
2020-02-07 11:32:05 -08:00
George Kalpakas 9601b5d18a refactor(ngcc): remove unused function (#35122)
Since #35057, the `markNonAngularPackageAsProcessed()` function is no
longer used and can be removed.

PR Close #35122
2020-02-03 14:04:59 -08:00
Pete Bacon Darwin 3d4067a464 fix(ngcc): do not lock if the target is not compiled by Angular (#35057)
To support parallel CLI builds we instruct developers to pre-process
their node_modules via ngcc at the command line.

Despite doing this ngcc was still trying to set a lock when it was being
triggered by the CLI for packages that are not going to be processed,
since they are not compiled by Angular for instance.

This commit checks whether a target package needs to be compiled
at all before attempting to set the lock.

Fixes #35000

PR Close #35057
2020-02-03 08:46:43 -08:00
Pete Bacon Darwin 2bfddcf29f feat(ngcc): automatically clean outdated ngcc artifacts (#35079)
If ngcc gets updated to a new version then the artifacts
left in packages that were processed by the previous
version are possibly invalid.

Previously we just errored if we found packages that
had already been processed by an outdated version.

Now we automatically clean the packages that have
outdated artifacts so that they can be reprocessed
correctly with the current ngcc version.

Fixes #35082

PR Close #35079
2020-01-31 17:02:44 -08:00
Pete Bacon Darwin 16e15f50d2 refactor(ngcc): export magic strings as constants (#35079)
These strings will be used when cleaning up outdated
packages.

PR Close #35079
2020-01-31 17:02:43 -08:00
Pete Bacon Darwin 3cf55c195b refactor(ngcc): add additional build marker helpers (#35079)
PR Close #35079
2020-01-31 17:02:43 -08:00
Pete Bacon Darwin cc43bfa725 refactor(ngcc): do not crash if package build version is outdated (#35079)
Now `hasBeenProcessed()` will no longer throw if there
is an entry-point that has been built with an outdated
version of ngcc.

Instead it just returns `false`, which will include it in this
processing run.

This is a precursor to adding functionality that will
automatically revert outdate build artifacts.

PR Close #35079
2020-01-31 17:02:43 -08:00
Pete Bacon Darwin 171a79d04f refactor(ngcc): remove unused code (#35079)
PR Close #35079
2020-01-31 17:02:43 -08:00
Pete Bacon Darwin 7f44fa65a7 fix(ngcc): improve lockfile error message (#35001)
The message now gives concrete advice to developers who
experience the error due to running multiple simultaneous builds
via webpack.

Fixes #35000

PR Close #35001
2020-01-28 09:09:00 -08:00
Miško Hevery 69de7680f5 Revert: "feat(ivy): convert [ngStyle] and [ngClass] to use ivy styling bindings" (#34616)
This change reverts https://github.com/angular/angular/pull/28711
NOTE: This change deletes code and creates a BROKEN SHA. If reverting this SHA needs to be reverted with the next SHA to get back into a valid state.

The change removes the fact that `NgStyle`/`NgClass` is special and colaborates with the `[style]`/`[class]` to merge its styles. By reverting to old behavior we have better backwards compatiblity since it is no longer treated special and simply overwrites the styles (same as VE)

PR Close #34616
2020-01-24 12:22:44 -08:00
Miško Hevery 2961bf06c6 refactor(ivy): move `hostVars`/`hostAttrs` from instruction to `DirectiveDef` (#34683)
This change moves information from instructions to declarative position:
- `ɵɵallocHostVars(vars)` => `DirectiveDef.hostVars`
- `ɵɵelementHostAttrs(attrs)` => `DirectiveDef.hostAttrs`

When merging directives it is necessary to know about `hostVars` and `hostAttrs`. Before this change the information was stored in the `hostBindings` function. This was problematic, because in order to get to the information the `hostBindings` would have to be executed. In order for `hostBindings` to be executed the directives would have to be instantiated. This means that the directive instantiation would happen before we had knowledge about the `hostAttrs` and as a result the directive could observe in the constructor that not all of the `hostAttrs` have been applied. This further complicates the runtime as we have to apply `hostAttrs` in parts over many invocations.

`ɵɵallocHostVars` was unnecessarily complicated because it would have to update the `LView` (and Blueprint) while existing directives are already executing. By moving it out of `hostBindings` function we can access it statically and we can create correct `LView` (and Blueprint) in a single pass.

This change only changes how the instructions are generated, but does not change the runtime much. (We cheat by emulating the old behavior by calling `ɵɵallocHostVars` and `ɵɵelementHostAttrs`) Subsequent change will refactor the runtime to take advantage of the static information.

PR Close #34683
2020-01-24 12:22:10 -08:00
JoostK 7659f2e24b fix(ngcc): do not attempt compilation when analysis fails (#34889)
In #34288, ngtsc was refactored to separate the result of the analysis
and resolve phase for more granular incremental rebuilds. In this model,
any errors in one phase transition the trait into an error state, which
prevents it from being ran through subsequent phases. The ngcc compiler
on the other hand did not adopt this strict error model, which would
cause incomplete metadata—due to errors in earlier phases—to be offered
for compilation that could result in a hard crash.

This commit updates ngcc to take advantage of ngtsc's `TraitCompiler`,
that internally manages all Ivy classes that are part of the
compilation. This effectively replaces ngcc's own `AnalyzedFile` and
`AnalyzedClass` types, together with all of the logic to drive the
`DecoratorHandler`s. All of this is now handled in the `TraitCompiler`,
benefiting from its explicit state transitions of `Trait`s so that the
ngcc crash is a thing of the past.

Fixes #34500
Resolves FW-1788

PR Close #34889
2020-01-23 14:47:03 -08:00
JoostK ba82532812 test(ngcc): remove usage of ES2015 syntax in ES5/UMD/CommonJS tests (#34889)
This syntax is invalid in these source files and does result in
compilation errors as the constructor parameters could not be resolved.
This hasn't been an issue until now as those errors were ignored in the
tests, but future work to introduce the Trait system of ngtsc into
ngcc will cause these errors to prevent compilation, resulting in broken
tests.

PR Close #34889
2020-01-23 14:47:03 -08:00
George Kalpakas 5b42084912 fix(ngcc): do not collect private declarations from external packages (#34811)
Previously, while trying to build an `NgccReflectionHost`'s
`privateDtsDeclarationMap`, `computePrivateDtsDeclarationMap()` would
try to collect exported declarations from all source files of the
program (i.e. without checking whether they were within the target
package, as happens for declarations in `.d.ts` files).

Most of the time, that would not be a problem, because external packages
would be represented as `.d.ts` files in the program. But when an
external package had no typings, the JS files would be used instead. As
a result, the `ReflectionHost` would try to (unnecessarilly) parse the
file in order to extract exported declarations, which in turn would be
harmless in most cases.

There are certain cases, though, where the `ReflectionHost` would throw
an error, because it cannot parse the external package's JS file. This
could happen, for example, in `UmdReflectionHost`, which expects the
file to contain exactly one statement. See #34544 for more details on a
real-world failure.

This commit fixes the issue by ensuring that
`computePrivateDtsDeclarationMap()` will only collect exported
declarations from files within the target package.

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

Fixes #34544

PR Close #34811
2020-01-23 13:58:37 -08:00
Paul Gschwendtner 6b468f9b2e fix(ngcc): libraries using spread in object literals cannot be processed (#34661)
Consider a library that uses a shared constant for host bindings. e.g.

```ts
export const BASE_BINDINGS= {
  '[class.mat-themed]': '_isThemed',
}

----

@Directive({
  host: {...BASE_BINDINGS, '(click)': '...'}
})
export class Dir1 {}

@Directive({
  host: {...BASE_BINDINGS, '(click)': '...'}
})
export class Dir2 {}
```

Previously when these components were shipped as part of the
library to NPM, consumers were able to consume `Dir1` and `Dir2`.
No errors showed up.

Now with Ivy, when ngcc tries to process the library, an error
will be thrown. The error is stating that the host bindings should
be an object (which they obviously are). This happens because
TypeScript transforms the object spread to individual
`Object.assign` calls (for compatibility).

The partial evaluator used by the `@Directive` annotation handler
is unable to process this expression because there is no
integrated support for `Object.assign`. In View Engine, this was
not a problem because the `metadata.json` files from the library
were used to compute the host bindings.

Fixes #34659

PR Close #34661
2020-01-23 10:29:57 -08:00
George Kalpakas 93ffc67bfb fix(ngcc): update `package.json` deterministically (#34870)
Ngcc adds properties to the `package.json` files of the entry-points it
processes to mark them as processed for a format and point to the
created Ivy entry-points (in case of `--create-ivy-entry-points`). When
running ngcc in parallel mode (which is the default for the standalone
ngcc command), multiple formats can be processed simultaneously for the
same entry-point and the order of completion is not deterministic.

Previously, ngcc would append new properties at the end of the target
object in `package.json` as soon as the format processing was completed.
As a result, the order of properties in the resulting `package.json`
(when processing multiple formats for an entry-point in parallel) was
not deterministic. For tools that use file hashes for caching purposes
(such as Bazel), this lead to a high probability of cache misses.

This commit fixes the problem by ensuring that the position of
properties added to `package.json` files is deterministic and
independent of the order in which each format is processed.

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

Fixes #34635

PR Close #34870
2020-01-23 10:16:35 -08:00
George Kalpakas 43db4ffcd6 test(ngcc): verify that `PackageJsonUpdater` does not write to files from worker processes (#34870)
PR Close #34870
2020-01-23 10:16:35 -08:00
Pete Bacon Darwin 03465b621b fix(ngcc): only lock ngcc after targeted entry-point check (#34722)
The Angular CLI will continue to call ngcc on all possible packages, even if they
have already been processed by ngcc in a postinstall script.

In a parallel build environment, this was causing ngcc to complain that it was
being run in more than one process at the same time.

This commit moves the check for whether the targeted package has been
processed outside the locked code section, since there is no issue with
multiple ngcc processes from doing this check.

PR Close #34722
2020-01-22 15:35:34 -08:00
Pete Bacon Darwin a107e9edc6 feat(ngcc): lock ngcc when processing (#34722)
Previously, it was possible for multiple instance of ngcc to be running
at the same time, but this is not supported and can cause confusing and
flakey errors at build time.

Now, only one instance of ngcc can run at a time. If a second instance
tries to execute it fails with an appropriate error message.

See https://github.com/angular/angular/issues/32431#issuecomment-571825781

PR Close #34722
2020-01-22 15:35:34 -08:00
Igor Minar 0b1e34de40 fix(common): cleanup the StylingDiffer and related code (#34307)
Since I was learning the codebase and had a hard time understanding what was going on I've done a
bunch of changes in one commit that under normal circumstances should have been split into several
commits. Because this code is likely going to be overwritten with Misko's changes I'm not going to
spend the time with trying to split this up.

Overall I've done the following:
- I processed review feedback from #34307
- I did a bunch of renaming to make the code easier to understand
- I refactored some internal functions that were either inefficient or hard to read
- I also updated lots of type signatures to correct them and to remove many casts in the code

PR Close #34307
2020-01-17 14:07:27 -05:00
Greg Magolan aee67f08d9 test: handle bootstrap templated_args in jasmine_node_test defaults.bzl (#34736)
PR Close #34736
2020-01-15 14:58:07 -05:00
Greg Magolan dcff76e8b9 refactor: handle breaking changes in rules_nodejs 1.0.0 (#34736)
The major one that affects the angular repo is the removal of the bootstrap attribute in nodejs_binary, nodejs_test and jasmine_node_test in favor of using templated_args --node_options=--require=/path/to/script. The side-effect of this is that the bootstrap script does not get the require.resolve patches with explicitly loading the targets _loader.js file.

PR Close #34736
2020-01-15 14:58:07 -05:00
Pete Bacon Darwin 3d5bcd5883 test(ngcc): update dependency host test description (#34695)
The `describe` description did not match the name of the
method.

PR Close #34695
2020-01-15 10:24:50 -08:00
Pete Bacon Darwin 85b5c365fc fix(ngcc): do not add DTS deep imports to missing packages list (#34695)
When searching the typings program for a package for imports a
distinction is drawn between missing entry-points and deep imports.

Previously in the `DtsDependencyHost` these deep imports may be
marked as missing if there was no typings file at the deep import path.
Instead there may be a javascript file instead. In practice this means
the import is "deep" and not "missing".

Now the `DtsDependencyHost` will also consider `.js` files when checking
for deep-imports, and it will also look inside `@types/...` for a suitable
deep-imported typings file.

Fixes #34720

PR Close #34695
2020-01-15 10:24:50 -08:00
Pete Bacon Darwin da51d884a1 test(ngcc): remove `declare` from JS classes (#34695)
PR Close #34695
2020-01-15 10:24:49 -08:00
George Kalpakas cfbb1a1e77 fix(ngcc): correctly detect dependencies in CommonJS (#34528)
Previously, `CommonJsDependencyHost.collectDependencies()` would only
find dependencies via imports of the form `var foo = require('...');` or
`var foo = require('...'), bar = require('...');` However, CommonJS
files can have imports in many different forms. By failing to recognize
other forms of imports, the associated dependencies were missed, which
in turn resulted in entry-points being compiled out-of-order and failing
due to that.

While we cannot easily capture all different types of imports, this
commit enhances `CommonJsDependencyHost` to recognize the following
common forms of imports:

- Imports in property assignments. E.g.:
  `exports.foo = require('...');` or
  `module.exports = {foo: require('...')};`

- Imports for side-effects only. E.g.:
  `require('...');`

- Star re-exports (with both emitted and imported heleprs). E.g.:
  `__export(require('...'));` or
  `tslib_1.__exportStar(require('...'), exports);`

PR Close #34528
2020-01-13 09:48:20 -08:00
George Kalpakas eb6e1af46d test(ngcc): fix typos in `CommonJsDependencyHost` tests (to avoid confusion) (#34528)
PR Close #34528
2020-01-13 09:48:20 -08:00
crisbeto 6d534f10e6 fix(ivy): don't run decorator handlers against declaration files (#34557)
Currently the decorator handlers are run against all `SourceFile`s in the compilation, but we shouldn't be doing it against declaration files. This initially came up as a CI issue in #33264 where it was worked around only for the `DirectiveDecoratorHandler`. These changes move the logic into the `TraitCompiler` and `DecorationAnalyzer` so that it applies to all of the handlers.

PR Close #34557
2020-01-10 15:54:51 -08:00
atscott 538d0446b5 Revert "refactor: handle breaking changes in rules_nodejs 1.0.0 (#34589)" (#34730)
This reverts commit 9bb349e1c8.

PR Close #34730
2020-01-10 14:12:15 -08:00
atscott 5e60215470 Revert "test: handle bootstrap templated_args in jasmine_node_test defaults.bzl (#34589)" (#34730)
This reverts commit da4782e67f.

PR Close #34730
2020-01-10 14:12:15 -08:00
Greg Magolan da4782e67f test: handle bootstrap templated_args in jasmine_node_test defaults.bzl (#34589)
PR Close #34589
2020-01-10 08:31:59 -08:00
Greg Magolan 9bb349e1c8 refactor: handle breaking changes in rules_nodejs 1.0.0 (#34589)
The major one that affects the angular repo is the removal of the bootstrap attribute in nodejs_binary, nodejs_test and jasmine_node_test in favor of using templated_args --node_options=--require=/path/to/script. The side-effect of this is that the bootstrap script does not get the require.resolve patches with explicitly loading the targets _loader.js file.

PR Close #34589
2020-01-10 08:31:59 -08:00
George Kalpakas c3271ac22a fix(ngcc): recognize re-exports with imported TS helpers in CommonJS and UMD (#34527)
Previously, the `CommonJsReflectionHost` and `UmdReflectionHost` would
only recognize re-exports of the form `__export(...)`. This is what
re-exports look like, when the TypeScript helpers are emitted inline
(i.e. when compiling with the default [TypeScript compiler options][1]
that include `noEmitHelpers: false` and `importHelpers: false`).

However, when compiling with `importHelpers: true` and [tslib][2] (which
is the recommended way for optimized bundles), the re-exports will look
like: `tslib_1.__exportStar(..., exports)`
These types of re-exports were previously not recognized by the
CommonJS/UMD `ReflectionHost`s and thus ignored.

This commit fixes this by ensuring both re-export formats are
recognized.

[1]: https://www.typescriptlang.org/docs/handbook/compiler-options.html
[2]: https://www.npmjs.com/package/tslib

PR Close #34527
2020-01-10 08:28:50 -08:00
Pete Bacon Darwin 8815ace418 fix(ngcc): insert definitions after statement (#34677)
If a class was defined as a class expression
in a variable declaration, the definitions
were being inserted before the statment's
final semi-colon.

Now the insertion point will be after the
full statement.

Fixes #34648

PR Close #34677
2020-01-08 15:09:24 -08:00
Pete Bacon Darwin 58cdc22791 fix(ngcc): handle UMD factories that do not use all params (#34660)
In some cases, where a module imports a dependency
but does not actually use it, UMD bundlers may remove
the dependency parameter from the UMD factory function
definition.

For example:

```
import * as x from 'x';
import * as z from 'z';
export const y = x;
```

may result in a UMD bundle including:

```
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ?
        factory(exports, require('x'), require('z')) :
    typeof define === 'function' && define.amd ?
        define(['exports', 'x', 'z'], factory) :
    (global = global || self, factory(global.myBundle = {}, global.x));
}(this, (function (exports, x) { 'use strict';
...
})));
```

Note that while the `z` dependency is provide in the call,
the factory itself only accepts `exports` and `x` as parameters.

Previously ngcc appended new dependencies to the end of the factory
function, but this breaks in the above scenario. Now the new
dependencies are prefixed at the front of parameters/arguments
already in place.

Fixes #34653

PR Close #34660
2020-01-08 15:07:36 -08:00
George Kalpakas 07ea6cf582 fix(ngcc): avoid error due to circular dependency in `EsmDependencyHost` (#34512)
Previously, there was circular dependency between `ngcc/src/utils.ts`,
`ngcc/src/dependencies/dependency_host.ts` and
`ngcc/src/dependencies/esm_dependency_host.ts`. More specifically,
`utils.ts` would [import from `esm_dependency_host.ts`][1], which would
[import from `dependency_host.ts`][2], which would in turn
[import from `utils.ts`][3].

This might be fine in some environments/module formats, but it can cause
unclear errors in the transpiled CommonJS/UMD format (given how Node.js
handles [cycles in module resolution][4]).
(An example error can be found [here][5].)

This commit fixes the problem by moving the code that depends on
`EsmDependencyHost` out of `utils.ts` and into a dedicated file under
`dependencies/`. It also converts the `createDtsDependencyHost()`
function to a class for consistency with the rest of the
`DependencyHost`s.

[1]: https://github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/utils.ts#L10
[2]: https://github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/esm_dependency_host.ts#L10
[3]: https://github.com/angular/angular/blob/18d89c9c8/packages/compiler-cli/ngcc/src/dependencies/dependency_host.ts#L9
[4]: https://nodejs.org/api/modules.html#modules_cycles
[5]: https://circleci.com/gh/angular/angular/577581

PR Close #34512
2020-01-08 15:00:50 -08:00
George Kalpakas c38195f59e refactor(ngcc): use a special map for memoizing expensive-to-compute values (#34512)
Previously, in cases were values were expensive to compute and would be
used multiple times, a combination of a regular `Map` and a helper
function (`getOrDefault()`) was used to ensure values were only computed
once.

This commit uses a special `Map`-like structure to compute and memoize
such expensive values without the need to a helper function.

PR Close #34512
2020-01-08 15:00:50 -08:00
George Kalpakas 6606ce69f6 refactor(ngcc): avoid returning the same top-level helper calls multiple times (#34512)
This change should not have any impact on the code's behavior (based on
how the function is currently used), but it will avoid unnecessary work.

PR Close #34512
2020-01-08 15:00:50 -08:00
George Kalpakas 17d5e2bc99 refactor(ngcc): share code between `CommonJsReflectionHost` and `UmdReflectionHost` (#34512)
While different, CommonJS and UMD have a lot in common regarding the
their exports are constructed. Therefore, there was some code
duplication between `CommonJsReflectionHost` and `UmdReflectionHost`.

This commit extracts some of the common bits into a separate file as
helpers to allow reusing the code in both `ReflectionHost`s.

PR Close #34512
2020-01-08 15:00:49 -08:00
George Kalpakas d5fd742763 fix(ngcc): recognize re-exports with `require()` calls in UMD (#34512)
Previously, `UmdReflectionHost` would only recognize re-exports of the
form `__export(someIdentifier)` and not `__export(require('...'))`.
However, it is possible in some UMD variations to have the latter format
as well. See discussion in https://github.com/angular/angular/pull/34254/files#r359515373

This commit adds support for re-export of the form
`__export(require('...'))` in UMD.

PR Close #34512
2020-01-08 15:00:49 -08:00
George Kalpakas 6654f82522 fix(ngcc): correctly handle inline exports in UMD (#34512)
This fix was part of a broader `ngtsc`/`ngcc` fix in 02bab8cf9 (see
there for details). In 02bab8cf9, the fix was only applied to
`CommonJsReflectionHost`, but it is equally applicable to
`UmdReflectionHost`. Later in #34254, the fix was partially ported to
`UmdReflectionHost` by fixing the `extractUmdReexports()` method.

This commit fully fixes `ngcc`'s handling of inline exports for code in
UMD format.

PR Close #34512
2020-01-08 15:00:49 -08:00
George Kalpakas 10e29355db fix(ngcc): do not add trailing commas in UMD imports (#34545)
Previously, if `UmdRenderingFormatter#addImports()` was called with an
empty list of imports to add (i.e. no new imports were needed), it would
add trailing commas in several locations (arrays, function arguments,
function parameters), thus making the code imcompatible with legacy
browsers such as IE11.

This commit fixes it by ensuring that no trailing commas are added if
`addImports()` is called with an empty list of imports.
This is a follow-up to #34353.

Fixes #34525

PR Close #34545
2020-01-07 10:42:06 -08:00
Pete Bacon Darwin 4f42de9704 fix(ngcc): capture entry-point dependencies from typings as well as source (#34494)
ngcc computes a dependency graph of entry-points to ensure that
entry-points are processed in the correct order. Previously only the imports
in source files were analysed to determine the dependencies for each
entry-point.

This is not sufficient when an entry-point has a "type-only" dependency
 - for example only importing an interface from another entry-point.
In this case the "type-only" import does not appear in the
source code. It only appears in the typings files. This can cause a
dependency to be missed on the entry-point.

This commit fixes this by additionally processing the imports in the
typings program, as well as the source program.

Note that these missing dependencies could cause unexpected flakes when
running ngcc in async mode on multiple processes due to the way that
ngcc caches files when they are first read from disk.

Fixes #34411

// FW-1781

PR Close #34494
2020-01-07 10:35:03 -08:00
Pete Bacon Darwin 69950e3888 refactor(ngcc): resolve modules based on the provided `moduleResolver` (#34494)
The `DependencyHost` implementations were duplicating the "postfix" strings
which are used to find matching paths when resolving module specifiers.
Now the hosts reuse the postfixes given to the `ModuleResolver` that is
passed to the host.

PR Close #34494
2020-01-07 10:35:03 -08:00
Pete Bacon Darwin e2b184515b refactor(ngcc): pass dependency info to `collectDependencies()` (#34494)
Rather than return a new object of dependency info from calls to
`collectDependencies()` we now pass in an object that will be updated
with the dependency info. This is in preparation of a change where
we will collect dependency information from more than one
`DependencyHost`.

Also to better fit with this approach the name is changed from
`findDependencies()` to `collectDependencies()`.

PR Close #34494
2020-01-07 10:35:03 -08:00
crisbeto cf37c003ff feat(ivy): error in ivy when inheriting a ctor from an undecorated base (#34460)
Angular View Engine uses global knowledge to compile the following code:

```typescript
export class Base {
  constructor(private vcr: ViewContainerRef) {}
}

@Directive({...})
export class Dir extends Base {
  // constructor inherited from base
}
```

Here, `Dir` extends `Base` and inherits its constructor. To create a `Dir`
the arguments to this inherited constructor must be obtained via dependency
injection. View Engine is able to generate a correct factory for `Dir` to do
this because via metadata it knows the arguments of `Base`'s constructor,
even if `Base` is declared in a different library.

In Ivy, DI is entirely a runtime concept. Currently `Dir` is compiled with
an ngDirectiveDef field that delegates its factory to `getInheritedFactory`.
This looks for some kind of factory function on `Base`, which comes up
empty. This case looks identical to an inheritance chain with no
constructors, which works today in Ivy.

Both of these cases will now become an error in this commit. If a decorated
class inherits from an undecorated base class, a diagnostic is produced
informing the user of the need to either explicitly declare a constructor or
to decorate the base class.

PR Close #34460
2019-12-18 15:04:49 -08:00
crisbeto dcc8ff4ce7 feat(ivy): throw compilation error when providing undecorated classes (#34460)
Adds a compilation error if the consumer tries to pass in an undecorated class into the `providers` of an `NgModule`, or the `providers`/`viewProviders` arrays of a `Directive`/`Component`.

PR Close #34460
2019-12-18 15:04:49 -08:00
Pete Bacon Darwin 9264f43511 refactor(ngcc): remove private declaration aliases (#34254)
Now that the source to typings matching is able to handle
aliasing of exports, there is no need to handle aliases in private
declarations analysis.

These were originally added to cope when the typings files had
to use the name that the original source files used when exporting.

PR Close #34254
2019-12-18 11:25:01 -08:00
Pete Bacon Darwin 918d8c9909 refactor(ngcc): slightly improve the info in error messages (#34254)
PR Close #34254
2019-12-18 11:25:01 -08:00
Pete Bacon Darwin 31be29a9f3 fix(ngcc): use the correct identifiers when updating typings files (#34254)
Previously the identifiers used in the typings files were the same as
those used in the source files.

When the typings files and the source files do not match exactly, e.g.
when one of them is flattened, while the other is a deep tree, it is
possible for identifiers to be renamed.

This commit ensures that the correct identifier is used in typings files
when the typings file does not export the same name as the source file.

Fixes https://github.com/angular/ngcc-validation/pull/608

PR Close #34254
2019-12-18 11:25:01 -08:00
Pete Bacon Darwin f22a6eb00e fix(ngcc): correctly match aliased classes between src and dts files (#34254)
The naïve matching algorithm we previously used to match declarations in
source files to declarations in typings files was based only on the name
of the thing being declared.  This did not handle cases where the declared
item had been exported via an alias - a common scenario when one of the two
file sets (source or typings) has been flattened, while the other has not.

The new algorithm tries to overcome this by creating two maps of export
name to declaration (i.e. `Map<string, ts.Declaration>`).
One for the source files and one for the typings files.
It then joins these two together by matching export names, resulting in a
new map that maps source declarations to typings declarations directly
(i.e. `Map<ts.Declaration, ts.Declaration>`).

This new map can handle the declaration names being different between the
source and typings as long as they are ultimately both exported with the
same alias name.

Further more, there is one map for "public exports", i.e. exported via the
root of the source tree (the entry-point), and another map for "private
exports", which are exported from individual files in the source tree but
not necessarily from the root. This second map can be used to "guess"
the mapping between exports in a deep (non-flat) file tree, which can be
used by ngcc to add required private exports to the entry-point.

Fixes #33593

PR Close #34254
2019-12-18 11:25:01 -08:00
Pete Bacon Darwin e9fb5fdb89 fix(ngcc): handle UMD re-exports (#34254)
In TS we can re-export imports using statements of the form:

```
export * from 'some-import';
```

This is downleveled in UMD to:

```
function factory(exports, someImport) {
  function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
  }
  __export(someImport);
}
```

This commit adds support for this.

PR Close #34254
2019-12-18 11:25:01 -08:00
Pete Bacon Darwin 47666f548c fix(ngcc): handle CommonJS re-exports by reference (#34254)
In TS we can re-export imports using statements of the form:

```
export * from 'some-import';
```

This can be downleveled in CommonJS to either:

```
__export(require('some-import'));
```

or

```
var someImport = require('some-import');
__export(someImport);
```

Previously we only supported the first downleveled version.
This commit adds support for the second version.

PR Close #34254
2019-12-18 11:25:01 -08:00
Pete Bacon Darwin 0b837e2f0d refactor(ngcc): use bundle src to create reflection hosts (#34254)
Previously individual properties of the src bundle program were
passed to the reflection host constructors. But going forward,
more properties will be required. To prevent the signature getting
continually larger and more unwieldy, this change just passes the
whole src bundle to the constructor, allowing it to extract what it
needs.

PR Close #34254
2019-12-18 11:25:01 -08:00
Alex Rickabaugh 763f8d470a fix(ivy): validate the NgModule declarations field (#34404)
This commit adds three previously missing validations to
NgModule.declarations:

1. It checks that declared classes are actually within the current
   compilation.

2. It checks that declared classes are directives, components, or pipes.

3. It checks that classes are declared in at most one NgModule.

PR Close #34404
2019-12-17 11:39:48 -08:00
George Kalpakas 9cabd6638e refactor(ngcc): un-nest accidentally nested `describe()` blocks (#34437)
PR Close #34437
2019-12-17 11:39:18 -08:00
George Kalpakas cd8a837956 refactor(ngcc): add debug messages to help with debugging in parallel mode (#34437)
PR Close #34437
2019-12-17 11:39:18 -08:00
JoostK 12444a8afc test(ngcc): cleanup entry-point bundle testcases (#34415)
There was an issue with the program under test and two tests with the
same description, this has been fixed.

PR Close #34415
2019-12-16 07:45:36 -08:00
Alex Rickabaugh af95dddd7e perf(ivy): eagerly parse the template twice during analysis (#34334)
A quirk of the Angular template parser is that when parsing templates in the
"default" mode, with options specified by the user, the source mapping
information in the template AST may be inaccurate. As a result, the compiler
parses the template twice: once for "emit" and once to produce an AST with
accurate sourcemaps for diagnostic production.

Previously, only the first parse was performed during analysis. The second
parse occurred during the template type-checking phase, just in time to
produce the template type-checking file.

However, with the reuse of analysis results during incremental builds, it
makes more sense to do the diagnostic parse eagerly during analysis so that
the work isn't unnecessarily repeated in subsequent builds. This commit
refactors the `ComponentDecoratorHandler` to do both parses eagerly, which
actually cleans up some complexity around template parsing as well.

PR Close #34334
2019-12-12 14:13:16 -08:00
JoostK 8c2cbdd385 perf(ivy): use module resolution cache (#34332)
During TypeScript module resolution, a lot of filesystem requests are
done. This is quite an expensive operation, so a module resolution cache
can be used to speed up the process significantly.

This commit lets the Ivy compiler perform all module resolution with a
module resolution cache. Note that the module resolution behavior can be
changed with a custom compiler host, in which case that custom host
implementation is responsible for caching. In the case of the Angular
CLI a custom compiler host with proper module resolution caching is
already in place, so the CLI already has this optimization.

PR Close #34332
2019-12-12 14:06:37 -08:00
Alex Rickabaugh 74edde0a94 perf(ivy): reuse prior analysis work during incremental builds (#34288)
Previously, the compiler performed an incremental build by analyzing and
resolving all classes in the program (even unchanged ones) and then using
the dependency graph information to determine which .js files were stale and
needed to be re-emitted. This algorithm produced "correct" rebuilds, but the
cost of re-analyzing the entire program turned out to be higher than
anticipated, especially for component-heavy compilations.

To achieve performant rebuilds, it is necessary to reuse previous analysis
results if possible. Doing this safely requires knowing when prior work is
viable and when it is stale and needs to be re-done.

The new algorithm implemented by this commit is such:

1) Each incremental build starts with knowledge of the last known good
   dependency graph and analysis results from the last successful build,
   plus of course information about the set of files changed.

2) The previous dependency graph's information is used to determine the
   set of source files which have "logically" changed. A source file is
   considered logically changed if it or any of its dependencies have
   physically changed (on disk) since the last successful compilation. Any
   logically unchanged dependencies have their dependency information copied
   over to the new dependency graph.

3) During the `TraitCompiler`'s loop to consider all source files in the
   program, if a source file is logically unchanged then its previous
   analyses are "adopted" (and their 'register' steps are run). If the file
   is logically changed, then it is re-analyzed as usual.

4) Then, incremental build proceeds as before, with the new dependency graph
   being used to determine the set of files which require re-emitting.

This analysis reuse avoids template parsing operations in many circumstances
and significantly reduces the time it takes ngtsc to rebuild a large
application.

Future work will increase performance even more, by tackling a variety of
other opportunities to reuse or avoid work.

PR Close #34288
2019-12-12 13:11:45 -08:00
Alex Rickabaugh 50cdc0ac1b refactor(ivy): move analysis side effects into a register phase (#34288)
Previously 'analyze' in the various `DecoratorHandler`s not only extracts
information from the decorators on the classes being analyzed, but also has
several side effects within the compiler:

* it can register metadata about the types involved in global metadata
  trackers.
* it can register information about which .ngfactory symbols are actually
  needed.

In this commit, these side-effects are moved into a new 'register' phase,
which runs after the 'analyze' step. Currently this is a no-op refactoring
as 'register' is always called directly after 'analyze'. In the future this
opens the door for re-use of prior analysis work (with only 'register' being
called, to apply the above side effects).

Also as part of this refactoring, the reification of NgModule scope
information into the incremental dependency graph is moved to the
`NgtscProgram` instead of the `TraitCompiler` (which now only manages trait
compilation and does not have other side effects).

PR Close #34288
2019-12-12 13:11:45 -08:00
Alex Rickabaugh 252e3e9487 refactor(ivy): formalize the compilation process for matched handlers (#34288)
Prior to this commit, the `IvyCompilation` tracked the state of each matched
`DecoratorHandler` on each class in the `ts.Program`, and how they
progressed through the compilation process. This tracking was originally
simple, but had grown more complicated as the compiler evolved. The state of
each specific "target" of compilation was determined by the nullability of
a number of fields on the object which tracked it.

This commit formalizes the process of compilation of each matched handler
into a new "trait" concept. A trait is some aspect of a class which gets
created when a `DecoratorHandler` matches the class. It represents an Ivy
aspect that needs to go through the compilation process.

Traits begin in a "pending" state and undergo transitions as various steps
of compilation take place. The `IvyCompilation` class is renamed to the
`TraitCompiler`, which manages the state of all of the traits in the active
program.

Making the trait concept explicit will support future work to incrementalize
the expensive analysis process of compilation.

PR Close #34288
2019-12-12 13:11:45 -08:00
Pete Bacon Darwin 05c1398b4d fix(ngcc): render UMD imports even if no prior imports (#34353)
Previously the UMD rendering formatter assumed that
there would already be import (and an export) arguments
to the UMD factory function.

This commit adds support for this corner case.

Fixes #34138

PR Close #34353
2019-12-12 09:09:41 -08:00
Pete Bacon Darwin c77656e2dd fix(ngcc): handle imports in dts files when processing UMD (#34356)
When statically evalulating UMD 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 UMD file).

Previously, the UMD reflection host would always try to use
a UMD 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 UMD reflection host will check to see if the file containing
the identifier is a typings file and use the appropriate stategy.

PR Close #34356
2019-12-11 13:20:49 -08:00
JoostK ead169a402 fix(ngcc): fix undecorated child migration when `exportAs` is present (#34014)
The undecorated child migration creates a synthetic decorator, which
contained `"exportAs": ["exportName"]` as obtained from the metadata of
the parent class. This is a problem, as `exportAs` needs to specified
as a comma-separated string instead of an array. This commit fixes the
bug by transforming the array of export names back to a comma-separated
string.

PR Close #34014
2019-12-09 16:13:09 -08:00
JoostK 95429d55ff fix(ngcc): log Angular error codes correctly (#34014)
Replaces the "TS-99" sequence with just "NG", so that error codes are
logged correctly.

PR Close #34014
2019-12-09 16:13:08 -08:00
JoostK 0f0fd25038 fix(ngcc): report diagnostics from migrations (#34014)
When ngcc is analyzing synthetically inserted decorators from a
migration, it is typically not expected that any diagnostics are
produced. In the situation where a diagnostic is produced, however, the
diagnostic would not be reported at all. This commit ensures that
diagnostics in migrations are reported.

PR Close #34014
2019-12-09 16:13:08 -08:00
Pete Bacon Darwin 61e8ed6623 fix(ngcc): ensure that bundle `rootDir` is the package path (#34212)
Previously the `rootDir` was set to the entry-point path but
this is incorrect if the source files are stored in a directory outside
the entry-point path. This is the case in the latest versions of the
Angular CDK.

Instead the `rootDir` should be the containing package path, which is
guaranteed to include all the source for the entry-point.

---

A symptom of this is an error when ngcc is trying to process the source of
an entry-point format after the entry-point's typings have already been
processed by a previous processing run.

During processing the `_toR3Reference()` function gets called which in turn
makes a call to `ReflectionHost.getDtsDeclaration()`. If the typings files
are also being processed this returns the node from the dts typings files.

But if we have already processed the typings files and are now processing
only an entry-point format without typings, the call to
`ReflectionHost.getDtsDeclaration()` returns `null`.

When this value is `null`, a JS `valueRef` is passed through as the DTS
`typeRef` to the `ReferenceEmitter`. In this case, the `ReferenceEmitter`
fails during `emit()` because no `ReferenceEmitStrategy` is able to provide
an emission:

1) The `LocalIdentifierStrategy` is not able help because in this case
`ImportMode` is `ForceNewImport`.
2) The `LogicalProjectStrategy` cannot find the JS file below the `rootDir`.

The second strategy failure is fixed by this PR.

Fixes https://github.com/angular/ngcc-validation/issues/495

PR Close #34212
2019-12-05 10:13:02 -08:00
Pete Bacon Darwin f16f6a290b fix(ngcc): render legacy i18n message ids by default (#34135)
By ensuring that legacy i18n message ids are rendered into the templates
of components for packages processed by ngcc, we ensure that these packages
can be used in an application that may provide translations in a legacy
format.

Fixes #34056

PR Close #34135
2019-12-03 10:15:53 -08:00
Pete Bacon Darwin cebe49d3c9 refactor(ngcc): store whether to render legacy i18n message ids in the bundle (#34135)
Placing this configuration in to the bundle avoids having to pass the
value around through lots of function calls, but also could enable
support for different behaviour per bundle in the future.

PR Close #34135
2019-12-03 10:15:53 -08:00
Pete Bacon Darwin e12933a3aa test(ngcc): tidy up helper function (#34135)
Thanks to @gkalpakl for the better regular expression approach.

PR Close #34135
2019-12-03 10:15:52 -08:00
Kara Erickson 755d2d572f refactor(ivy): remove unnecessary fac wrapper (#34076)
For injectables, we currently generate a factory function in the
injectable def (prov) that delegates to the factory function in
the factory def (fac). It looks something like this:

```
factory: function(t) { return Svc.fac(t); }
```

The extra wrapper function is unnecessary since the args for
the factory functions are the same. This commit changes the
compiler to generate this instead:

```
factory: Svc.fac
```

Because we are generating less code for each injectable, we
should see some modest code size savings. AIO's main bundle
is about 1 KB smaller.

PR Close #34076
2019-12-02 11:35:24 -08:00
Pete Bacon Darwin 2fb9b7ff1b fix(ngcc): do not output duplicate ɵprov properties (#34085)
Previously, the Angular AOT compiler would always add a
`ɵprov` to injectables. But in ngcc this resulted in duplicate `ɵprov`
properties since published libraries already have this property.

Now in ngtsc, trying to add a duplicate `ɵprov` property is an error,
while in ngcc the additional property is silently not added.

// FW-1750

PR Close #34085
2019-11-27 12:46:37 -08:00
Pete Bacon Darwin 44225e4010 fix(ngcc): render UMD global imports correctly (#34012)
The current UMD rendering formatter did not handle
a number of corner cases, such as imports from namespaced
packages.

PR Close #34012
2019-11-25 11:38:36 -05:00
JoostK 310ce6dcc2 fix(ngcc): do not crash on packages that specify typings as an array (#33973)
In a package.json file, the "typings" or "types" field could be an array
of typings files. ngcc would previously crash unexpectedly for such
packages, as it assumed that the typings field would be a string. This
commit lets ngcc skip over such packages, as having multiple typing
entry-points is not supported for Angular packages so it is safe to
ignore them.

Fixes #33646

PR Close #33973
2019-11-22 12:40:04 -05:00
Pete Bacon Darwin bf1bcd1e08 fix(ngcc): render localized strings when in ES5 format (#33857)
Recently the ngtsc translator was modified to be more `ScriptTarget`
aware, which basically means that it will not generate non-ES5 code
when the output format is ES5 or similar.

This commit enhances that change by also "downleveling" localized
messages. In ES2015 the messages use tagged template literals, which
are not available in ES5.

PR Close #33857
2019-11-21 10:54:59 -08:00
Pete Bacon Darwin 715d02aa14 fix(ngcc): report errors from `analyze` and `resolve` processing (#33964)
Previously, these errors were being swallowed, which made it
hard to debug problems with packages.

See https://github.com/angular/angular/issues/33685#issuecomment-557091719

PR Close #33964
2019-11-21 10:44:24 -08:00
Andrew Kushnir fc2f6b8456 fix(ivy): wrap functions from "providers" in parentheses in Closure mode (#33609)
Due to the fact that Tsickle runs between analyze and transform phases in Angular, Tsickle may transform nodes (add comments with type annotations for Closure) that we captured during the analyze phase. As a result, some patterns where a function is returned from another function may trigger automatic semicolon insertion, which breaks the code (makes functions return `undefined` instead of a function). In order to avoid the problem, this commit updates the code to wrap all functions in some expression ("privders" and "viewProviders") in parentheses. More info can be found in Tsickle source code here: d797426257/src/jsdoc_transformer.ts (L1021)

PR Close #33609
2019-11-20 14:58:35 -08:00
Alex Rickabaugh 08a4f10ee7 fix(ivy): move setClassMetadata calls into a pure iife (#33337)
This commit transforms the setClassMetadata calls generated by ngtsc from:

```typescript
/*@__PURE__*/ setClassMetadata(...);
```

to:

```typescript
/*@__PURE__*/ (function() {
  setClassMetadata(...);
})();
```

Without the IIFE, terser won't remove these function calls because the
function calls have arguments that themselves are function calls or other
impure expressions. In order to make the whole block be DCE-ed by terser,
we wrap it into IIFE and mark the IIFE as pure.

It should be noted that this change doesn't have any impact on CLI* with
build-optimizer, which removes the whole setClassMetadata block within
the webpack loader, so terser or webpack itself don't get to see it at
all. This is done to prevent cross-chunk retention issues caused by
webpack's internal module registry.

* actually we do expect a short-term size regression while
https://github.com/angular/angular-cli/pull/16228
is merged and released in the next rc of the CLI. But long term this
change does nothing to CLI + build-optimizer configuration and is done
primarly to correct the seemingly correct but non-function PURE annotation
that builds not using build-optimizer could rely on.

PR Close #33337
2019-11-20 12:55:58 -08:00
Alex Rickabaugh 29b8666b10 fix(ngcc): properly detect origin of constructor param types (#33901)
The ReflectionHost supports enumeration of constructor parameters, and one
piece of information it returns describes the origin of the parameter's
type. Parameter types come in two flavors: local (the type is not imported
from anywhere) or non-local (the type comes via an import).

ngcc incorrectly classified all type parameters as 'local', because in the
source files that ngcc processes the type parameter is a real ts.Identifer.
However, that identifier may still have come from an import and thus might
be non-local.

This commit changes ngcc's ReflectionHost(s) to properly recognize and
report these non-local type references.

Fixes #33677

PR Close #33901
2019-11-19 11:38:33 -08:00
JoostK 7215889b3c fix(ngcc): always add exports for `ModuleWithProviders` references (#33875)
In #32902 a bug was supposedly fixed where internal classes as used
within `ModuleWithProviders` are publicly exported, even when the
typings file already contained the generic type on the
`ModuleWithProviders`. This fix turns out to have been incomplete, as
the `ModuleWithProviders` analysis is not done when not processing the
typings files.

The effect of this bug is that formats that are processed after the
initial format had been processed would not have exports for internal
symbols, resulting in "export '...' was not found in '...'" errors.

This commit fixes the bug by always running the `ModuleWithProviders`
analyzer. An integration test has been added that would fail prior to
this change.

Fixes #33701

PR Close #33875
2019-11-18 09:11:34 -08:00
JoostK 32a4a549fd test(ngcc): expand integration tests with APF like package layouts (#33875)
ngcc has a basic integration test infrastructure that downlevels
TypeScript code into bundle formats that need to be processed by ngcc.
Until now, only ES5 bundles were created with a flat structure, however
more complex scenarios require an APF-like layout containing multiple
bundle formats.

PR Close #33875
2019-11-18 09:11:34 -08:00
JoostK 985cadb73d fix(ngcc): correctly include internal .d.ts files (#33875)
Some declaration files may not be referenced from an entry-point's
main typings file, as it may declare types that are only used internally.
ngcc has logic to include declaration files based on all source files,
to ensure internal declaration files are available.

For packages following APF layout, however, this logic was insufficient.
Consider an entry-point with base path of `/esm2015/testing` and typings
residing in `/testing`, the file
`/esm2015/testing/src/nested/internal.js` has its typings file at
`/testing/src/nested/internal.d.ts`. Previously, the declaration was
assumed to be located at `/esm2015/testing/testing/internal.d.ts` (by
means of `/esm2015/testing/src/nested/../../testing/internal.d.ts`)
which is not where the declaration file can be found. This commit
resolves the issue by looking in the correct directory.

PR Close #33875
2019-11-18 09:11:34 -08:00
JoostK e666d283dd fix(ngcc): correctly associate decorators with aliased classes (#33878)
In flat bundle formats, multiple classes that have the same name can be
suffixed to become unique. In ES5-like bundles this results in the outer
declaration from having a different name from the "implementation"
declaration within the class' IIFE, as the implementation declaration
may not have been suffixed.

As an example, the following code would fail to have a `Directive`
decorator as ngcc would search for `__decorate` calls that refer to
`AliasedDirective$1` by name, whereas the `__decorate` call actually
uses the `AliasedDirective` name.

```javascript
var AliasedDirective$1 = /** @class */ (function () {
    function AliasedDirective() {}
    AliasedDirective = tslib_1.__decorate([
        Directive({ selector: '[someDirective]' }),
    ], AliasedDirective);
    return AliasedDirective;
}());
```

This commit fixes the problem by not relying on comparing names, but
instead finding the declaration and matching it with both the outer
and inner declaration.

PR Close #33878
2019-11-18 09:10:35 -08:00
JoostK 19a6c158d2 test(ngcc): avoid using spy in `Esm2015ReflectionHost` test (#33878)
A testcase that was using a spy has shown itself to be brittle, and its
assertions can easily be moved into a related test.

PR Close #33878
2019-11-18 09:10:35 -08:00
George Kalpakas 033aba9351 fix(ngcc): do not emit ES2015 code in ES5 files (#33514)
Previously, ngcc's `Renderer` would add some constants in the processed
files which were emitted as ES2015 code (e.g. `const` declarations).
This would result in invalid ES5 generated code that would break when
run on browsers that do not support the emitted format.

This commit fixes it by adding a `printStatement()` method to
`RenderingFormatter`, which can convert statements to JavaScript code in
a suitable format for the corresponding `RenderingFormatter`.
Additionally, the `translateExpression()` and `translateStatement()`
ngtsc helper methods are augmented to accept an extra hint to know
whether the code needs to be translated to ES5 format or not.

Fixes #32665

PR Close #33514
2019-11-13 13:49:31 -08:00
George Kalpakas 704775168d fix(ngcc): generate correct metadata for classes with getter/setter properties (#33514)
While processing class metadata, ngtsc generates a `setClassMetadata()`
call which (among other things) contains info about property decorators.
Previously, processing getter/setter pairs with some of ngcc's
`ReflectionHost`s resulted in multiple metadata entries for the same
property, which resulted in duplicate object keys, which in turn causes
an error in ES5 strict mode.

This commit fixes it by ensuring that there are no duplicate property
names in the `setClassMetadata()` calls.

In addition, `generateSetClassMetadataCall()` is updated to treat
`ClassMember#decorators: []` the same as `ClassMember.decorators: null`
(i.e. omitting the `ClassMember` from the generated `setClassMetadata()`
call). Alternatively, ngcc's `ReflectionHost`s could be updated to do
this transformation (`decorators: []` --> `decorators: null`) when
reflecting on class members, but this would require changes in many
places and be less future-proof.

For example, given a class such as:

```ts
class Foo {
  @Input() get bar() { return 'bar'; }
  set bar(value: any) {}
}
```

...previously the generated `setClassMetadata()` call would look like:

```ts
ɵsetClassMetadata(..., {
  bar: [{type: Input}],
  bar: [],
});
```

The same class will now result in a call like:

```ts
ɵsetClassMetadata(..., {
  bar: [{type: Input}],
});
```

Fixes #30569

PR Close #33514
2019-11-13 13:49:31 -08:00
Pete Bacon Darwin 1e1e242570 fix(ngcc): support minified ES5 scenarios (#33777)
The reflection hosts have been updated to support the following
code forms, which were found in some minified library code:

* The class IIFE not being wrapped in parentheses.
* Calls to `__decorate()` being combined with the IIFE return statement.

PR Close #33777
2019-11-13 11:11:48 -08:00
Pete Bacon Darwin d21471e24e fix(ngcc): remove `__decorator` calls even when part of the IIFE return statement (#33777)
Previously we only removed `__decorate()` calls that looked like:

```
SomeClass = __decorate(...);
```

But in some minified scenarios this call gets wrapped up with the
return statement of the IIFE.

```
return SomeClass = __decorate(...);
```

This is now removed also, leaving just the return statement:

```
return SomeClass;
```

PR Close #33777
2019-11-13 11:11:48 -08:00
Pete Bacon Darwin 9c6ee5fcd0 refactor(ngcc): move `stripParentheses` to `Esm5ReflectionHost` for re-use (#33777)
PR Close #33777
2019-11-13 11:11:48 -08:00
Pete Bacon Darwin 7f24975a60 refactor(ngcc): remove unused function (#33777)
PR Close #33777
2019-11-13 11:11:48 -08:00
George Kalpakas 95715fc71e fix(ngcc): add default config for `ng2-dragula` (#33797)
The `dist/` directory has a duplicate `package.json` pointing to the
same files, which (under certain configurations) can causes ngcc to try
to process the files twice and fail.

This commit adds a default ngcc config for `ng2-dragula` to ignore the
`dist/` entry-point.

Fixes #33718

PR Close #33797
2019-11-13 11:09:59 -08:00
Pete Bacon Darwin b3c3000004 fix(ngcc): ensure that adjacent statements go after helper calls (#33689)
Previously the renderers were fixed so that they inserted extra
"adjacent" statements after the last static property of classes.

In order to help the build-optimizer (in Angular CLI) to be able to
tree-shake classes effectively, these statements should also appear
after any helper calls, such as `__decorate()`.

This commit moves the computation of this positioning into the
`NgccReflectionHost` via the `getEndOfClass()` method, which
returns the last statement that is related to the class.

FW-1668

PR Close #33689
2019-11-11 13:01:15 -08:00
Pete Bacon Darwin 52d1500155 refactor(ngcc): allow look up of multiple helpers (#33689)
This change is a precursor to finding the end of a
class, which needs to search for helpers of many
different names.

PR Close #33689
2019-11-11 13:01:15 -08:00
JoostK 81828ae7f4 fix(ngcc): add reexports only once (#33658)
When ngcc is configured to generate reexports for a package using the
`generateDeepReexports` configuration option, it could incorrectly
render the reexports as often as the number of compiled classes in the
declaration file. This would cause compilation errors due to duplicated
declarations.

PR Close #33658
2019-11-07 20:29:13 +00:00
Pete Bacon Darwin fe12d0dc78 fix(ngcc): render adjacent statements after static properties (#33630)
See https://github.com/angular/angular/pull/33337#issuecomment-545487737

Fixes FW-1664

PR Close #33630
2019-11-06 19:54:05 +00:00
Alan Agius d749dd3ea1 fix(ngcc): handle new `__spreadArrays` tslib helper (#33617)
We already have special cases for the `__spread` helper function and with this change we handle the new tslib helper introduced in version 1.10 `__spreadArrays`.

For more context see: https://github.com/microsoft/tslib/releases/tag/1.10.0

Fixes: #33614

PR Close #33617
2019-11-06 19:43:07 +00:00
Pete Bacon Darwin 85298e345d fix(ngcc): render new definitions using the inner name of the class (#33533)
When decorating classes with ivy definitions (e.g. `ɵfac` or `ɵdir`)
the inner name of the class declaration must be used.

This is because in ES5 the definitions are inside the class's IIFE
where the outer declaration has not yet been initialized.

PR Close #33533
2019-11-05 17:25:02 +00:00
Pete Bacon Darwin 93a23b9ae0 fix(ngcc): override `getInternalNameOfClass()` and `getAdjacentNameOfClass()` for ES5 (#33533)
In ES5 the class consists of an outer variable declaration that is
initialised by an IIFE. Inside the IIFE the class is implemented by
an inner function declaration that is returned from the IIFE.
This inner declaration may have a different name to the outer
declaration.

This commit overrides `getInternalNameOfClass()` and
`getAdjacentNameOfClass()` in `Esm5ReflectionHost` with methods that
can find the correct inner declaration name identifier.

PR Close #33533
2019-11-05 17:25:01 +00:00
Pete Bacon Darwin 90f33dd11d refactor(ngcc): remove unnecessary ! operator (#33533)
PR Close #33533
2019-11-05 17:25:01 +00:00
Pete Bacon Darwin 1d141a8ab1 fix(compiler-cli): attach the correct `viaModule` to namespace imports (#33495)
Previously declarations that were imported via a namespace import
were given the same `bestGuessOwningModule` as the context
where they were imported to. This causes problems with resolving
`ModuleWithProviders` that have a type that has been imported in
this way, causing errors like:

```
ERROR in Symbol UIRouterModule declared in
.../@uirouter/angular/uiRouterNgModule.d.ts
is not exported from
.../@uirouter/angular/uirouter-angular.d.ts
(import into .../src/app/child.module.ts)
```

This commit modifies the `TypescriptReflectionHost.getDirectImportOfIdentifier()`
method so that it also understands how to attach the correct `viaModule` to
the identifier of the namespace import.

Resolves #32166

PR Close #33495
2019-10-31 22:25:48 +00:00
crisbeto c3e93564d0 perf(ivy): avoid generating selectors array for directives without a selector (#33431)
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 #33431
2019-10-29 12:06:15 -07:00
crisbeto 14c4b1b205 refactor(ivy): remove ngBaseDef (#33264)
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 #33264
2019-10-25 13:11:34 -07:00
Alex Rickabaugh b381497126 feat(ngcc): add a migration for undecorated child classes (#33362)
In Angular View Engine, there are two kinds of decorator inheritance:

1) both the parent and child classes have decorators

This case is supported by InheritDefinitionFeature, which merges some fields
of the definitions (such as the inputs or queries).

2) only the parent class has a decorator

If the child class is missing a decorator, the compiler effectively behaves
as if the parent class' decorator is applied to the child class as well.
This is the "undecorated child" scenario, and this commit adds a migration
to ngcc to support this pattern in Ivy.

This migration has 2 phases. First, the NgModules of the application are
scanned for classes in 'declarations' which are missing decorators, but
whose base classes do have decorators. These classes are the undecorated
children. This scan is performed recursively, so even if a declared class
has a base class that itself inherits a decorator, this case is handled.

Next, a synthetic decorator (either @Component or @Directive) is created
on the child class. This decorator copies some critical information such
as 'selector' and 'exportAs', as well as supports any decorated fields
(@Input, etc). A flag is passed to the decorator compiler which causes a
special feature `CopyDefinitionFeature` to be included on the compiled
definition. This feature copies at runtime the remaining aspects of the
parent definition which `InheritDefinitionFeature` does not handle,
completing the "full" inheritance of the child class' decorator from its
parent class.

PR Close #33362
2019-10-25 09:16:50 -07:00
JoostK 6b267482d7 feat(ngcc): enable migrations to apply schematics to libraries (#33362)
When upgrading an Angular application to a new version using the Angular
CLI, built-in schematics are being run to update user code from
deprecated patterns to the new way of working. For libraries that have
been built for older versions of Angular however, such schematics have
not been executed which means that deprecated code patterns may still be
present, potentially resulting in incorrect behavior.

Some of the logic of schematics has been ported over to ngcc migrations,
which are automatically run on libraries. These migrations achieve the
same goal of the regular schematics, but operating on published library
sources instead of used code.

PR Close #33362
2019-10-25 09:16:50 -07:00
JoostK 2e5e1dd5f5 refactor(ngcc): rework undecorated parent migration (#33362)
Previously, the (currently disabled) undecorated parent migration in
ngcc would produce errors when a base class could not be determined
statically or when a class extends from a class in another package. This
is not ideal, as it would cause the library to fail compilation without
a workaround, whereas those problems are not guaranteed to cause issues.

Additionally, inheritance chains were not handled. This commit reworks
the migration to address these limitations.

PR Close #33362
2019-10-25 09:16:50 -07:00
JoostK 3858b26211 refactor(ivy): mark synthetic decorators explicitly (#33362)
In ngcc's migration system, synthetic decorators can be injected into a
compilation to ensure that certain classes are compiled with Angular
logic, where the original library code did not include the necessary
decorators. Prior to this change, synthesized decorators would have a
fake AST structure as associated node and a made-up identifier. In
theory, this may introduce issues downstream:

1) a decorator's node is used for diagnostics, so it must have position
information. Having fake AST nodes without a position is therefore a
problem. Note that this is currently not a problem in practice, as
injected synthesized decorators would not produce any diagnostics.

2) the decorator's identifier should refer to an imported symbol.
Therefore, it is required that the symbol is actually imported.
Moreover, bundle formats such as UMD and CommonJS use namespaces for
imports, so a bare `ts.Identifier` would not be suitable to use as
identifier. This was also not a problem in practice, as the identifier
is only used in the `setClassMetadata` generated code, which is omitted
for synthetically injected decorators.

To remedy these potential issues, this commit makes a decorator's
identifier optional and switches its node over from a fake AST structure
to the class' name.

PR Close #33362
2019-10-25 09:16:49 -07:00
JoostK 31b9492951 feat(ngcc): migrate services that are missing `@Injectable()` (#33362)
A class that is provided as Angular service is required to have an
`@Injectable()` decorator so that the compiler generates its injectable
definition for the runtime. Applications are automatically migrated
using the "missing-injectable" schematic, however libraries built for
older version of Angular may not yet satisfy this requirement.

This commit ports the "missing-injectable" schematic to a migration that
is ran when ngcc is processing a library. This ensures that any service
that is provided from an NgModule or Directive/Component will have an
`@Injectable()` decorator.

PR Close #33362
2019-10-25 09:16:49 -07:00
JoostK 0de2dbfec1 fix(ngcc): prevent reflected decorators from being clobbered (#33362)
ngcc has an internal cache of computed decorator information for
reflected classes, which could previously be mutated by consumers of the
reflection host. With the ability to inject synthesized decorators, such
decorators would inadvertently be added into the array of decorators
that was owned by the internal cache of the reflection host, incorrectly
resulting in synthesized decorators to be considered real decorators on
a class. This commit fixes the issue by cloning the cached array before
returning it.

PR Close #33362
2019-10-25 09:16:49 -07:00
Alex Rickabaugh e030375d9a feat(ngcc): enable private NgModule re-exports in ngcc on request (#33177)
This commit adapts the private NgModule re-export system (using aliasing) to
ngcc. Not all ngcc compilations are compatible with these re-exports, as
they assume a 1:1 correspondence between .js and .d.ts files. The primary
concern here is supporting them for commonjs-only packages.

PR Close #33177
2019-10-22 13:14:31 -04:00
Pete Bacon Darwin bfd07b3c94 fix(ngcc): Esm5ReflectionHost.getDeclarationOfIdentifier should handle aliased inner declarations (#33252)
In ES5 modules, the class declarations consist of an IIFE with inner
and outer declarations that represent the class. The `EsmReflectionHost`
has logic to ensure that `getDeclarationOfIdentifier()` always returns the
outer declaration.

Before this commit, if an identifier referred to an alias of the inner
declaration, then `getDeclarationOfIdentifier()` was failing to find
the outer declaration - instead returning the inner declaration.

Now the identifier is correctly resolved up to the outer declaration
as expected.

This should fix some of the failing 3rd party packages discussed in
https://github.com/angular/ngcc-validation/issues/57.

PR Close #33252
2019-10-18 14:41:25 -04:00
Igor Minar 86e1e6c082 feat: typescript 3.6 support (#32946)
BREAKING CHANGE: typescript 3.4 and 3.5 are no longer supported, please update to typescript 3.6

Fixes #32380

PR Close #32946
2019-10-18 13:15:16 -04:00
Alex Rickabaugh de445709d4 fix(ivy): use ReflectionHost to check exports when writing an import (#33192)
This commit fixes ngtsc's import generator to use the ReflectionHost when
looking through the exports of an ES module to find the export of a
particular declaration that's being imported. This is necessary because
some module formats like CommonJS have unusual export mechanics, and the
normal TypeScript ts.TypeChecker does not understand them.

This fixes an issue with ngcc + CommonJS where exports were not being
enumerated correctly.

FW-1630 #resolve

PR Close #33192
2019-10-17 19:43:39 -04:00
Alex Rickabaugh 50710838bf fix(ngcc): better detection of end of decorator expression (#33192)
for removal of decorator from __decorate calls.

FW-1629 #resolve

PR Close #33192
2019-10-17 19:43:39 -04:00
Alex Rickabaugh 4da2dda647 feat(ngcc): support ignoreMissingDependencies in ngcc config (#33192)
Normally, when ngcc encounters a package with missing dependencies while
attempting to determine a compilation ordering, it will ignore that package.
This commit adds a configuration for a flag to tell ngcc to compile the
package anyway, regardless of any missing dependencies.

FW-1931 #resolve

PR Close #33192
2019-10-17 19:43:39 -04:00
Alex Rickabaugh afcff73be3 fix(ngcc): report the correct viaModule when reflecting over commonjs (#33192)
In the ReflectionHost API, a 'viaModule' indicates that a particular value
originated in another absolute module. It should always be 'null' for values
originating in relatively-imported modules.

This commit fixes a bug in the CommonJsReflectionHost where viaModule would
be reported even for relatively-imported values, which causes invalid import
statements to be generated during compilation.

A test is added to verify the correct behavior.

FW-1628 #resolve

PR Close #33192
2019-10-17 19:43:39 -04:00
Alex Rickabaugh 2196114501 feat(ngcc): support --async flag (defaults to true) (#33192)
This allows disabling parallelism in ngcc if desired, which is mainly useful
for debugging. The implementation creates the flag and passes its value to
mainNgcc.

No tests are added since the feature mainly exists already - ngcc supports
both parallel and serial execution. This commit only allows switching the
flag via the commandline.

PR Close #33192
2019-10-17 19:43:39 -04:00
George Kalpakas 78214e72ea fix(ngcc): avoid warning when reflecting on index signature member (#33198)
Previously, when `ngcc` was reflecting on class members it did not
account for the fact that a member could be of the kind
`IndexSignature`. This can happen, for example, on abstract classes (as
is the case for [JsonCallbackContext][1]).

Trying to reflect on such members (and failing to recognize their kind),
resulted in warnings, such as:
```
Warning: Unknown member type: "[key: string]: (data: any) => void;
```

While these warnings are harmless, they can be confusing and worrisome
for users.

This commit avoids such warnings by detecting class members of the
`IndexSignature` kind and ignoring them.

[1]: https://github.com/angular/angular/blob/4659cc26e/packages/common/http/src/jsonp.ts#L39

PR Close #33198
2019-10-17 16:05:48 -04:00
Kara Erickson cda9248b33 refactor(core): rename ngInjectorDef to ɵinj (#33151)
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 #33151
2019-10-16 16:36:19 -04:00
Gabriel Medeiros Coelho 4659cc26ea style: emove unreachable 'return null' statement (#33174)
There's another return statement before this one, therefore 'return null' will never be reached.

PR Close #33174
2019-10-16 10:58:38 -04:00
Kara Erickson fc93dafab1 refactor(core): rename ngModuleDef to ɵmod (#33142)
Module 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
ngModuleDef to mod. 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 #33142
2019-10-14 23:08:10 +00:00
Kara Erickson 0de2a5e408 refactor(core): rename ngFactoryDef to ɵfac (#33116)
Factory 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
ngFactoryDef to fac. 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.

Note that the other "defs" (ngPipeDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.

PR Close #33116
2019-10-14 20:27:25 +00:00
George Kalpakas 25af147a8c refactor(ngcc): fix formatting of missing dependencies error (#33139)
Previously, the list of missing dependencies was not explicitly joined,
which resulted in the default `,` joiner being used during
stringification.

This commit explicitly joins the missing dependency lines to avoid
unnecessary commas.

Before:
```
The target entry-point "some-entry-point" has missing dependencies:
 - dependency 1
, - dependency 2
, - dependency 3
```

After:
```
The target entry-point "some-entry-point" has missing dependencies:
 - dependency 1
 - dependency 2
 - dependency 3
```

PR Close #33139
2019-10-14 16:30:39 +00:00
George Kalpakas 1a34fbce25 fix(ngcc): rename the executable from `ivy-ngcc` to `ngcc` (#33140)
Previously, the executable for the Angular Compatibility Compiler
(`ngcc`) was called `ivy-ngcc`. This would be confusing for users not
familiar with our internal terminology, especially given that we call it
`ngcc` in all our docs and presentations.

This commit renames the executable to `ngcc` and replaces `ivy-ngcc`
with a script that errors with an informative message (prompting the
user to use `ngcc` instead).

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

PR Close #33140
2019-10-14 16:29:14 +00:00
Kara Erickson 1a67d70bf8 refactor(core): rename ngDirectiveDef to ɵdir (#33110)
Directive 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
ngDirectiveDef to dir. 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.

Note that the other "defs" (ngFactoryDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.

PR Close #33110
2019-10-14 16:20:11 +00:00
Kara Erickson 64fd0d6db9 refactor(core): rename ngComponentDef to ɵcmp (#33088)
Component 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
`ngComponentDef` to `cmp`. 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.

Note that the other "defs" (ngDirectiveDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.

PR Close #33088
2019-10-11 15:45:22 -07:00
Pete Bacon Darwin 90007e97ca feat(ngcc): support version ranges in project/default configurations (#33008)
By appending a version range to the package name, it is now possible to
target configuration to specific versions of a package.

PR Close #33008
2019-10-10 13:59:57 -07:00
Pete Bacon Darwin 916762440c feat(ngcc): support fallback to a default configuration (#33008)
It is now possible to include a set of default ngcc configurations
that ship with ngcc out of the box. This allows ngcc to handle a
set of common packages, which are unlikely to be fixed, without
requiring the application developer to write their own configuration
for them.

Any packages that are configured at the package or project level
will override these default configurations. This allows a reasonable
level of control at the package and user level.

PR Close #33008
2019-10-10 13:59:57 -07:00
crisbeto d5b87d32b0 perf(ivy): move attributes array into component def (#32798)
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 #32798
2019-10-09 13:16:55 -07:00
Pete Bacon Darwin b2b917d2d8 feat(ngcc): expose `--create-ivy-entry-points` option on ivy-ngcc (#33049)
This allows a postinstall hook to generate the same
output as the CLI integration does.

See https://github.com/angular/angular/pull/32999#issuecomment-539937368

PR Close #33049
2019-10-09 13:16:16 -07:00
Pete Bacon Darwin bcbf3e4123 feat(ivy): i18n - render legacy message ids in `$localize` if requested (#32937)
The `$localize` library uses a new message digest function for
computing message ids. This means that translations in legacy
translation files will no longer match the message ids in the code
and so will not be translated.

This commit adds the ability to specify the format of your legacy
translation files, so that the appropriate message id can be rendered
in the `$localize` tagged strings. This results in larger code size
and requires that all translations are in the legacy format.

Going forward the developer should migrate their translation files
to use the new message id format.

PR Close #32937
2019-10-03 12:12:55 -07:00
Martin Probst 5332b04f35 build: TypeScript 3.6 compatibility. (#32908)
This PR updates Angular to compile with TypeScript 3.6 while retaining
compatibility with TS3.5. We achieve this by inserting several `as any`
casts for compatiblity around `ts.CompilerHost` APIs.

PR Close #32908
2019-10-03 09:09:11 -07:00
crisbeto 4e35e348af refactor(ivy): generate ngFactoryDef for injectables (#32433)
With #31953 we moved the factories for components, directives and pipes into a new field called `ngFactoryDef`, however I decided not to do it for injectables, because they needed some extra logic. These changes set up the `ngFactoryDef` for injectables as well.

For reference, the extra logic mentioned above is that for injectables we have two code paths:

1. For injectables that don't configure how they should be instantiated, we create a `factory` that proxies to `ngFactoryDef`:

```
// Source
@Injectable()
class Service {}

// Output
class Service {
  static ngInjectableDef = defineInjectable({
    factory: () => Service.ngFactoryFn(),
  });

  static ngFactoryFn: (t) => new (t || Service)();
}
```

2. For injectables that do configure how they're created, we keep the `ngFactoryDef` and generate the factory based on the metadata:

```
// Source
@Injectable({
  useValue: DEFAULT_IMPL,
})
class Service {}

// Output
export class Service {
  static ngInjectableDef = defineInjectable({
    factory: () => DEFAULT_IMPL,
  });

  static ngFactoryFn: (t) => new (t || Service)();
}
```

PR Close #32433
2019-10-02 13:04:26 -07:00
JoostK 747f0cff9e fix(ngcc): handle presence of both `ctorParameters` and `__decorate` (#32901)
Recently ng-packagr was updated to include a transform that used to be
done in tsickle (https://github.com/ng-packagr/ng-packagr/pull/1401),
where only constructor parameter decorators are emitted in tsickle's
format, not any of the other decorators.

ngcc used to extract decorators from only a single format, so once it
saw the `ctorParameters` static property it assumed the library is using
the tsickle format. Therefore, none of the `__decorate` calls were
considered. This resulted in missing decorator information, preventing
proper processing of a package.

This commit changes how decorators are extracted by always looking at
both the static properties and the `__decorate` calls, merging these
sources appropriately.

Resolves FW-1573

PR Close #32901
2019-09-30 14:11:45 -07:00
JoostK 002a97d852 fix(ngcc): ensure private exports are added for `ModuleWithProviders` (#32902)
ngcc may need to insert public exports into the bundle's source as well
as to the entry-point's declaration file, as the Ivy compiler may need
to create import statements to internal library types. The way ngcc
knows which exports to add is through the references registry, to which
references to things that require a public export are added by the
various analysis steps that are executed.

One of these analysis steps is the augmentation of declaration files
where functions that return `ModuleWithProviders` are updated so that a
generic type argument is added that corresponds with the `NgModule` that
is actually imported. This type has to be publicly exported, so the
analyzer step has to add the module type to the references registry.

A problem occurs when `ModuleWithProviders` already has a generic type
argument, in which case no update of the declaration file is necessary.
This may happen when 1) ngcc is processing additional bundle formats, so
that the declaration file has already been updated while processing the
first bundle format, or 2) when a package is processed which already
contains the generic type in its source. In both scenarios it may occur
that the referenced `NgModule` type does not yet have a public export,
so it is crucial that a reference to the type is added to the
references registry, which ngcc failed to do.

This commit fixes the issue by always adding the referenced `NgModule`
type to the references registry, so that a public export will always be
created if necessary.

Resolves FW-1575

PR Close #32902
2019-09-30 14:11:16 -07:00
Pete Bacon Darwin 0ea4875b10 fix(ngcc): make the build-marker error more clear (#32712)
The previous message was confusing as it could be
interpreted as only deleting the package mentioned.

Now we compute and display the actual node_modules
path to remove.

See https://github.com/angular/angular/issues/31354#issuecomment-532080537

PR Close #32712
2019-09-25 11:29:45 -07:00
Pete Bacon Darwin e5a3de575f fix(ngcc): support UMD global factory in comma lists (#32709)
Previously we were looking for a global factory call that looks like:

```ts
(factory((global.ng = global.ng || {}, global.ng.common = {}), global.ng.core))"
```

but in some cases it looks like:

```ts
(global = global || self, factory((global.ng = global.ng || {}, global.ng.common = {}), global.ng.core))"
```

Note the `global = global || self` at the start of the statement.

This commit makes the test when finding the global factory
function call resilient to being in a comma list.

PR Close #32709
2019-09-17 09:16:08 -07:00
JoostK 3c7da767d8 fix(ngcc): resolve imports in `.d.ts` files for UMD/CommonJS bundles (#32619)
In ngcc's reflection host for UMD and CommonJS bundles, custom logic is
present to resolve import details of an identifier. However, this custom
logic is unable to resolve an import for an identifier inside of
declaration files, as such files use the regular ESM import syntax.

As a consequence of this limitation, ngtsc is unable to resolve
`ModuleWithProviders` imports that are declared in an external library.
In that situation, ngtsc determines the type of the actual `NgModule`
that is imported, by looking in the library's declaration files for the
generic type argument on `ModuleWithProviders`. In this process, ngtsc
resolves the import for the `ModuleWithProviders` identifier to verify
that it is indeed the `ModuleWithProviders` type from `@angular/core`.
So, when the UMD reflection host was in use this resolution would fail,
therefore no `NgModule` type could be detected.

This commit fixes the bug by using the regular import resolution logic
in addition to the custom resolution logic that is required for UMD
and CommonJS bundles.

Fixes #31791

PR Close #32619
2019-09-12 13:18:20 -07:00
JoostK c4e039a43a fix(ngcc): correctly read static properties for aliased classes (#32619)
In ESM2015 bundles, a class with decorators may be emitted as follows:

```javascript
var MyClass_1;
let MyClass = MyClass_1 = class MyClass {};
MyClass.decorators = [/* here be decorators */];
```

Such a class has two declarations: the publicly visible `let MyClass`
and the implementation `class MyClass {}` node. In #32539 a refactoring
took place to handle such classes more consistently, however the logic
to find static properties was mistakenly kept identical to its broken
state before the refactor, by looking for static properties on the
implementation symbol (the one for `class MyClass {}`) whereas the
static properties need to be obtained from the symbol corresponding with
the `let MyClass` declaration, as that is where the `decorators`
property is assigned to in the example above.

This commit fixes the behavior by looking for static properties on the
public declaration symbol. This fixes an issue where decorators were not
found for classes that do in fact have decorators, therefore preventing
the classes from being compiled for Ivy.

Fixes #31791

PR Close #32619
2019-09-12 13:18:20 -07:00
JoostK 373e1337de fix(ngcc): consistently use outer declaration for classes (#32539)
In ngcc's reflection hosts for compiled JS bundles, such as ESM2015,
special care needs to be taken for classes as there may be an outer
declaration (referred to as "declaration") and an inner declaration
(referred to as "implementation") for a given class. Therefore, there
will also be two `ts.Symbol`s bound per class, and ngcc needs to switch
between those declarations and symbols depending on where certain
information can be found.

Prior to this commit, the `NgccReflectionHost` interface had methods
`getClassSymbol` and `findClassSymbols` that would return a `ts.Symbol`.
These class symbols would be used to kick off compilation of components
using ngtsc, so it is important for these symbols to correspond with the
publicly visible outer declaration of the class. However, the ESM2015
reflection host used to return the `ts.Symbol` for the inner
declaration, if the class was declared as follows:

```javascript
var MyClass = class MyClass {};
```

For the above code, `Esm2015ReflectionHost.getClassSymbol` would return
the `ts.Symbol` corresponding with the `class MyClass {}` declaration,
whereas it should have corresponded with the `var MyClass` declaration.
As a consequence, no `NgModule` could be resolved for the component, so
no components/directives would be in scope for the component. This
resulted in errors during runtime.

This commit resolves the issue by introducing a `NgccClassSymbol` that
contains references to both the outer and inner `ts.Symbol`, instead of
just a single `ts.Symbol`. This avoids the unclarity of whether a
`ts.Symbol` corresponds with the outer or inner declaration.

More details can be found here: https://hackmd.io/7nkgWOFWQlSRAuIW_8KPPw

Fixes #32078
Closes FW-1507

PR Close #32539
2019-09-12 11:12:10 -07:00
JoostK 2279cb8dc0 refactor(ngcc): move `ClassSymbol` to become `NgccClassSymbol` (#32539)
PR Close #32539
2019-09-12 11:12:10 -07:00
George Kalpakas c714330856 refactor(ngcc): add debug logging for the duration of different operations (#32427)
This gives an overview of how much time is spent in each operation/phase
and makes it easy to do rough comparisons of how different
configurations or changes affect performance.

PR Close #32427
2019-09-09 15:55:14 -04:00
George Kalpakas e36e6c85ef perf(ngcc): process tasks in parallel in async mode (#32427)
`ngcc` supports both synchronous and asynchronous execution. The default
mode when using `ngcc` programmatically (which is how `@angular/cli` is
using it) is synchronous. When running `ngcc` from the command line
(i.e. via the `ivy-ngcc` script), it runs in async mode.

Previously, the work would be executed in the same way in both modes.

This commit improves the performance of `ngcc` in async mode by
processing tasks in parallel on multiple processes. It uses the Node.js
built-in [`cluster` module](https://nodejs.org/api/cluster.html) to
launch a cluster of Node.js processes and take advantage of multi-core
systems.

Preliminary comparisons indicate a 1.8x to 2.6x speed improvement when
processing the angular.io app (apparently depending on the OS, number of
available cores, system load, etc.). Further investigation is needed to
better understand these numbers and identify potential areas of
improvement.

Inspired by/Based on @alxhub's prototype: alxhub/angular@cb631bdb1
Original design doc: https://hackmd.io/uYG9CJrFQZ-6FtKqpnYJAA?view

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

PR Close #32427
2019-09-09 15:55:13 -04:00
George Kalpakas f4e4bb2085 refactor(ngcc): implement task selection for parallel task execution (#32427)
This commit adds a new `TaskQueue` implementation that supports
executing multiple tasks in parallel (while respecting interdependencies
between them).

This new implementation is currently not used, thus the behavior of
`ngcc` is not affected by this change. The parallel `TaskQueue` will be
used in a subsequent commit that will introduce parallel task execution.

PR Close #32427
2019-09-09 15:55:13 -04:00