This commit adds bazel rules to test whether linking the golden partial
files for test cases produces the same output as a full compile of the
test case would.
PR Close#39617
This commit contains the basic runner logic and a couple of sample test cases
for the "full compile" compliance tests, where source files are compiled
to full definitions and checked against expectations.
PR Close#39617
This commit renames the original `compliance` test directory to `compliance_old`.
Eventually this directory will be deleted once all the tests have been
migrated to the new test case based compliance tests.
PR Close#39617
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
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
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
The resource loader uses TypeScript's module resolution system to
determine at which locations it needs to look for a resource file. A
marker string is used to force the module resolution to fail, such that
all failed lookup locations can then be considered for actual resource
resolution. Any filesystem requests targeting files/directories that
contain the marker are known not to exist, so no filesystem request
needs to be done at all.
PR Close#39604
The type alias allows for this pattern to be more easily used in other
areas of the compiler code. The current usages of this pattern have been
updated to use the type alias.
PR Close#39604
When a `ViewContainerRef` is injected, we dynamically create a comment node next to the host
so that it can be used as an anchor point for inserting views. The comment node is inserted
through the `appendChild` helper from `node_manipulation.ts` in most cases.
The problem with using `appendChild` here is that it has some extra logic which doesn't return
a parent `RNode` if an element is at the root of a component. I __think__ that this is a performance
optimization which is used to avoid inserting an element in one place in the DOM and then
moving it a bit later when it is projected. This can break down in some cases when creating
a `ViewContainerRef` for a non-component node at the root of another component like the following:
```
<root>
<div #viewContainerRef></div>
</root>
```
In this case the `#viewContainerRef` node is at the root of a component so we intentionally don't
insert it, but since its anchor element was created manually, it'll never be projected. This will
prevent any views added through the `ViewContainerRef` from being inserted into the DOM.
These changes resolve the issue by not going through `appendChild` at all when creating a comment
node for `ViewContainerRef`. This should work identically since `appendChild` doesn't really do
anything with the T structures anyway, it only uses them to reach the relevant DOM nodes.
Fixes#39556.
PR Close#39599
Currently when an instance of the `FormControlName` directive is destroyed, the Forms package invokes
the `cleanUpControl` to clear all directive-specific logic (such as validators, onChange handlers,
etc) from a bound control. The logic of the `cleanUpControl` function should revert all setup
performed by the `setUpControl` function. However the `cleanUpControl` is too aggressive and removes
all callbacks related to the onChange and disabled state handling. This is causing problems when
a form control is bound to multiple FormControlName` directives, causing other instances of that
directive to stop working correctly when the first one is destroyed.
This commit updates the cleanup logic to only remove callbacks added while setting up a control
for a given directive instance.
The fix is needed to allow adding `cleanUpControl` function to other places where cleanup is needed
(missing this function calls in some other places causes memory leak issues).
PR Close#39623
* Fixes that the Ivy styling logic wasn't accounting for `!important` in the property value.
* Fixes that the default DOM renderer only sets `!important` on a property with a dash in its name.
* Accounts for the `flags` parameter of `setStyle` in the server renderer.
Fixes#35323.
PR Close#39603
Since WebStorm 2019.1, all of Angular Compiler validations has been implemented
as inspections, which has some additional benefits of being able to provide some
basic quick fixes like adding missing selector property, or something as neat as
auto-module import.
See https://intellij-support.jetbrains.com/hc/en-us/community/posts/360009914880
Signed-off-by: Adrien Crivelli <adrien.crivelli@gmail.com>
PR Close#39637
In #39470, the `deploy-to-firebase.sh` script (used to deploy AIO to
Firebase when building an upstream branch), was replaced by an
equivalent JS script. In this new `deploy-to-firebase.js` script, we
were overly aggressive with suppressing command output, which made it
hard to investigate failures ([example failing CI job][1]).
This commit updates the `deploy-to-firebase.js` script to capture
command output as usual in the CI job logs. This makes the output
similar to the one generated by the old [deploy-to-firebase.sh][2]
script ([example CI logs][3]).
One concern with capturing command output is having the value of a
secret environment variables leaked in the logs. This is not the case
here, since:
1. The secret env vars are not printed from the commands that use them.
2. CircleCI will [mask the values of secret env vars][4] in the output.
As an extra precaution (although not strictly necessary), we run `yarn`
with the `--silent` option, which avoid echoing the executed yarn
commands.
[1]: https://circleci.com/gh/angular/angular/849310
[2]: https://github.com/angular/angular/blob/3b0b7d22109c79b4dceb/aio/scripts/deploy-to-firebase.sh
[3]: https://circleci.com/gh/angular/angular/848109
[4]: https://circleci.com/docs/2.0/env-vars/#secrets-masking
PR Close#39596
The commit updates the AIO deployment script to also print the commit
SHA. This makes it easier to check whether a version has been
successfully deployed, by comparing the commit SHA from the CI job with
the SHA in the version string in the footer of the AIO app.
PR Close#39596
TCB generation occasionally transforms binding expressions twice, which can
result in a `BindingPipe` operation being `resolve()`'d multiple times. When
the pipe does not exist, this caused multiple OOB diagnostics to be recorded
about the missing pipe.
This commit fixes the problem by making the OOB recorder track which pipe
expressions have had diagnostics produced already, and only producing them
once per expression.
PR Close#39517
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
As with regular Angular components, Angular elements are expected to
have their views update when inputs change.
Previously, Angular Elements views were not updated if the underlying
component used the `OnPush` change detection strategy.
This commit fixes this by calling `markForCheck()` on the component
view's `ChangeDetectorRef`.
NOTE:
This is similar to how `@angular/upgrade` does it:
3236ae0ee1/packages/upgrade/src/common/src/downgrade_component_adapter.ts (L146).
Fixes#38948
PR Close#39452
Previously, the project used for running integration tests for Angular
Elements declared a component that used `ShadowDom` for view
encopsulation, but it did not include any tests to verify that the view
was updated correctly.
This commit adds the missing tests.
PR Close#39452
`ComponentNgElementStrategy` is supposed to call `ngOnChanges()` on the
underlying component instance if available, but not fail if the
component does not have an `ngOnChanges()` method. This works as
expected. However, the test used to verify that was invalid; i.e. the
test would pass even if `ComponentNgElementStrategy` would try to call
`ngOnChanges()` on a component without such a method.
This commit replaces the invalid test with a new one that correctly
verifies that `ComponentNgElementStrategy` does not try to call
`ngOnChanges()`.
PR Close#39452
Previously, the `componentRef` property of `FakeComponentFactory` used
in `elements` tests was initialy set to a spy object with all mock
properties defined as spied methods. Later, the properties where
overwritten to the actual mock values.
This commit simplifies the creation of `componentRef` by correctly using
the arguments of [jasmine.createSpyObj()][1] to specify the desired
shape of the spy object (separating spied properties from methods and
directly providing the mock values).
[1]: https://jasmine.github.io/api/3.5/jasmine.html#.createSpyObj
PR Close#39452
In ViewEngine, SelfSkip would navigate up the tree to get tokens from
the parent node, skipping the child. This restores that functionality in
Ivy. In ViewEngine, if a special token (e.g. ElementRef) was not found
in the NodeInjector tree, the ModuleInjector was also used to lookup
that token. While special tokens like ElementRef make sense only in a
context of a NodeInjector, we preserved ViewEngine logic for now to
avoid breaking changes.
We identified 4 scenarios related to @SkipSelf and special tokens where
ViewEngine behavior was incorrect and is likely due to bugs. In Ivy this
is implemented to provide a more intuitive API. The list of scenarios
can be found below.
1. When Injector is used in combination with @Host and @SkipSelf on the
first Component within a module and the injector is defined in the
module, ViewEngine will get the injector from the module. In Ivy, it
does not do this and throws instead.
2. When retrieving a @ViewContainerRef while @SkipSelf and @Host are
present, in ViewEngine, it throws an exception. In Ivy it returns the
host ViewContainerRef.
3. When retrieving a @ViewContainerRef on an embedded view and @SkipSelf
is present, in ViewEngine, the ref is null. In Ivy it returns the parent
ViewContainerRef.
4. When utilizing viewProviders and providers, a child component that is
nested within a parent component that has @SkipSelf on a viewProvider
value, if that provider is provided by the parent component's
viewProviders and providers, ViewEngine will return that parent's
viewProviders value, which violates how viewProviders' visibility should
work. In Ivy, it retrieves the value from providers, as it should.
These discrepancies all behave as they should in Ivy and are likely bugs
in ViewEngine.
PR Close#39464
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
Rather than re-reading component metadata that was already interpreted
by the Ivy compiler, the Language Service should instead use the
compiler APIs to get information it needs about the metadata.
PR Close#39476
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
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
The lexer is able to skip leading trivia in the `start` location of tokens.
This makes the source-span more friendly since things like elements
appear to begin at the start of the opening tag, rather than at the
start of any leading whitespace, which could include newlines.
But some tooling requires the full source-span to be available, such
as when tokenizing a text span into an Angular expression.
This commit simply adds the `fullStart` location to the `ParseSourceSpan`
class, and ensures that places where such spans are cloned, this
property flows through too.
PR Close#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
Close#38863
Monkey patches `queueMicrotask()` API, so the callback runs in the zone
when scheduled, and also the task is run as `microTask`.
```
Zone.current.fork({
name: 'queueMicrotask',
onScheduleTask: (delegate: ZoneDelegate, curr: Zone, target: Zone, task: Task) => {
logs.push(task.type);
logs.push(task.source);
return delegate.scheduleTask(target, task);
}
}).run(() => {
queueMicrotask(() => {
expect(logs).toEqual(['microTask', 'queueMicrotask']);
expect(Zone.current.name).toEqual('queueMicrotask');
done();
});
});
```
PR Close#38904