Commit Graph
414 Commits
Author SHA1 Message Date
Trotyl 8d613c1d42 feat(compiler): allow trailing comma in array literal (#22277)
Allows `[1, 2, ]` syntax in angular expressions.

closes #20773

PR Close #22277
2020-12-02 14:57:05 -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
Krzysztof Grzybek 94e790d4ee fix(compiler): report better error on interpolation in an expression (#30300)
Compiler results in weird error message when encounters interpolation inside
existing expression context, e.g. *ngIf="name {{ name }}"

PR Close #30300
2020-11-25 10:53:19 -08:00
Bjarki 358c50e226 feat(compiler): add schema for Trusted Types sinks (#39554)
Create a schema with an associated function to classify Trusted Types
sinks.

Piggyback a typo fix.

PR Close #39554
2020-11-23 08:29:04 -08:00
Marcono1234 3e1e5a15ba docs: update links to use HTTPS as protocol (#39718)
PR Close #39718
2020-11-20 12:52:16 -08:00
Pete Bacon Darwin 969ad329de refactor(compiler): tidy up interpolation splitting (#39717)
When parsing for i18n messages, interpolated strings are
split into `Text` and `Placeholder` pieces.  The method that
does this `_visitTextWithInterpolation()` was becoming too
complex. This commit refactors that method along with some
associated functions that it uses.

PR Close #39717
2020-11-20 08:35:56 -08:00
Alex Rickabaugh 3613e7c4e5 test(compiler-cli): move testing utils to separate package (#39594)
ngtsc has a robust suite of testing utilities, designed for in-memory
testing of a TypeScript compiler. Previously these utilities lived in the
`test` directory for the compiler-cli package.

This commit moves those utilities to an `ngtsc/testing` package, enabling
them to be depended on separately and opening the door for using them from
the upcoming language server testing infrastructure.

As part of this refactoring, the `fake_core` package (a lightweight API
replacement for @angular/core) is expanded to include functionality needed
for Language Service test use cases.

PR Close #39594
2020-11-17 11:59:56 -08:00
JoostK d281ea820b perf(compiler): use raw bytes to represent utf-8 encoded strings (#39694)
The result of utf-8 encoding a string was represented in a string, where
each individual character represented a single byte according to its
character code. All usages of this data were interested in the byte
itself, so this required conversion from a character back to its code.
This commit simply stores the individual bytes in array to avoid the
conversion. This yields a ~10% performance improvement for i18n message
ID computation.

PR Close #39694
2020-11-17 10:09:28 -08:00
JoostK 604b4e46c8 perf(compiler): optimize computation of i18n message ids (#39694)
Message ID computation makes extensive use of big integer
multiplications in order to translate the message's fingerprint into
a numerical representation. In large compilations with heavy use of i18n
this was showing up high in profiler sessions.

There are two factors contributing to the bottleneck:

1. a suboptimal big integer representation using strings, which requires
repeated allocation and conversion from a character to numeric digits
and back.
2. repeated computation of the necessary base-256 exponents and their
multiplication factors.

The first bottleneck is addressed using a representation that uses an
array of individual digits. This avoids repeated conversion and
allocation overhead is also greatly reduced, as adding two big integers
can now be done in-place with virtually no memory allocations.

The second point is addressed by a memoized exponentiation pool to
optimize the multiplication of a base-256 exponent.

As an additional optimization are the two 32-bit words now converted to
decimal per word, instead of going through an intermediate byte buffer
and doing the decimal conversion per byte.

The results of these optimizations depend a lot on the number of i18n
messages for which a message should be computed. Benchmarks have shown
that computing message IDs is now ~6x faster for 1,000 messages, ~14x
faster for 10,000 messages, and ~24x faster for 100,000 messages.

PR Close #39694
2020-11-17 10:09:28 -08:00
Andrew Scott 8a1c98c5e8 refactor(compiler-cli): add keySpan to reference nodes (#39616)
Similar to #39613, #39609, and #38898, we should store the `keySpan` for
Reference nodes so that we can accurately map from a template node to a
span in the original file. This is most notably an issue at the moment
for directive references `#ref="exportAs"`. The current behavior for the
language service when requesting information for the reference
is that it will return a text span that results in
highlighting the entire source when it should only highlight "ref" (test
added for this case as well).

PR Close #39616
2020-11-12 15:12:53 -08:00
Andrew Scott c33326c538 refactor(compiler-cli): add keySpan to parsed events (#39609)
Though we currently have the knowledge of where the `key` for an
event binding appears during parsing, we do not propagate this
information to the output AST. This means that once we produce the
template AST, we have no way of mapping a template position to the key
span alone. The best we can currently do is map back to the
`sourceSpan`. This presents problems downstream, specifically for the
language service, where we cannot provide correct information about a
position in a template because the AST is not granular enough.

This is essentially identical to the change from #38898, but for event
bindings rather than input bindings.

PR Close #39609
2020-11-12 15:09:17 -08:00
Andrew Scott 21651d362d refactor(compiler-cli): add keySpan to text attributes (#39613)
Similar to #39609 and #38898, though we currently have the knowledge of where the key for an
attribute appears during parsing, we do not propagate this
information to the output AST. This means that once we produce the
template AST, we have no way of mapping a template position to the key
span alone. The best we can currently do is map back to the
sourceSpan. This presents problems downstream, specifically for the
language service, where we cannot provide correct information about a
position in a template because the AST is not granular enough.

PR Close #39613
2020-11-12 14:19:00 -08:00
Pete Bacon Darwin 1f956184c4 fix(compiler): skipping leading whitespace should not break placeholder source-spans (#39486)
Tokenized text node may have leading whitespace skipped from their
source-span. But the source-span is used to compute where there are
interpolated blocks, resulting in placeholder nodes whose source-spans
are offset by the amount of skipped characters.

This fix uses the `fullStart` location of text source-spans for computing
the source-span of placeholders, so that they are accurate.

Fixes #39195

PR Close #39486
2020-11-06 09:01:37 -08:00
Pete Bacon Darwin 43d8e9aad2 refactor(compiler): capture fullStart locations when tokenizing (#39486)
This commit ensures that when leading whitespace is skipped by
the tokenizer, the original start location (before skipping) is captured
in the `fullStart` property of the token's source-span.

PR Close #39486
2020-11-06 09:01:37 -08:00
Pete Bacon Darwin 3f4fe45277 fix(compiler): ensure that i18n message-parts have the correct source-span (#39486)
In an i18n message, two placeholders next to each other must have
an "empty" message-part to separate them. Previously, the source-span
for this message-part was pointing to the wrong original location.
This caused problems in the generated source-maps and lead to extracted
i18n messages from being rendered incorrectly.

PR Close #39486
2020-11-06 09:01:37 -08:00
Kristiyan Kostadinov cbc0907bfd fix(compiler): preserve this.$event and this.$any accesses in expressions (#39323)
Currently expressions `$event.foo()` and `this.$event.foo()`, as well as `$any(foo)` and
`this.$any(foo)`, are treated as the same expression by the compiler, because `this` is considered
the same implicit receiver as when the receiver is omitted. This introduces the following issues:

1. Any time something called `$any` is used, it'll be stripped away, leaving only the first parameter.
2. If something called `$event` is used anywhere in a template, it'll be preserved as `$event`,
rather than being rewritten to `ctx.$event`, causing the value to undefined at runtime. This
applies to listener, property and text bindings.

These changes resolve the first issue and part of the second one by preserving anything that
is accessed through `this`, even if it's one of the "special" ones like `$any` or `$event`.
Furthermore, these changes only expose the `$event` global variable inside event listeners,
whereas previously it was available everywhere.

Fixes #30278.

PR Close #39323
2020-10-30 10:49:15 -07:00
ayazhafiz e3365724f2 feat(compiler): recover expression parsing in more malformed pipe cases (#39437)
This commit handles the following cases:
- incomplete pipes in a pipe chain
- incomplete arguments in a pipe chain
- incomplete arguments provided to a pipe
- nested pipes

The idea is to unconditionally recover on the presence of a pipe, which
should be okay because expression parsing can be independently between
pipes.

PR Close #39437
2020-10-29 12:38:40 -07:00
ayazhafiz 3f00c6150b test(compiler): Demonstrate recoverable parsing of unterminated pipes (#39113)
There is no actionable change in this commit other than to pretty-print
EOF tokens. Actual parsing of unterminated pipes is already supported,
this just adds a test for it.

Part of #38596

PR Close #39113
2020-10-22 13:41:51 -07:00
ayazhafiz e44e10bb81 feat(compiler): support recovery of malformed property writes (#39103)
This feature is trivial to support since
89c5255b8c has landed.

PR Close #39103
2020-10-22 13:36:50 -07:00
crisbeto 7f689a291a fix(compiler): incorrectly encapsulating @import containing colons and semicolons (#38716)
At a high level, the current shadow DOM shim logic works by escaping the content of a CSS rule
(e.g. `div {color: red;}` becomes `div {%BLOCK%}`), using a regex to parse out things like the
selector and the rule body, and then re-adding the content after the selector has been modified.
The problem is that the regex has to be very broad in order capture all of the different use cases,
which can cause it to match strings suffixed with a semi-colon in some places where it shouldn't,
like this URL from Google Fonts `https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap`.
Most of the time this is fine, because the logic that escapes the rule content to `%BLOCK%` will
have converted it to something that won't be matched by the regex. However, it breaks down for rules
like `@import` which don't have a body, but can still have quoted content with characters that can
match the regex.

These changes resolve the issue by making a second pass over the escaped string and replacing all
of the remaining quoted content with `%QUOTED%` before parsing it with the regex. Once everything
has been processed, we make a final pass where we restore the quoted content.

In a previous iteration of this PR, I went with a shorter approach which narrowed down the
regex so that it doesn't capture rules without a body. It fixed the issue, but it also ended
up breaking some of the more contrived unit test cases. I decided not to pursue it further, because
we would've ended up with a very long and brittle regex that likely would've broken in even weirder
ways.

Fixes #38587.

PR Close #38716
2020-10-09 08:33:04 -07:00
Kristiyan Kostadinov 4a1c12c773 feat(core): remove ViewEncapsulation.Native (#38882)
Removes `ViewEncapsulation.Native` which has been deprecated for several major versions.

BREAKING CHANGES:
* `ViewEncapsulation.Native` has been removed. Use `ViewEncapsulation.ShadowDom` instead. Existing
usages will be updated automatically by `ng update`.

PR Close #38882
2020-10-08 11:56:03 -07:00
JoostK 4b06ef75aa refactor(compiler): associate accurate source spans with ICU expressions (#39072)
Prior to this change, expressions within ICUs would have a source span
corresponding with the whole ICU. This commit narrows down the source
spans of these expressions to the exact location in the source file, as
a prerequisite for reporting type check errors within these expressions.

PR Close #39072
2020-10-08 11:55:27 -07:00
ayazhafiz 57f8dd2978 test(compiler): add tests for parsing of malformed property reads (#38998)
The expression parser already has support for recovering on malformed
property reads, but did not have tests describing the recovered ast in
such cases. This commit adds tests to demonstrate such cases; in
particular, the recovered ast is a full PropertyRead but with an empty
property name. This is likely the most preferred option, as it does not
constrain consumers of the AST to what the property name should look
like. Furthermore, we cannot mark the property name as empty in any
other way (e.g. an EmptyExpr) because the property name, as of present,
is a string field rather than an AST itself.

Note that tokens past a malformed property read are not preserved in the
AST (for example in `foo.1234`, `1234` is not preserved in the AST).
This is because the extra tokens do not belong to the singular
expression created by the property read, and there is not a meaningful
way to interpret a secondary expression in a single parsed expression.

Part of #38596

PR Close #38998
2020-10-05 14:24:46 -07:00
ayazhafiz 89c5255b8c refactor(compiler): iteratively parse interpolations (#38977)
This patch refactors the interpolation parser to do so iteratively
rather than using a regex. Doing so prepares us for supporting granular
recovery on poorly-formed interpolations, for example when an
interpolation does not terminate (`{{ 1 + 2`) or is not terminated
properly (`{{ 1 + 2 {{ 2 + 3 }}`).

Part of #38596

PR Close #38977
2020-10-02 15:13:23 -07:00
ayazhafiz 3bbbf39b58 feat(compiler): Recover on malformed keyed reads and keyed writes (#39004)
This patch adds support for recovering well-formed (and near-complete)
ASTs for semantically malformed keyed reads and keyed writes. See the
added tests for details on the types of semantics we can now recover;
in particular, notice that some assumptions are made about the form of
a keyed read/write intended by a user. For example, in the malformed
expression `a[1 + = 2`, we assume that the user meant to write a binary
expression for the key of `a`, and assign that key the value `2`. In
particular, we now parse this as `a[1 + <empty expression>] = 2`. There
are some different interpretations that can be made here, but I think
this is reasonable.

The actual changes in the parser code are fairly minimal (a nice
surprise!); the biggest addition is a `writeContext` that marks whether
the `=` operator can serve as a recovery point after error detection.

Part of #38596

PR Close #39004
2020-10-02 11:37:03 -07:00
Keen Yee Liau 8b7acc4f8f refactor(compiler): Binding parser sets binding span as source span in Ivy (#39036)
Currently it is impossible to determine the source of a binding that
generates `BoundAttribute` because all bound attributes generated from a
microsyntax expression share the same source span.

For example, in
```html
<div *ngFor="let item of items; trackBy: trackByFn"></div>
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     source span for all `BoundAttribute`s generated from microsyntax
```
the `BoundAttribute` for both `ngForOf` and `ngForTrackBy`
share the same source span.

A lot of hacks were necessary in View Engine language service to work
around this limitation. It was done by inspecting the whole source span
then figuring out the relative position of the cursor.

With this change, we introduce a flag to set the binding span as the
source span of the `ParsedProperty` in Ivy AST.
This flag is needed so that we don't have to change VE ASTs.

Note that in the binding parser, we already set `bindingSpan` as the
source span for a `ParsedVariable`, and `keySpan` as the source span for
a literal attribute. This change makes the Ivy AST more consistent by
propagating the binding span to `ParsedProperty` as well.

PR Close #39036
2020-09-30 09:31:44 -04:00
Andrew Scott c74917a7d5 refactor(compiler-cli): update type checker symbols to include more information (#38844)
This commit updates the symbols in the TemplateTypeCheck API and methods
for retrieving them:

* Include `isComponent` and `selector` for directives so callers can determine which
attributes on an element map to the matched directives.
* Add a new `TextAttributeSymbol` and return this when requesting a symbol for a `TextAttribute`.
* When requesting a symbol for `PropertyWrite` and `MethodCall`, use the
`nameSpan` to retrieve symbols.
* Add fix to retrieve generic directives attached to elements/templates.

PR Close #38844
2020-09-28 16:19:44 -04:00
Keen Yee Liau 239968d2f1 feat(compiler): Add keySpan to Variable Node (#38965)
Now that we have `keySpan` for `BoundAttribute` (implemented in
https://github.com/angular/angular/pull/38898) we could do the same
for `Variable`.

This would allow us to distinguish the LHS and RHS from the whole source
span.

PR Close #38965
2020-09-25 14:32:46 -04:00
JoostK b627f7f02e test(compiler-cli): improve test performance using shared source file cache (#38909)
Some compiler tests take a long time to run, even using multiple
executors. A profiling session revealed that most time is spent in
parsing source files, especially the default libraries are expensive to
parse.

The default library files are constant across all tests, so this commit
introduces a shared cache of parsed source files of the default
libraries. This achieves a significant improvement for several targets
on my machine:

//packages/compiler-cli/test/compliance: from 23s to 5s.
//packages/compiler-cli/test/ngtsc: from 115s to 11s.

Note that the number of shards for the compliance tests has been halved,
as the extra shards no longer provide any speedup.

PR Close #38909
2020-09-25 14:28:49 -04:00
Andrew Scott ba3f4c26bb refactor(compiler): make keySpan available for BoundAttributes (#38898)
Though we currently have the knowledge of where the `key` for an
attribute binding appears during parsing, we do not propagate this
information to the output AST. This means that once we produce the
template AST, we have no way of mapping a template position to the key
span alone. The best we can currently do is map back to the
`sourceSpan`. This presents problems downstream, specifically for the
language service, where we cannot provide correct information about a
position in a template because the AST is not granular enough.

PR Close #38898
2020-09-22 15:04:30 -07:00