Commit Graph

1580 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
Andrew Kushnir 646655d09a fix(compiler): use FatalDiagnosticError to generate better error messages (#35244)
Prior to this commit, decorator handling logic in Ngtsc used `Error` to throw errors. This commit replaces most of these instances with `FatalDiagnosticError` class, which provider a better diagnostics error (including location of the problematic code).

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

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

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

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

PR Close #35371
2020-02-19 12:49:52 -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
Pete Bacon Darwin 7e8ce24116 refactor(compiler-cli): add `invalidateCaches` to `CachedFileSystem` (#35131)
This is needed by ngcc when reading volatile files that may
be changed by an external process (e.g. the lockfile).

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
JoostK 5de5b52beb fix(ivy): repeat template guards to narrow types in event handlers (#35193)
In Ivy's template type checker, event bindings are checked in a closure
to allow for accurate type inference of the `$event` parameter. Because
of the closure, any narrowing effects of template guards will no longer
be in effect when checking the event binding, as TypeScript assumes that
the guard outside of the closure may no longer be true once the closure
is invoked. For more information on TypeScript's Control Flow Analysis,
please refer to https://github.com/microsoft/TypeScript/issues/9998.

In Angular templates, it is known that an event binding can only be
executed when the view it occurs in is currently rendered, hence the
corresponding template guard is known to hold during the invocation of
an event handler closure. As such, it is desirable that any narrowing
effects from template guards are still in effect within the event
handler closure.

This commit tweaks the generated Type-Check Block (TCB) to repeat all
template guards within an event handler closure. This achieves the
narrowing effect of the guards even within the closure.

Fixes #35073

PR Close #35193
2020-02-07 13:06:00 -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
Alex Rickabaugh 3c69442dbd feat(compiler-cli): implement NgTscPlugin on top of the NgCompiler API (#34792)
This commit implements an experimental integration with tsc_wrapped, where
it can load the Angular compiler as a plugin and perform Angular
transpilation at a user's request.

This is an alternative to the current ngc_wrapped mechanism, which is a fork
of tsc_wrapped from several years ago. tsc_wrapped has improved
significantly since then, and this feature will allow Angular to benefit
from those improvements.

Currently the plugin API between tsc_wrapped and the Angular compiler is a
work in progress, so NgTscPlugin does not yet implement any interfaces from
@bazel/typescript (the home of tsc_wrapped). Instead, an interface is
defined locally to guide this standardization.

PR Close #34792
2020-02-06 15:27:34 -08:00
Alex Rickabaugh 14aa6d090e refactor(ivy): compute ignoreFiles for compilation on initialization (#34792)
This commit moves the calculation of `ignoreFiles` - the set of files to be
ignored by a consumer of the `NgCompiler` API - from its `prepareEmit`
operation to its initialization. It's now available as a field on
`NgCompiler`.

This will allow a consumer to skip gathering diagnostics for `ignoreFiles`
as well as skip emit.

PR Close #34792
2020-02-06 15:27:34 -08:00
Alex Rickabaugh c35671c0a4 fix(ivy): template type-check errors from TS should not use NG error codes (#35146)
A bug previously caused the template type-checking diagnostics produced by
TypeScript for template expressions to use -99-prefixed error codes. These
codes are converted to "NG" errors instead of "TS" errors during diagnostic
printing. This commit fixes the issue.

PR Close #35146
2020-02-04 15:59:01 -08:00
JoostK 6ddf5508db fix(ivy): support emitting a reference to interface declarations (#34849)
In #34021 the ngtsc compiler gained the ability to emit type parameter
constraints, which would generate imports for any type reference that
is used within the constraint. However, the `AbsoluteModuleStrategy`
reference emitter strategy did not consider interface declarations as a
valid declaration it can generate an import for, throwing an error
instead.

This commit fixes the issue by including interface declarations in the
logic that determines whether something is a declaration.

Fixes #34837

PR Close #34849
2020-02-04 10:40:45 -08:00
JoostK 5cada5cce1 fix(ivy): recompile on template change in ngc watch mode on Windows (#34015)
In #33551, a bug in `ngc --watch` mode was fixed so that a component is
recompiled when its template file is changed. Due to insufficient
normalization of files paths, this fix did not have the desired effect
on Windows.

Fixes #32869

PR Close #34015
2020-02-04 10:40:22 -08:00
George Kalpakas 523c785e8f fix(ngcc): correctly invalidate cache when moving/removing files/directories (#35106)
One particular scenario where this was causing problems was when the
[BackupFileCleaner][1] restored a file (such as a `.d.ts` file) by
[moving the backup file][2] to its original location, but the modified
content was kept in the cache.

[1]: https://github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts#L54
[2]: https://github.com/angular/angular/blob/4d36b2f6e/packages/compiler-cli/ngcc/src/writing/cleaning/cleaning_strategies.ts#L61

Fixes #35095

PR Close #35106
2020-02-03 14:25:47 -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 2e52fcf1eb refactor(compiler-cli): add `removeDir()` to `FileSystem` (#35079)
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
Alan Agius 6d11a81994 fix(compiler-cli): add `sass` as a valid css preprocessor extension (#35052)
`.sass` is a valid preprocessor extension which is used for Sass indented syntax

https://sass-lang.com/documentation/syntax

PR Close #35052
2020-01-31 13:28:39 -08:00
Igor Minar c070037357 refactor(compiler): rename diagnostics/src/code.ts to diagnostics/src/error_code.ts (#35067)
the new filename is less ambiguous and better reflects the name of the symbol defined in it.

PR Close #35067
2020-01-31 11:25:27 -08:00
Alex Rickabaugh 37f39d6db5 build(compiler-cli): update to chokidar 3.x (#35047)
Update from chokidar 2.x to 3.x in ngc/ngtsc, to eliminate any possibility
of a security issue with a downstream dependency of the package.

FW-1809 #resolve

PR Close #35047
2020-01-30 08:41:13 -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
Kristiyan Kostadinov 304584c291 perf(ivy): remove unused argument in hostBindings function (#34969)
We had some logic for generating and passing in the `elIndex` parameter into the `hostBindings` function, but it wasn't actually being used for anything. The only place left that had a reference to it was the `StylingBuilder` and it only stored it without referencing it again.

PR Close #34969
2020-01-27 12:49:35 -08:00
Andrew Kushnir 6e5cfd2cd2 fix(ivy): catch FatalDiagnosticError thrown from preanalysis phase (#34801)
Component's decorator handler exposes `preanalyze` method to preload async resources (templates, stylesheets). The logic in preanalysis phase may throw `FatalDiagnosticError` errors that contain useful information regarding the origin of the problem. However these errors from preanalysis phase were not intercepted in TraitCompiler, resulting in just error message text be displayed. This commit updates the logic to handle FatalDiagnosticError and transform it before throwing, so that the result diagnostic errors contain the necessary info.

PR Close #34801
2020-01-27 10:58:27 -08:00
Miško Hevery 5aabe93abe refactor(ivy): Switch styling to new reconcile algorithm (#34616)
NOTE: This change must be reverted with previous deletes so that it code remains in build-able state.

This change deletes old styling code and replaces it with a simplified styling algorithm.

The mental model for the new algorithm is:
- Create a linked list of styling bindings in the order of priority. All styling bindings ere executed in compiled order and than a linked list of bindings is created in priority order.
- Flush the style bindings at the end of `advance()` instruction. This implies that there are two flush events. One at the end of template `advance` instruction in the template. Second one at the end of `hostBindings` `advance` instruction when processing host bindings (if any).
- Each binding instructions effectively updates the string to represent the string at that location. Because most of the bindings are additive, this is a cheap strategy in most cases. In rare cases the strategy requires removing tokens from the styling up to this point. (We expect that to be rare case)S Because, the bindings are presorted in the order of priority, it is safe to resume the processing of the concatenated string from the last change binding.

PR Close #34616
2020-01-24 12:23: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
Matias Niemelä 4005815114 refactor(ivy): generate 2 slots per styling instruction (#34616)
Compiler keeps track of number of slots (`vars`) which are needed for binding instructions. Normally each binding instructions allocates a single slot in the `LView` but styling instructions need to allocate two slots.

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
Alex Rickabaugh 24b2f1da2b refactor(ivy): introduce the 'core' package and split apart NgtscProgram (#34887)
Previously, NgtscProgram lived in the main @angular/compiler-cli package
alongside the legacy View Engine compiler. As a result, the main package
depended on all of the ngtsc internal packages, and a significant portion of
ngtsc logic lived in NgtscProgram.

This commit refactors NgtscProgram and moves the main logic of compilation
into a new 'core' package. The new package defines a new API which enables
implementers of TypeScript compilers (compilers built using the TS API) to
support Angular transpilation as well. It involves a new NgCompiler type
which takes a ts.Program and performs Angular analysis and transformations,
as well as an NgCompilerHost which wraps an input ts.CompilerHost and adds
any extra Angular files.

Together, these two classes are used to implement a new NgtscProgram which
adapts the legacy api.Program interface used by the View Engine compiler
onto operations on the new types. The new NgtscProgram implementation is
significantly smaller and easier to reason about.

The new NgCompilerHost replaces the previous GeneratedShimsHostWrapper which
lived in the 'shims' package.

A new 'resource' package is added to support the HostResourceLoader which
previously lived in the outer compiler package.

As a result of the refactoring, the dependencies of the outer
@angular/compiler-cli package on ngtsc internal packages are significantly
trimmed.

This refactoring was driven by the desire to build a plugin interface to the
compiler so that tsc_wrapped (another consumer of the TS compiler APIs) can
perform Angular transpilation on user request.

PR Close #34887
2020-01-24 08:59:59 -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
George Kalpakas ba2bf82540 refactor(compiler-cli): fix typo in `TypeScriptCompilerHost#getExportsOfModule()` error message (#34811)
PR Close #34811
2020-01-23 13:58:37 -08:00
Alex Rickabaugh 5aa0507f6a docs(ivy): move incremental package README file to the correct location (#34912)
It was erroneously committed to src/.

PR Close #34912
2020-01-23 13:30:10 -08:00
Alex Rickabaugh 5b2fa3cfd3 fix(ivy): correctly emit component when it's removed from its module (#34912)
This commit fixes a bug in the incremental rebuild engine of ngtsc, where if
a component was removed from its NgModule, it would not be properly
re-emitted.

The bug stemmed from the fact that whether to emit a file was a decision
based purely on the updated dependency graph, which captures the dependency
structure of the rebuild program. This graph has no edge from the component
to its former module (as it was removed, of course), so the compiler
erroneously decides not to emit the component.

The bug here is that the compiler does know, from the previous dependency
graph, that the component file has logically changed, since its previous
dependency (the module file) has changed. This information was not carried
forward into the set of files which need to be emitted, because it was
assumed that the updated dependency graph was a more accurate source of that
information.

With this commit, the set of files which need emit is pre-populated with the
set of logically changed files, to cover edge cases like this.

Fixes #34813

PR Close #34912
2020-01-23 13:30:10 -08:00
Alex Rickabaugh 0c8d085666 fix(ivy): use any for generic context checks when !strictTemplates (#34649)
Previously, the template type-checker would always construct a generic
template context type with correct bounds, even when strictTemplates was
disabled. This meant that type-checking of expressions involving that type
was stricter than View Engine.

This commit introduces a 'strictContextGenerics' flag which behaves
similarly to other 'strictTemplates' flags, and switches the inference of
generic type parameters on the component context based on the value of this
flag.

PR Close #34649
2020-01-23 10:31:48 -08:00
Alex Rickabaugh cb11380515 fix(ivy): disable use of aliasing in template type-checking (#34649)
FileToModuleHost aliasing supports compilation within environments that have
two properties:

1. A `FileToModuleHost` exists which defines canonical module names for any
   given TS file.
2. Dependency restrictions exist which prevent the import of arbitrary files
   even if such files are within the .d.ts transitive closure of a
   compilation ("strictdeps").

In such an environment, generated imports can only go through import paths
which are already present in the user program. The aliasing system supports
the generation and consumption of such imports at runtime.

`FileToModuleHost` aliasing does not emit re-exports in .d.ts files. This
means that it's safe to rely on alias re-exports in generated .js code (they
are guaranteed to exist at runtime) but not in template type-checking code
(since TS will not be able to follow such imports). Therefore, non-aliased
imports should be used in template type-checking code.

This commit adds a `NoAliasing` flag to `ImportFlags` and sets it when
generating imports in template type-checking code. The testing environment
is also patched to support resolution of FileToModuleHost canonical paths
within the template type-checking program, enabling testing of this change.

PR Close #34649
2020-01-23 10:31:48 -08:00
Alex Rickabaugh 5b9c96b9b8 refactor(ivy): change ImportMode enum to ImportFlags (#34649)
Previously, `ReferenceEmitter.emit()` took an `ImportMode` enum value, where
one value of the enum allowed forcing new imports to be generated when
emitting a reference to some value or type.

This commit refactors `ImportMode` to be an `ImportFlags` value instead.
Using a bit field of flags will allow future customization of reference
emitting.

PR Close #34649
2020-01-23 10:31:47 -08:00
Alex Rickabaugh af015982f5 fix(ivy): wrap 'as any' casts in parentheses when needed (#34649)
Previously, when generating template type-checking code, casts to 'any' were
produced as `expr as any`, regardless of the expression. However, for
certain expression types, this led to precedence issues with the cast. For
example, `a !== b` is a `ts.BinaryExpression`, and wrapping it directly in
the cast yields `a !== b as any`, which is semantically equivalent to
`a !== (b as any)`. This is obviously not what is intended.

Instead, this commit adds a list of expression types for which a "bare"
wrapping is permitted. For other expressions, parentheses are added to
ensure correct precedence: `(a !== b) as any`

PR Close #34649
2020-01-23 10:31:47 -08:00
Alex Rickabaugh cfe5dccdd2 fix(ivy): type-check multiple bindings to the same input (#34649)
Currently, the template type-checker gives an error if there are multiple
bindings to the same input. This commit aligns the behavior of the template
type-checker with the View Engine runtime: only the first binding to a field
has any effect. The rest are ignored.

PR Close #34649
2020-01-23 10:31:47 -08:00
Alex Rickabaugh 22c957a93d fix(ivy): type-checking of properties which map to multiple fields (#34649)
It's possible to declare multiple inputs for a directive/component which all
map to the same property name. This is usually done in error, as only one of
any bindings to the property will "win".

In the template type-checker, an error was previously being raised as a
result of this ambiguity. Specifically, a type constructor was produced
which required a binding for each field, but only one of the fields had
a value via the binding. TypeScript would (rightfully) error on missing
values for the remaining fields. This ultimately was happening when the
code which generated the default values for "unset" inputs belonging to
directives or pipes used the final mapping from properties to fields as
a source for field names.

Instead, this commit uses the original list of fields to generate unset
input values, which correctly provides values for fields which shared a
property name but didn't receive the final binding.

PR Close #34649
2020-01-23 10:31:47 -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 d15cf60c49 feat(compiler-cli): require node 10 as runtime engine (#34722)
Similar to c602563 this commit aligns the node.js version
requirements of the Angular compiler with Angular CLI.

PR Close #34722
2020-01-22 15:35:34 -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
Pete Bacon Darwin 3a6cb6a5d2 refactor(ivy): add exclusive mode to `writeFile()` (#34722)
This commit adds an `exclusive` parameter to the
`FileSystem.writeFile()` method. When this parameter is
true, the method will fail with an `EEXIST` error if the
file already exists on disk.

PR Close #34722
2020-01-22 15:35:34 -08:00
Pete Bacon Darwin ecbc25044c refactor(ivy): add `removeFile` to ngtsc `FileSystem` (#34722)
PR Close #34722
2020-01-22 15:35:34 -08:00
Matias Niemelä 32489c7426 revert: refactor(ivy): remove styleSanitizer instruction in favor of an inline param (#34480) (#34910)
This reverts commit 84d24c08e1.

PR Close #34910
2020-01-22 15:59:33 -05:00
Matias Niemelä 84d24c08e1 refactor(ivy): remove styleSanitizer instruction in favor of an inline param (#34480)
This patch removes the need for the styleSanitizer() instruction in
favor of passing the sanitizer into directly into the styleProp
instruction.

This patch also increases the binding index size for all style/class bindings in preparation for #34418

PR Close #34480
2020-01-22 14:35:00 -05:00
Andrew Kushnir 39ec188003 fix(ivy): more accurate detection of pipes in host bindings (#34655)
Pipes in host binding expressions are not supported in View Engine and Ivy, but in some more complex cases (like `(value | pipe) === true`) compiler was not reporting errors. This commit extends Ivy logic to detect pipes in host binding expressions and throw in cases bindings are present. View Engine behavior remains the same.

PR Close #34655
2020-01-21 13:22:00 -05: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 a28c02bf89 build: derive ts_library dep from jasmine_node_test boostrap label if it ends in `_es5` (#34736)
PR Close #34736
2020-01-15 14:58:07 -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
Greg Magolan 93c2df23bf build: upgrade to rules_nodejs 1.0.0 (first stable release) (#34736)
Brings in the fix for stamping which was preventing many targets from getting cached.

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
Andrius 1f79e624d1 build: typescript 3.7 support (#33717)
This PR updates TypeScript version to 3.7 while retaining compatibility with TS3.6.

PR Close #33717
2020-01-14 16:42:21 -08:00
crisbeto c3c72f689a fix(ivy): handle overloaded constructors in ngtsc (#34590)
Currently ngtsc looks for the first `ConstructorDeclaration` when figuring out what the parameters are so that it can generate the DI instructions. The problem is that if a constructor has overloads, it'll have several `ConstructorDeclaration` members with a different number of parameters. These changes tweak the logic so it looks for the constructor implementation.

PR Close #34590
2020-01-14 15:17:09 -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 e88d652f2a Revert "build: upgrade to rules_nodejs 1.0.0 (first stable release) (#34589)" (#34730)
This reverts commit cb6ffa1211.

PR Close #34730
2020-01-10 14:12:15 -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
atscott 24679d8676 Revert "build: derive ts_library dep from jasmine_node_test boostrap label if it ends in `_es5` (#34589)" (#34730)
This reverts commit 79a0d007b4.

PR Close #34730
2020-01-10 14:12:14 -08:00
Greg Magolan 79a0d007b4 build: derive ts_library dep from jasmine_node_test boostrap label if it ends in `_es5` (#34589)
PR Close #34589
2020-01-10 08:32:00 -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
Greg Magolan cb6ffa1211 build: upgrade to rules_nodejs 1.0.0 (first stable release) (#34589)
Brings in the fix for stamping which was preventing many targets from getting cached.

PR Close #34589
2020-01-10 08:31:58 -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
Pete Bacon Darwin 570574df5b fix(ngcc): don't crash if symbol has no declarations (#34658)
In some cases TypeScript is unable to identify a valid
symbol for an export. In this case it returns an "unknown"
symbol, which does not reference any declarations.

This fix ensures that ngcc does not crash if such a symbol
is encountered by checking whether `symbol.declarations`
exists before accessing it.

The commit does not contain a unit test as it was not possible
to recreate a scenario that had such an "unknown" symbol in
the unit test environment. The fix has been manually checked
against that original issue; and also this check is equivalent to
similar checks elsewhere in the code, e.g.

https://github.com/angular/angular/blob/8d0de89e/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts#L309

Fixes #34560

PR Close #34658
2020-01-08 15:07:10 -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
Andrew Scott 4d7a9db44c fix(ivy): Ensure ngProjectAs marker name appears at even attribute index (#34617)
The `getProjectAsAttrValue` in `node_selector_matcher` finds the
ProjectAs marker and then additionally checks that the marker appears in
an even index of the node attributes because "attribute names are stored
at even indexes". This is true for "regular" attribute bindings but
classes, styles, bindings, templates, and i18n do not necessarily follow
this rule because there can be an uneven number of them, causing the
next "special" attribute "name" to appear at an odd index. To address
this issue, ensure ngProjectAs is placed right after "regular"
attributes.

PR Close #34617
2020-01-07 10:51:46 -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
Andrew Kushnir b4c5bdb093 fix(ivy): append `advance` instructions before `i18nExp` (#34436)
Prior to this commit, there were no `advance` instructions generated before `i18nExp` instructions and as a result, lifecycle hooks for components used inside i18n blocks were flushed too late. This commit adds the logic to generate `advance` instructions in front of `i18nExp` ones (similar to what we have in other places like interpolations, property bindings, etc), so that the necessary lifecycle hooks are flushed before expression value is captured.

PR Close #34436
2020-01-07 10:31:45 -08:00
JoostK e116816131 refactor(ivy): let `strictTemplates` imply `fullTemplateTypeCheck` (#34195)
Previously, it was required that both `fullTemplateTypeCheck` and
`strictTemplates` had to be enabled for strict mode to be enabled. This
is strange, as `strictTemplates` implies `fullTemplateTypeCheck`. This
commit makes setting the `fullTemplateTypeCheck` flag optional so that
strict mode can be enabled by just setting `strictTemplates`.

PR Close #34195
2020-01-06 11:07:54 -08:00
JoostK 2e82357611 refactor(ivy): verify template type check options are compatible (#34195)
It is now an error if '"fullTemplateTypeCheck"' is disabled while
`"strictTemplates"` is enabled, as enabling the latter implies that the
former is also enabled.

PR Close #34195
2020-01-06 11:07:54 -08:00
JoostK 1de49ba369 refactor(ivy): consistently translate types to `ts.TypeNode` (#34021)
The compiler has a translation mechanism to convert from an Angular
`Type` to a `ts.TypeNode`, as appropriate. Prior to this change, it
would translate certain Angular expressions into their value equivalent
in TypeScript, instead of the correct type equivalent. This was possible
as the `ExpressionVisitor` interface is not strictly typed, with `any`s
being used for return values.

For example, a literal object was translated into a
`ts.ObjectLiteralExpression`, containing `ts.PropertyAssignment` nodes
as its entries. This has worked without issues as their printed
representation is identical, however it was incorrect from a semantic
point of view. Instead, a `ts.TypeLiteralNode` is created with
`ts.PropertySignature` as its members, which corresponds with the type
declaration of an object literal.

PR Close #34021
2020-01-06 11:06:07 -08:00
JoostK f27187c063 perf(ivy): support simple generic type constraints in local type ctors (#34021)
In Ivy's template type checker, type constructors are created for all
directive types to allow for accurate type inference to work. The type
checker has two strategies for dealing with such type constructors:

1. They can be emitted local to the type check block/type check file.
2. They can be emitted as static `ngTypeCtor` field into the directive
itself.

The first strategy is preferred, as it avoids having to update the
directive type which would cause a more expensive rebuild. However, this
strategy is not suitable for directives that have constrained generic
types, as those constraints would need to be present on the local type
constructor declaration. This is not trivial, as it requires that any
type references within a type parameter's constraint are imported into
the local context of the type check block.

For example, lets consider the `NgForOf` directive from '@angular/core'
looks as follows:

```typescript
import {NgIterable} from '@angular/core';

export class NgForOf<T, U extends NgIterable<T>> {}
```

The type constructor will then have the signature:
`(o: Pick<i1.NgForOf<T, U>, 'ngForOf'>) => i1.NgForOf<T, U>`

Notice how this refers to the type parameters `T` and `U`, so the type
constructor needs to be emitted into a scope where those types are
available, _and_ have the correct constraints.

Previously, the template type checker would detect the situation where a
type parameter is constrained, and would emit the type constructor
using strategy 2; within the directive type itself. This approach makes
any type references within the generic type constraints lexically
available:

```typescript
export class NgForOf<T, U extends NgIterable<T>> {
  static ngTypeCtor<T = any, U extends NgIterable<T> = any>
    (o: Pick<NgForOf<T, U>, 'ngForOf'>): NgForOf<T, U> { return null!; }
}
```

This commit introduces the ability to emit a type parameter with
constraints into a different context, under the condition that it can
be imported from an absolute module. This allows a generic type
constructor to be emitted into a type check block or type check file
according to strategy 1, as imports have been generated for all type
references within generic type constraints. For example:

```typescript
import * as i0 from '@angular/core';
import * as i1 from '@angular/common';

const _ctor1: <T = any, U extends i0.NgIterable<T> = any>
  (o: Pick<i1.NgForOf<T, U>, 'ngForOf'>) => i1.NgForOf<T, U> = null!;
```

Notice how the generic type constraint of `U` has resulted in an import
of `@angular/core`, and the `NgIterable` is transformed into a qualified
name during the emitting process.

Resolves FW-1739

PR Close #34021
2020-01-06 11:06:07 -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