Commit Graph
1135 Commits
Author SHA1 Message Date
JoostK c18c7e23ec fix(compiler): exclude trailing whitespace from element source spans (#40513)
If the template parse option `leadingTriviaChars` is configured to
consider whitespace as trivia, any trailing whitespace of an element
would be considered as leading trivia of the subsequent element, such
that its `start` span would start _after_ the whitespace. This means
that the start span cannot be used to mark the end of the current
element, as its trailing whitespace would then be included in its span.
Instead, the full start of the subsequent element should be used.

To harden the tests that for the Ivy parser, the test utility `parseR3`
has been adjusted to use the same configuration for `leadingTriviaChars`
as would be the case in its production counterpart `parseTemplate`. This
uncovered another bug in offset handling of the interpolation parser,
where the absolute offset was computed from the start source span
(which excludes leading trivia) whereas the interpolation expression
would include the leading trivia. As such, the absolute offset now also
uses the full start span.

Fixes #39148

PR Close #40513
2021-01-28 08:53:02 -08:00
Alex Rickabaugh be979c907b perf(compiler-cli): introduce fast path for resource-only updates (#40561)
This commit adds a new `IncrementalResourceCompilationTicket` which reuses
an existing `NgCompiler` instance and updates it to optimally process
template-only and style-only changes. Performing this update involves both
instructing `DecoratorHandler`s to react to the resource changes, as well as
invalidating `TemplateTypeChecker` state for the component(s) in question.
That way, querying the `TemplateTypeChecker` will trigger new TCB generation
for the changed template(s).

PR Close #40561
2021-01-27 10:45:57 -08:00
Alex Rickabaugh 52aeb5326d refactor(compiler-cli): split template parsing into declaration/parse steps (#40561)
To prepare for the optimization of template-only changes, this commit
refactors the `ComponentDecoratorHandler`'s handling of template parsing.
Previously, templates were extracted from the raw decorator metadata and
parsed in a single operation.

To better handle incremental template updates, this commit splits this
operation into a "declaration" step where the template info is extracted
from the decorator metadata, and a "parsing" step where the declared
template is read and parsed. This allows for re-reading and re-parsing of
the declared template at a future point, using the same template declaration
extracted from the decorator.

PR Close #40561
2021-01-27 10:45:57 -08:00
Alex Rickabaugh 21e24d1474 refactor(compiler-cli): introduce CompilationTicket system for NgCompiler (#40561)
Previously, the incremental flow for NgCompiler was simple: when creating a
new NgCompiler instance, the consumer could pass state from a previous
compilation, which would cause the new compilation to be performed
incrementally. "Local" information about TypeScript files which had not
changed would be passed from the old compilation to the new and reused,
while "global" information would always be recalculated.

However, this flow could be made more efficient in certain cases, such as
when no TypeScript files are changed in a new compilation. In this case,
_all_ information extracted during the first compilation is reusable. Doing
this involves reusing the previous `NgCompiler` instance (the container for
such global information) and updating it, instead of creating a new one for
the next compilation. This approach works cleanly, but complicates the
lifecycle of `NgCompiler`.

To prevent consumers from having to deal with the mechanics of reuse vs
incremental steps of `NgCompiler`, a new `CompilationTicket` mechanism is
added in this commit. Consumers obtain a `CompilationTicket` via one of
several code paths depending on the nature of the incoming compilation, and
use the `CompilationTicket` to obtain an `NgCompiler` instance. This
instance may be a fresh compilation, a new `NgCompiler` for an incremental
compilation, or an existing `NgCompiler` that's been updated to optimally
process a resource-only change. Consumers can use the new `NgCompiler`
without knowledge of its provenance.

PR Close #40561
2021-01-27 10:45:57 -08:00
Keen Yee Liau ecae75f477 feat(language-service): Add diagnostics to suggest turning on strict mode (#40423)
This PR adds a way for the language server to retrieve compiler options
diagnostics via `languageService.getCompilerOptionsDiagnostics()`.

This will be used by the language server to show a prompt in the editor if
users don't have `strict` or `fullTemplateTypeCheck` turned on.

Ref https://github.com/angular/vscode-ng-language-service/issues/1053

PR Close #40423
2021-01-25 14:17:31 -08:00
Pete Bacon Darwin dc06873c72 fix(compiler-cli): handle pseudo cycles in inline source-maps (#40435)
When a source-map has an inline source, any source-map linked from
that source should only be loaded if itself is also inline; it should not
attempt to load a source-map from the file-system. Otherwise we can
find ourselves with inadvertent infinite cyclic dependencies.

For example, if a transpiler takes a file (e.g. index.js) and generates
a new file overwriting the original file - capturing the original
source inline in the new source-map (index.js.map) - the source
file loader might read the inline original file (also index.js) and
then try to load the `index.js.map` file from disk - ad infinitum.

Note that the first call to `loadSourceFile()` is special, since you can
pass in the source-file and source-map contents directly as in-memory
strrngs. This is common if the transpiler has just generated these and has
not yet written them to disk.
When the contents are passed into `loadSourceFile()` directly, they are
not treated as "inline" for the purposes described above since there is
no chance of these "in-memory" source and source-map contents being caught
up in a cyclic dependency.

Fixes #40408

PR Close #40435
2021-01-21 14:06:57 -08:00
twerske afabb83696 refactor(core): add links to top compiler errors (#40326)
add links to 5 compiler error messages
navigate user to AIO new /errors pages for debugging

PR Close #40326
2021-01-19 10:14:57 -08:00
Misko Hevery e32b6256ce fix(core): QueryList should not fire changes if the underlying list did not change. (#40091)
Previous implementation would fire changes `QueryList.changes.subscribe`
whenever the `QueryList` was recomputed. This resulted in artificially
high number of change notifications, as it is possible that recomputing
`QueryList` results in the same list. When the `QueryList` gets recomputed
is an implementation detail and it should not be the thing which determines
how often change event should fire.

This change introduces a new `emitDistinctChangesOnly` option for
`ContentChildren` and `ViewChildren`.

```
export class QueryCompWithStrictChangeEmitParent {
  @ContentChildren('foo', {
    // This option will become the default in the future
    emitDistinctChangesOnly: true,
  })
  foos!: QueryList<any>;
}
```

PR Close #40091
2021-01-14 13:55:02 -08:00
Alexey Elin cf02cf1e18 docs: remove duplicated the (#40434)
PR Close #40434
2021-01-14 11:33:57 -08:00
Zach Arend 4db89f4576 fix(compiler-cli): report non-template diagnostics (#40331)
Report non-template diagnotics when calling `getDiagnotics` function of
the language service we only returned template diagnotics. This change
causes it to return all diagnotics, not just diagnostics from the
template type checker.

PR Close #40331
2021-01-13 10:55:04 -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
Pete Bacon Darwin e27b920ac3 refactor(compiler-cli): split up NodeJSFileSystem class (#40281)
This class is refactored to extend the new `NodeJSReadonlyFileSystem`
which itself extends `NodeJSPathManipulation`. These new classes allow
consumers to create file-systems that provide a subset of the full file-system.

PR Close #40281
2021-01-08 09:34:44 -08:00
Pete Bacon Darwin d100a15998 refactor(compiler-cli): update to use new file-system interfaces (#40281)
Now that `ReadonlyFileSystem` and `PathManipulation` interfaces are
available, this commit updates the compiler-cli to use these more
focussed interfaces.

PR Close #40281
2021-01-08 09:34:44 -08:00
Pete Bacon Darwin 80b1ba9f95 refactor(compiler-cli): split the FileSystem interface up (#40281)
This interface now extends `ReadonlyFileSystem` which in turn
extends `PathManipulation`. This means consumers of these
interfaces can be more specific about what is needed, and so
providers do not need to implement unnecessary methods.

PR Close #40281
2021-01-08 09:34:44 -08:00
Andrew Scott 46ea684351 refactor(compiler-cli): find symbol for output when there is a two way binding (#40185)
This commit fixes the Template Type Checker's `getSymbolOfNode` so that
it is able to retrieve a symbol for the `BoundEvent` of a two-way
binding. Previously, the implementation would locate the node in the TCB
for the input because it appeared first and shares the same `keySpan` as
the event binding. To fix this, the TCB node search now verifies that
the located node matches the expected name for the output subscription:
either `addEventListener` for a native listener  or the class member of the Angular `@Output`
in the case of an Angular output, as would be the case for two-way
bindings.

PR Close #40185
2021-01-07 13:18:38 -08:00
Kristiyan Kostadinov 104546569e fix(compiler): incorrectly interpreting some HostBinding names (#40233)
Currently when analyzing the metadata of a directive, we bundle together the bindings from `host`
and the `HostBinding` and `HostListener` together. This can become a problem later on in the
compilation pipeline, because we try to evaluate the value of the binding, causing something like
`@HostBinding('class.foo') public true = 1;` to be treated the same as
`host: {'[class.foo]': 'true'}`.

While looking into the issue, I noticed another one that is closely related: we weren't treating
quoted property names correctly. E.g. `@HostBinding('class.foo') public "foo-bar" = 1;` was being
interpreted as `classProp('foo', ctx.foo - ctx.bar)` due to the same issue where property names
were being evaluated.

These changes resolve both of the issues by treating all `HostBinding` instance as if they're
reading the property from `this`. E.g. the `@HostBinding('class.foo') public true = 1;` from above
is now being treated as `host: {'[class.foo]': 'this.true'}` which further down the pipeline becomes
`classProp('foo', ctx.true)`. This doesn't have any payload size implications for existing code,
because we've always been prefixing implicit property reads with `ctx.`. If the property doesn't
have an identifier that can be read using dotted access, we convert it to a quoted one (e.g.
`classProp('foo', ctx['is-foo']))`.

Fixes #40220.
Fixes #40230.
Fixes #18698.

PR Close #40233
2021-01-07 13:15:46 -08:00
Pete Bacon Darwin 3158858059 fix(compiler-cli): do not duplicate repeated source-files in rendered source-maps (#40237)
When a source-map/source-file tree has nodes that refer to the same file, the
flattened source-map rendering was those files multiple times, rather than
consolidating them into a single source-map source.

PR Close #40237
2021-01-07 13:12:53 -08:00
Pete Bacon Darwin e7c3687936 refactor(compiler): synthesize external template node for partial compilation (#40237)
When partially compiling a component with an external template, we must
synthesize a new AST node for the string literal that holds the contents of
the external template, since we want to source-map this expression directly
back to the original external template file.

PR Close #40237
2021-01-07 13:12:53 -08:00
Andrew Scott 989b4a94d4 refactor(compiler-cli): Return symbols for all matching outputs (#40144)
This commit ensures that the template type checker returns symbols for
all outputs if a template output listener binds to more than one.

PR Close #40144
2021-01-06 13:53:46 -08:00
Andrew Scott da2be4b710 refactor(compiler-cli): Return symbols for all matching inputs (#40144)
This commit ensures that the template type checker returns symbols for
all inputs if an attribute binds to more than one.

PR Close #40144
2021-01-06 13:53:46 -08:00
Keen Yee Liau a62416c6e4 fix(language-service): include compilerOptions.rootDir in rootDirs (#40243)
When resolving references, the Ivy compiler has a few strategies it could use.

For relative path, one of strategies is [`RelativePathStrategy`](
https://github.com/angular/angular/blob/master/packages/compiler-cli/src/
ngtsc/imports/README.md#relativepathstrategy). This strategy
relies on `compilerOptions.rootDir` and `compilerOptions.rootDirs` to perform
the resolution, but language service only passes `rootDirs` to the compiler,
and not `rootDir`.

In reality, `rootDir` is very different from `rootDirs` even though they
sound the same.
According to the official [TS documentation][1],
> `rootDir` specifies the root directory of input files. Only use to control
> the output directory structure with --outDir.

> `rootDirs` is a list of root folders whose combined content represent the
> structure of the project at runtime. See [Module Resolution documentation](
> https://www.typescriptlang.org/docs/handbook/
> module-resolution.html#virtual-directories-with-rootdirs)
> for more details.

For now, we keep the behavior between compiler and language service consistent,
but we will revisit the notion of `rootDir` and how it is used later.

Fix angular/vscode-ng-language-service#1039

[1]: https://www.typescriptlang.org/docs/handbook/compiler-options.html

PR Close #40243
2021-01-06 10:54:11 -08:00
JoostK d4327d51d1 feat(compiler-cli): JIT compilation of component declarations (#40127)
The `ɵɵngDeclareComponent` calls are designed to be translated to fully
AOT compiled code during a build transform, but in cases this is not
done it is still possible to compile the declaration object in the
browser using the JIT compiler. This commit adds a runtime
implementation of `ɵɵngDeclareComponent` which invokes the JIT compiler
using the declaration object, such that a compiled component definition
is made available to the Ivy runtime.

PR Close #40127
2021-01-06 08:28:03 -08:00
Andrew Scott d466db8285 fix(language-service): Do not include $event parameter in reference results (#40158)
Given the template
`<div (click)="doSomething($event)"></div>`

If you request references for the `$event`, the results include both `$event` and `(click)="doSomething($event)"`.

This happens because in the TCB, `$event` is passed to the `subscribe`/`addEventListener`
function as an argument. So when we ask typescript to give us the references, we
get the result from the usage in the subscribe body as well as the one passed in as an argument.

This commit adds an identifier to the `$event` parameter in the TCB so
that the result returned from `getReferencesAtPosition` can be
identified and filtered out.

fixes #40157

PR Close #40158
2021-01-05 10:07:20 -08:00
Pete Bacon Darwin 34f083c8ed fix(compiler-cli): handle \r\n line-endings correctly in source-mapping (#40187)
Previously `\r\n` was being treated as a single character in source-map
line start positions, which caused segment positions to become offset.

Now the `\r` is ignored when splitting, leaving it at the end of the
previous line, which solves the offsetting problem, and does not affect
source-mappings.

Fixes #40169
Fixes #39654

PR Close #40187
2020-12-22 14:50:57 -08:00
Zach Arend db97453ca0 refactor(compiler-cli): move template parse errors to TemplateData (#40026)
Durring analysis we find template parse errors. This commit changes
where the type checking context stores the parse errors. Previously, we
stored them on the AnalysisOutput this commit changes the errors to be
stored on the TemplateData (which is a property on the shim). That way,
the template parse errors can be grouped by template.

Previously, if a template had a parse error, we poisoned the module and
would not procede to find typecheck errors. This change does not poison
modules whose template have typecheck errors, so that ngtsc can emit
typecheck errors for templates with parse errors.

Additionally, all template diagnostics are produced in the same place.
This allows requesting just the template template diagnostics or just
other types of errors.

PR Close #40026
2020-12-15 13:30:52 -08:00
Alex Rickabaugh 973bb403a5 fix(compiler-cli): remove classes in .d.ts files from provider checks (#40118)
This commit temporarily excludes classes declared in .d.ts files from checks
regarding whether providers are actually injectable.

Such classes used to be ignored (on accident) because the
`TypeScriptReflectionHost.getConstructorParameters()` method did not return
constructor parameters from d.ts files, mostly as an oversight. This was
recently fixed, but caused more providers to be exposed to this check, which
created a breakage in g3.

This commit temporarily fixes the breakage by continuing to exclude such
providers from the check, until g3 can be patched.

PR Close #40118
2020-12-14 16:14:25 -08:00
Alex Rickabaugh c55bf4a4a3 refactor(compiler-cli): identify structural directives (#40032)
This commit introduces an `isStructural` flag on directive metadata, which
is `true` if the directive injects `TemplateRef` (and thus is at least
theoretically usable as a structural directive). The flag is not used for
anything currently, but will be utilized by the Language Service to offer
better autocompletion results for structural directives.

PR Close #40032
2020-12-14 12:08:41 -08:00
Alex Rickabaugh c0ab43f3c8 refactor(compiler-cli): introduce APIs to support directive autocompletion (#40032)
This commit adds two new APIs to the `TemplateTypeChecker`:
`getPotentialDomBindings` and `getDirectiveMetadata`. Together, these will
support the Language Service in performing autocompletion of directive
inputs/outputs.

PR Close #40032
2020-12-14 12:08:41 -08:00
Alex Rickabaugh a543e69497 refactor(compiler-cli): make TypeCheckingScopeRegistry a general utility (#40032)
The `annotations` package in the compiler previously contained a registry
which tracks NgModule scopes for template type-checking, including unifying
all type-checking metadata across class inheritance lines.

This commit generalizes this utility and prepares it for use in the
`TemplateTypeChecker` as well, to back APIs used by the language service.

PR Close #40032
2020-12-14 12:08:41 -08:00
Alex Rickabaugh e42250f139 feat(language-service): autocompletion of element tags (#40032)
This commit expands the autocompletion capabilities of the language service
to include element tag names. It presents both DOM elements from the Angular
DOM schema as well as any components (or directives with element selectors)
that are in scope within the template as options for completion.

PR Close #40032
2020-12-14 12:08:40 -08:00