Commit Graph
234 Commits
Author SHA1 Message Date
Paul Gschwendtner 2d0ff0a5d3 ci: add lint error for files with missing trailing new-line (#42478)
For quite a while it is an unspoken convention to add a trailing
new-line files within the Angular repository. This was never enforced
automatically, but has been frequently raised in pull requests through
manual review. This commit sets up a lint rule so that this is
"officially" enforced and doesn't require manual review.

PR Close #42478
2021-06-04 13:31:03 -07:00
Alex Rickabaugh c9aa87cec0 fix(compiler-cli): show a more specific error for Ivy NgModules (#41534)
When an Ivy NgModule is imported into a View Engine build, it doesn't have
metadata.json files that describe it as an NgModule, so it appears to VE
builds as a plain, undecorated class. The error message shown in this
situation generic and confusing, since it recommends adding an @NgModule
annotation to a class from a library.

This commit adds special detection into the View Engine compiler to give a
more specific error message when an Ivy NgModule is imported.

PR Close #41534
2021-04-13 07:34:45 -07:00
Kristiyan Kostadinov ec27bd4ed1 feat(compiler): support nullish coalescing in templates (#41437)
Adds support for nullish coalescing expressions inside of Angular templates (e.g. `{{ a ?? b ?? c}}`).

Fixes #36528.

PR Close #41437
2021-04-07 12:04:28 -07:00
Alan Agius dc655262be refactor(compiler): remove TypeScript 4.0 program reuse check (#41406)
We no longer support TS 4.0, hence this check is redundant.

PR Close #41406
2021-04-02 15:47:54 -07:00
Andrew Scott 54b088967a refactor(compiler): remove unreachable code (#40984)
1. The error function throws, so no code after it is reachable.
2. Some switch statements are exhaustive, so no code after them are reachable.

PR Close #40984
2021-03-01 15:29:20 -08:00
Joey Perrott b75d7cb11f fix(compiler-cli): update type castings for JSON.parse usage (#40710)
Update usages of JSON.parse to be cast as specific types.

PR Close #40710
2021-02-09 10:48:43 -08:00
Alexey Elin cf02cf1e18 docs: remove duplicated the (#40434)
PR Close #40434
2021-01-14 11:33:57 -08:00
JoostK 27d0e54705 fix(compiler-cli): prevent stack overflow in decorator transform for large number of files (#40374)
The decorator downleveling transform patches `ts.EmitResolver.isReferencedAliasDeclaration`
to prevent elision of value imports that occur only in a type-position, which would
inadvertently install the patch repeatedly for each source file in the program.
This could potentially result in a stack overflow when a very large number of files is
present in the program.

This commit fixes the issue by ensuring that the patch is only applied once.
This is also a slight performance improvement, as `isReferencedAliasDeclaration`
is no longer repeatedly calling into all prior installed patch functions.

Fixes #40276

PR Close #40374
2021-01-11 10:39:10 -08:00
Bjarki ef892743ec feat(compiler): support tagged template literals in code generator (#39122)
Add a TaggedTemplateExpr to represent tagged template literals in
Angular's syntax tree (more specifically Expression in output_ast.ts).
Also update classes that implement ExpressionVisitor to add support for
tagged template literals in different contexts, such as JIT compilation
and conversion to JS.

Partial support for tagged template literals had already been
implemented to support the $localize tag used by Angular's i18n
framework. Where applicable, this code was refactored to support
arbitrary tags, although completely replacing the i18n-specific support
for the $localize tag with the new generic support for tagged template
literals may not be completely trivial, and is left as future work.

PR Close #39122
2020-12-07 16:20:04 -08:00
Charles Lyding 318255a5f8 build: support building with TypeScript 4.1 (#39571)
TypeScript 4.1 is now used to build and test within the repository.

PR Close #39571
2020-11-25 11:10:01 -08:00
Charles Lyding a7e7c211b5 feat(compiler-cli): add support for using TypeScript 4.1 (#39571)
This change enables projects to be built with TypeScript 4.1.  Support for TypeScript 4.0 is also retained.

PR Close #39571
2020-11-25 11:10:00 -08:00
Marcono1234 3e1e5a15ba docs: update links to use HTTPS as protocol (#39718)
PR Close #39718
2020-11-20 12:52:16 -08:00
Alan Agius 0929099e41 refactor(compiler-cli): remove TypeScript 3.9 workarounds (#39586)
With this change we remove code which was used to support both TypeScript 3.9 and TypeScript 4.0

This code is now no longer needed because G3 is on TypeScript 4.0

PR Close #39586
2020-11-06 15:26:51 -08:00
Pete Bacon Darwin b9b9178458 fix(compiler-cli): do not drop non-Angular decorators when downleveling (#39577)
There is a compiler transform that downlevels Angular class decorators
to static properties so that metadata is available for JIT compilation.
The transform was supposed to ignore non-Angular decorators but it was
actually completely dropping decorators that did not conform to a very
specific syntactic shape (i.e. the decorator was a simple identifier, or
a namespaced identifier).

This commit ensures that all non-Angular decorators are kepts as-is
even if they are built using a syntax that the Angular compiler does not
understand.

Fixes #39574

PR Close #39577
2020-11-06 09:21:51 -08:00
Pete Bacon Darwin 05672ab136 refactor(compiler-cli): attachComments() now expects a defined leadingComments array (#39076)
Previously the value passed to `AstFactory.attachComments()` could be
`undefined` which is counterintuitive, since why attach something that
doesn't exist? Now it expects there to be a defined array. Further it no
longer returns a statement. Both these aspects of the interface were designed
to make the usage simpler but has the result of complicating the implemenation.

The `ExpressionTranslatorVisitor` now has a helper function (`attachComments()`)
to handle `leadingComments` being undefined and also returning the statement.
This keeps the usage in the translator simple, while ensuring that the `AstFactory`
API is not influenced by how it is used.

PR Close #39076
2020-10-06 11:33:55 -07:00
Pete Bacon Darwin d795a00137 refactor(compiler): replace Comment nodes with leadingComments property (#38811)
Common AST formats such as TS and Babel do not use a separate
node for comments, but instead attach comments to other AST nodes.
Previously this was worked around in TS by creating a `NotEmittedStatement`
AST node to attach the comment to. But Babel does not have this facility,
so it will not be a viable approach for the linker.

This commit refactors the output AST, to remove the `CommentStmt` and
`JSDocCommentStmt` nodes. Instead statements have a collection of
`leadingComments` that are rendered/attached to the final AST nodes
when being translated or printed.

PR Close #38811
2020-09-18 08:01:25 -07:00
Alan Agius 0fc44e0436 feat(compiler-cli): add support for TypeScript 4.0 (#38076)
With this change we add support for TypeScript 4.0

PR Close #38076
2020-08-24 13:06:59 -07:00
JoostK 874792dc43 feat(compiler): support unary operators for more accurate type checking (#37918)
Prior to this change, the unary + and - operators would be parsed as `x - 0`
and `0 - x` respectively. The runtime semantics of these expressions are
equivalent, however they may introduce inaccurate template type checking
errors as the literal type is lost, for example:

```ts
@Component({
  template: `<button [disabled]="isAdjacent(-1)"></button>`
})
export class Example {
  isAdjacent(direction: -1 | 1): boolean { return false; }
}
```

would incorrectly report a type-check error:

> error TS2345: Argument of type 'number' is not assignable to parameter
  of type '-1 | 1'.

Additionally, the translated expression for the unary + operator would be
considered as arithmetic expression with an incompatible left-hand side:

> error TS2362: The left-hand side of an arithmetic operation must be of
  type 'any', 'number', 'bigint' or an enum type.

To resolve this issues, the implicit transformation should be avoided.
This commit adds a new unary AST node to represent these expressions,
allowing for more accurate type-checking.

Fixes #20845
Fixes #36178

PR Close #37918
2020-08-21 12:25:53 -07:00
crisbeto e7da4040d6 fix(compiler-cli): adding references to const enums in runtime code (#38542)
We had a couple of places where we were assuming that if a particular
symbol has a value, then it will exist at runtime. This is true in most cases,
but it breaks down for `const` enums.

Fixes #38513.

PR Close #38542
2020-08-21 12:23:21 -07:00
Paul Gschwendtner 66e6b932d8 refactor(compiler-cli): skip class decorators in tooling constructor parameters transform (#37545)
We recently added a transformer to NGC that is responsible for downleveling Angular
decorators and constructor parameter types. The primary goal was to mitigate a
TypeScript limitation/issue that surfaces in Angular projects due to the heavy
reliance on type metadata being captured for DI. Additionally this is a pre-requisite
of making `tsickle` optional in the Angular bazel toolchain.

See: 401ef71ae5 for more context on this.

Another (less important) goal was to make sure that the CLI can re-use
this transformer for its JIT mode compilation. The CLI (as outlined in
the commit mentioned above), already has a transformer for downleveling
constructor parameters. We want to avoid this duplication and exported
the transform through the tooling-private compiler entry-point.

Early experiments in using this transformer over the current one, highlighted
that in JIT, class decorators cannot be downleveled. Angular relies on those
to be invoked immediately for JIT (so that factories etc. are generated upon loading)

The transformer we exposed, always downlevels such class decorators
though, so that would break CLI's JIT mode. We can address the CLI's
needs by adding another flag to skip class decorators. This will allow
us to continue with the goal of de-duplication.

PR Close #37545
2020-06-15 12:47:57 -07:00
Paul Gschwendtner 401ef71ae5 fix(compiler-cli): downlevel angular decorators to static properties (#37382)
In v7 of Angular we removed `tsickle` from the default `ngc` pipeline.
This had the negative potential of breaking ES2015 output and SSR due
to a limitation in TypeScript.

TypeScript by default preserves type information for decorated constructor
parameters when `emitDecoratorMetadata` is enabled. For example,
consider this snippet below:

```
@Directive()
export class MyDirective {
  constructor(button: MyButton) {}
}

export class MyButton {}
```

TypeScript would generate metadata for the `MyDirective` class it has
a decorator applied. This metadata would be needed in JIT mode, or
for libraries that provide `MyDirective` through NPM. The metadata would
look as followed:

```
let MyDirective = class MyDir {}

MyDirective = __decorate([
  Directive(),
  __metadata("design:paramtypes", [MyButton]),
], MyDirective);

let MyButton = class MyButton {}
```

Notice that TypeScript generated calls to `__decorate` and
`__metadata`. These calls are needed so that the Angular compiler
is able to determine whether `MyDirective` is actually an directive,
and what types are needed for dependency injection.

The limitation surfaces in this concrete example because `MyButton`
is declared after the `__metadata(..)` call, while `__metadata`
actually directly references `MyButton`. This is illegal though because
`MyButton` has not been declared at this point. This is due to the
so-called temporal dead zone in JavaScript. Errors like followed will
be reported at runtime when such file/code evaluates:

```
Uncaught ReferenceError: Cannot access 'MyButton' before initialization
```

As noted, this is a TypeScript limitation because ideally TypeScript
shouldn't evaluate `__metadata`/reference `MyButton` immediately.
Instead, it should defer the reference until `MyButton` is actually
declared. This limitation will not be fixed by the TypeScript team
though because it's a limitation as per current design and they will
only revisit this once the tc39 decorator proposal is finalized
(currently stage-2 at time of writing).

Given this wontfix on the TypeScript side, and our heavy reliance on
this metadata in libraries (and for JIT mode), we intend to fix this
from within the Angular compiler by downleveling decorators to static
properties that don't need to evaluate directly. For example:

```
MyDirective.ctorParameters = () => [MyButton];
```

With this snippet above, `MyButton` is not referenced directly. Only
lazily when the Angular runtime needs it. This mitigates the temporal
dead zone issue caused by a limitation in TypeScript's decorator
metadata output. See: https://github.com/microsoft/TypeScript/issues/27519.

In the past (as noted; before version 7), the Angular compiler by
default used tsickle that already performed this transformation. We
moved the transformation to the CLI for JIT and `ng-packager`, but now
we realize that we can move this all to a single place in the compiler
so that standalone ngc consumers can benefit too, and that we can
disable tsickle in our Bazel `ngc-wrapped` pipeline (that currently
still relies on tsickle to perform this decorator processing).

This transformation also has another positive side-effect of making
Angular application/library code more compatible with server-side
rendering. In principle, TypeScript would also preserve type information
for decorated class members (similar to how it did that for constructor
parameters) at runtime. This becomes an issue when your application
relies on native DOM globals for decorated class member types. e.g.

```
@Input() panelElement: HTMLElement;
```

Your application code would then reference `HTMLElement` directly
whenever the source file is loaded in NodeJS for SSR. `HTMLElement`
does not exist on the server though, so that will become an invalid
reference. One could work around this by providing global mocks for
these DOM symbols, but that doesn't match up with other places where
dependency injection is used for mocking DOM/browser specific symbols.

More context in this issue: #30586. The TL;DR here is that the Angular
compiler does not care about types for these class members, so it won't
ever reference `HTMLElement` at runtime.

Fixes #30106. Fixes #30586. Fixes #30141.
Resolves FW-2196. Resolves FW-2199.

PR Close #37382
2020-06-10 09:24:11 -07:00
Joey Perrott d1ea1f4c7f build: update license headers to reference Google LLC (#37205)
Update the license headers throughout the repository to reference Google LLC
rather than Google Inc, for the required license headers.

PR Close #37205
2020-05-26 14:26:58 -04:00
Alex Rickabaugh 0a69a2832b style(compiler-cli): reformat of codebase with new clang-format version (#36520)
This commit reformats the packages/compiler-cli tree using the new version
of clang-format.

PR Close #36520
2020-04-08 14:51:08 -07:00
JoostK 75afd80ae8 refactor(compiler): add @nocollapse annotation using a synthetic comment (#35932)
In Ivy, Angular decorators are compiled into static fields that are
inserted into a class declaration in a TypeScript transform. When
targeting Closure compiler such fields need to be annotated with
`@nocollapse` to prevent them from being lifted from a static field into
a variable, as that would prevent the Ivy runtime from being able to
find the compiled definitions.

Previously, there was a bug in TypeScript where synthetic comments added
in a transform would not be emitted at all, so as a workaround a global
regex-replace was done in the emit's `writeFile` callback that would add
the `@nocollapse` annotation to all static Ivy definition fields. This
approach is no longer possible when ngtsc is running as TypeScript
plugin, as a plugin cannot control emit behavior.

The workaround is no longer necessary, as synthetic comments are now
properly emitted, likely as of
https://github.com/microsoft/TypeScript/pull/22141 which has been
released with TypeScript 2.8.

This change is required for running ngtsc as TypeScript plugin in
Bazel's `ts_library` rule, to move away from the custom `ngc_wrapped`
approach.

Resolves FW-1952

PR Close #35932
2020-04-01 15:37:06 -07:00
Alex Rickabaugh 95c729f5d1 build: typescript 3.8 support (#35864)
This commit adds support in the Angular monorepo and in the Angular
compiler(s) for TypeScript 3.8. All packages can now compile with
TS 3.8.

For most of the repo, only a handful few typings adjustments were needed:

* TS 3.8 has a new `CustomElementConstructor` DOM type, which enforces a
  zero-argument constructor. The `NgElementConstructor` type previously
  declared a required `injector` argument despite the fact that its
  implementation allowed `injector` to be optional. The interface type was
  updated to reflect the optionality of the argument.
* Certain error messages were changed, and expectations in tests were
  updated as a result.
* tsserver (part of language server) now returns performance information in
  responses, so test expectations were changed to only assert on the actual
  body content of responses.

For compiler-cli and schematics (which use the TypeScript AST) a major
breaking change was the introduction of the export form:

```typescript
export * as foo from 'bar';
```

This is a `ts.NamespaceExport`, and the `exportClause` of a
`ts.ExportDeclaration` can now take this type as well as `ts.NamedExports`.
This broke a lot of places where `exportClause` was assumed to be
`ts.NamedExports`.

For the most part these breakages were in cases where it is not necessary
to handle the new `ts.NamedExports` anyway. ngtsc's design uses the
`ts.TypeChecker` APIs to understand syntax and so automatically supports the
new form of exports.

The View Engine compiler on the other hand extracts TS structures into
metadata.json files, and that format was not designed for namespaced
exports. As a result it will take a nontrivial amount of work if we want to
support such exports in View Engine. For now, these new exports are not
accounted for in metadata.json, and so using them in "folded" Angular
expressions will result in errors (probably claiming that the referenced
exported namespace doesn't exist).

Care was taken to only use TS APIs which are present in 3.7/3.6, as Angular
needs to remain compatible with these for the time being.

This commit does not update angular.io.

PR Close #35864
2020-03-10 17:51:20 -04:00
Yiting Wang c296bfcaf9 fix(compiler-cli): suppress extraRequire errors in Closure Compiler (#35737)
This is needed to support https://github.com/angular/tsickle/pull/1133
because it will add an extra require on `tslib`.

PR Close #35737
2020-03-04 08:37:03 -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
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
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
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