When requesting a queries instance for a node, it was previously
decided whether it needs to be cloned if the node was not already marked
as hosting a query. This check is in place to have only a single queries
instance per node.
The issue with this approach is that no clone is created for subsequent
instantiations of a component, as the TNode is already marked as hosting
a query during first template pass, whereas the cloning of queries
should be independent of first template pass.
To overcome this issue, the queries are assigned an owner TNode such
that it can reliably be determined if a clone needs to be created.
PR Close#27892
This update fixes the way the @internal and @nocollapse annotations are used together, which produced errors while running it with Closure compiler. Now two annotations are a part of the same comment block.
PR Close#28138
* This is a follow-up to cd0451305a which fixes that "ngc-wrapped" from the "npm" workspace is always used if "angular" is fetched as an external dependency.
PR Close#28137
Prior to this change we performed prop and attr name validation at compile time, which failed in case a given prop/attr is an input to a Directive (thus should not be a subject to this check). Since Directive matching in Ivy happens at runtime, the corresponding checks are now moved to runtime as well.
PR Close#28054
With the update to TypeScript 3.2.x, a big issue seems to have appeared for downstream Bazel users. If the downstream user still uses a lower TypeScript version, normal Bazel targets using the `ng_module` rule are still compiled with the correct/old TypeScript version (assuming they set the `node_modules` attribute properly).
But, if they build the previous Bazel targets by specifying them within a `ng_package` rule, the TypeScript version from the Angular `workspace` is being used for the replayed ESM5 compilation. This is because we resolve the replay compiler to `ngc_wrapped` or `tsc_wrapped` Bazel executables which are defined as part of the `angular` workspace. This means that the compilers are different if the downstream user uses `ngc-wrapped` from the `@npm` repository because the replayed compilation would use the compiler with `@ngdeps//typescript`.
In order to fix this, we should just use the compiler that is defined in the `@angular//BUILD.bazel` file. This target by defaults to the "@npm" workspace which is working for downstream users. This is similar to how it is handled for `tsc-wrapped`. `tsc-wrapped` works as expected for downstream users.
**Note**: This is not the ideal solution because ideally we would
completely respect the `compiler` option from the base `ng_module`, but
this is not possible in a hermetic way, unless we somehow accept the
`compiler` as an attribute that builds all transitive deps. This is
something we should explore in the future. For now, we just fix this in
a reasonable way that is also used for `tsc_wrapped` from the TypeScript
rules.
PR Close#28053
index.html needs to have the zone.js and the project bundle injected
using script tags. This used to be done explicitly by specifying a
new index.html but with `web_package` rule introduced in rules_nodejs,
it is now possible to perform the injection dynamically.
PR Close#27995
This change is a prerequasity for a later change which will turn the
'di' into its own bazel package. In order to do that we have to:
- have `Injector` type be importable by Ivy. This means that we need
to create `Injector` as a pure type in `interface` folder which is
already a bazel package which Ivy can depend on.
- Remove the dependency of `class Injector` on Ivy so that it can be
compiled in isolation. We do that by using `-1` as special value for
`__NG_ELEMENT_ID__` which tells the Ivy `NodeInjector` than
`Injector` is being requested.
PR Close#28066
Incremental rebuilds is a fundamental part of the development
workflow. `@bazel/ibazel` should be added to the dev dependencies
of a Bazel project.
PR Close#28090
This update aligns Ivy behavior with ViewEngine related to empty bindings (for example <div [someProp]></div>): empty bindings are ignored.
PR Close#28059
__NG_ELEMENT_ID__ static fields are a part of how the Ivy node injector
works. In order to survive closure minification correctly, they need to
be annotated with @nocollapse.
PR Close#28050
ngtsc has a hack to add @nocollapse jsdoc annotations to generated static
fields. This hack is currently broken (likely due to a TypeScript change
in the way writeFile() works).
This commit fixes the hack and introduces an ngtsc_spec test to ensure it
does not regress again.
PR Close#28050
When an @NgModule decorator executes, the module is added to a queue in
render3/jit/module.ts. Reading an ngComponentDef property causes this queue
to be flushed, ensuring that the component gets the correct module scope
applied.
In before_each.ts, a global beforeEach is added to all Angular tests which
calls TestBed.resetTestingModule() prior to running each test. This in turn
clears the module compilation queue (which is correct behavior, as modules
declared within the test should not leak outside of it via the queue).
So far this is okay. But before the first test runs, the module compilation
queue is full of modules declared in global scope. No definitions have been
read, so no flushes of the queue have been triggered. The global beforeEach
triggers a reset of the queue, aborting all of the in-progress global
compilation, breaking those classes when they're later used in tests.
This commit adds logic to TestBedRender3 to respect the state of the module
queue before the TestBed is first initialized or reset. The queue is flushed
prior to such an operation to ensure global compilation is allowed to finish
properly.
With this fix, a platform-server test now passes (previously the <my-child>
element was not detected as a component, because the encompassing module
never finished compilation.
FW-887 #resolve
PR Close#28033
Previously when testing code injected the Compiler, it received the
top-level Compiler implementation defined in linker/compiler.ts
(and governed by the __PRE_R3__ switch). Code running under the
TestBed, however, should always use a TestBed-aware Compiler
implementation.
This commit adds such an implementation to the TestBedRender3,
which passes compiled modules through the _compileNgModule()
function.
With this change, 3 formerly disabled router integration tests
now pass.
FW-855 #resolve
PR Close#28033
An @NgModule with invalid provider declarations produces errors under
normal circumstances. However, within the TestBed two small issues with
provider overrides interfered with the correct production of these errors:
1. a 'null' provider object caused a premature crash when the TestBed
attempted to check for a 'provide' property on it with hasOwnProperty().
2. the array of providers would have an empty override array appended to it
for each input provider, which would pollute the error messages produced
down the line.
This commit fixes both of these issues, by 1) checking for null and 2)
filtering out the empty override arrays.
Testing strategy: future commits change the way the TestBed compiles
modules, causing tests to become sensitive to this bug if not fixed.
PR Close#28033
An @NgModule with an 'id' property has its type registered in a global map
of modules by id. This happens during compilation of the module.
In Ivy, modules are first compiled when the @NgModule decorator executes.
In tests, they might be passed again through the TestBed's compiler,
resulting in a second compilation and registration.
Before this fix, this second registration would cause an error, as the id
was previously registered. This commit makes the registration idempotent,
so if the same module type is being registered for the same id then no
error is thrown.
Testing strategy: future commits change the way the TestBed compiles
modules, causing tests to become sensitive to this bug if not fixed.
PR Close#28033
In ESM5 decorated classes can be indicated by calls to `__decorate()`.
Previously the `ReflectionHost.findDecoratedClasses()` call would identify
helper calls of the form:
```
SomeClass = tslib_1.__decorate(...);
```
But it was missing calls of the form:
```
SomeClass = SomeClass_1 = tslib_1.__decorate(...);
```
This form is common in `@NgModule()` decorations, where the class
being decorated is referenced inside the decorator or another
member.
This commit now ensures that a chain of assignments, of any length,
is now identified as a class decoration if it results in a call to
`__decorate()`.
Fixes#27841
PR Close#27848
* Interface that a class can implement to be a guard deciding if a children can be loaded.
'...if a children...' changed to '...if children...'
* Interface that a class can implement to be a guard deciding if children can be loaded.
PR Close#27894
Previously, we had the logic to schedule a change detection tick
inside markViewDirty(). This is fine when used in markDirty(),
the user-facing API, because it should always schedule change
detection. However, this doesn't work when used in markForCheck()
because historically markForCheck() does not trigger change
detection.
To be backwards compatible, this commit moves the scheduling
logic out of markViewDirty() and into markDirty(), so
markForCheck no longer triggers a tick.
PR Close#28048
Libraries that create components dynamically using component factories,
such as `@angular/upgrade` need to pass blocks of projected content
through to the `ComponentFactory.create()` method. These blocks
are extracted from the content by matching CSS selectors defined in
`<ng-content select="..">` tags found in the component's template.
The Angular compiler collects these CSS selectors when compiling a component's
template, and exposes them via the `ComponentFactory.ngContentSelectors`
property.
This change ensures that this property is filled correctly when the
component factory is created by compiling a component with the Ivy engine.
PR Close#27867
When a pipe returns an instance of WrappedValue we should "invalidate" value
of a binding where the pipe in question is used.
Before this change we've always wrtten the invalidation value (NO_CHANGE) to
the binding root this invalidating the first binding in a LView. This commit
corrects the binding index calculation so the binding with a pipe is invalidated.
PR Close#28044
Previous to this change, there was a lot of noise when
trying to find tests in FIND_PASSING_TESTS mode because
tests marked "onlyInIvy" were also listed as "already
passing". Since these tests are not "fixmes" that need
to be enabled, it is not useful to have them listed.
This commit removes "onlyInIvy" tests from consideration
when running in this manual mode. The tests should still
run on CI by default (since FIND_PASSING_TESTS mode will
be false).
PR Close#28036
There are various e2e tests with the `_spec.ts` suffix in the Angular project. Currently the protractor Bazel rule does not pick up these files and just ignores them. Since underscore is commonly used, we should support this.
Needed for the conversion fo the `examples` to Bazel.
PR Close#28022
Prior to this change Component decorator was resolving `encapsulation` value a bit incorrectly, which resulted in `encapsulation: NaN` in compiled code. Now we resolve the value as Enum memeber and throw if it's not the case. As a part of this update, the `changeDetection` field handling is also added, the resolution logic is the same as the one used for `encapsulation` field.
PR Close#27971
exportAs in @Directive metadata supports multiple values, separated by
commas. Previously it was treated as a single value string.
This commit modifies the compiler to understand that exportAs is a
string[]. It stops short of carrying the multiple values through to the
runtime. Instead, it only emits the first one. A future commit will modify
the runtime to accept all the values.
PR Close#28001
Generated factory shims can import from @angular/core. However, we have
special logic in place to rewrite self-imports when generating code for
@angular/core.
This commit leverages the new standalone ImportRewriter interface to
properly rewrite imports in generated factory shims. Before this fix,
a generated factory file for core would look like:
```typescript
import * as i0 from './r3_symbols';
export var ApplicationModuleNgFactory = new ɵNgModuleFactory(...);
```
This is invalid, as ɵNgModuleFactory is just NgModuleFactory when imported
via r3_symbols.
FW-881 #resolve
PR Close#27998
Currently the ImportManager class handles various rewriting actions of
imports when compiling @angular/core. This is required as code compiled
within @angular/core cannot import from '@angular/core'. To work around
this, imports are rewritten to get core symbols from a particular file,
r3_symbols.ts.
In this refactoring, this rewriting logic is moved out of the ImportManager
and put behind an interface, ImportRewriter. There are three implementers
of the interface:
* NoopImportRewriter, used for compiling all non-core packages.
* R3SymbolsImportRewriter, used when ngtsc compiles @angular/core.
* NgccFlatImportRewriter, used when ngcc compiles @angular/core (special
logic is needed because ngcc has to rewrite imports in flat bundles
differently than in non-flat bundles).
This is a precursor to using this rewriting logic in other contexts besides
the ImportManager.
PR Close#27998
Project created by @angular/cli depends on Bazel at build time and
we should not assume that Bazel is available globally.
Instead, the project should specify an explicit dev dependency on
`@bazel/bazel`.
PR Close#28032
TestBed used to have its own implementation of the `transitiveScopesFor` function, customized for TestBed needs (to compile NgModules). This change unifies the `transitiveScopesFor` function usage by importing it from the `jit/module.ts` script and adding extra argument to configure its behavior (how to compile NgModule), so that TestBed can leverage it.
PR Close#27860
These tests validate the ability of the View Engine TestBed to consume
summary metadata, a mechanism which allows the TestBed to use
AOT-compiled components & directives in tests. It achieves this through
two operations which are independently obsolete in Ivy:
1. It injects CompileMetadataResolver, a View Engine specific compiler
internal class which extracts global analysis metadata from classes,
and uses it to construct summary metadata. This happens in a
beforeEach() block which calls createSummaries().
2. It uses TestBed.initTestEnvironment to pass summary metadata to the
TestBed itself. Any such metadata is ignored in Ivy.
Operation #1 makes it impossible to run these tests under Ivy, as the
CompileMetadataResolver is not available with an Ivy compiler.
Ivy itself does not rely on summary data, and the R3TestBed can depend
directly on AOT compiled components without it. Thus, the spirit of thes
tests is obsolete in an Ivy world.
FW-838 #resolve
PR Close#28027
Previously the canInsertNativeNode and getRenderParent functions had almost
_exaclty_ the same logic. What was worse that getRenderParent was calling
canInsertNativeNode thus executing the same, non-trivial logic twice.
This commit merges canInsertNativeNode and getRenderParent into one function.
Now getRenderParent will return a native parent or null if a node can't be
inserted (content projection, root of a view that is not inserted etc.).
PR Close#28011
Previously presence and type of a parent tNode was split among
canInsertNativeNode, canInsertNativeChildOfView and canInsertNativeChildOfElement.
This commit centralises the logic in canInsertNativeNode thus simplifying
the overall logic and making canInsertNativeChildOfElement trivial.
PR Close#28011
Instead of relying on implicit dependencies through Angular, the WORKSPACE
of the project should explicitly add rules_nodejs and rules_typescript so
it can better control the versions.
PR Close#28000
A constructor function may have been "synthesized" by TypeScript during
JavaScript emit, in the case no user-defined constructor exists and e.g.
property initializers are used. Those initializers need to be emitted
into a constructor in JavaScript, so the TypeScript compiler generates a
synthetic constructor.
This commit adds identification of such constructors as ngcc needs to be
able to tell if a class did originally have a constructor in the
TypeScript source. When a class has a superclass, a synthesized
constructor must not be considered as a user-defined constructor as that
prevents a base factory call from being created by ngtsc, resulting in a
factory function that does not inject the dependencies of the superclass.
Hence, we identify a default synthesized super call in the constructor
body, according to the structure that TypeScript emits.
PR Close#27897
* Fixes that the flat module out files do not have a proper AMD module name on Windows. This is currently blocking serving a `ng_module` using the Bazel TypeScript `devserver` on Windows.
PR Close#27839
The problem that `fixmeIvy`s refer to is resolved, but the tests are still broken due to other issue (not possible to retrieve host property bindings for DebugElement).
PR Close#28003
This commit adds sanitization for `elementProperty` and `elementAttribute` instructions used in `hostBindings` function, similar to what we already have in the `template` function. Main difference is the fact that for some attributes (like "href" and "src") we can't define which SecurityContext they belong to (URL vs RESOURCE_URL) in Compiler, since information in Directive selector may not be enough to calculate it. In order to resolve the problem, Compiler injects slightly different sanitization function which detects proper Security Context at runtime.
PR Close#27939
Previously, ngtsc would assume that a given directive/pipe being imported
from an external package was importable using the same name by which it
was declared. This isn't always true; sometimes a package will export a
directive under a different name. For example, Angular frequently prefixes
directive names with the 'ɵ' character to indicate that they're part of
the package's private API, and not for public consumption.
This commit introduces the TsReferenceResolver class which, given a
declaration to import and a module name to import it from, can determine
the exported name of the declared class within the module. This allows
ngtsc to pick the correct name by which to import the class instead of
making assumptions about how it was exported.
This resolver is used to select a correct symbol name when creating an
AbsoluteReference.
FW-517 #resolve
FW-536 #resolve
PR Close#27743
This commit adds tracking of modules, directives, and pipes which are made
visible to consumers through NgModules exported from the package entrypoint.
ngtsc will now produce a diagnostic if such classes are not themselves
exported via the entrypoint (as this is a requirement for downstream
consumers to use them with Ivy).
To accomplish this, a graph of references is created and populated via the
ReferencesRegistry. Symbols exported via the package entrypoint are compared
against the graph to determine if any publicly visible symbols are not
properly exported. Diagnostics are produced for each one which also show the
path by which they become visible.
This commit also introduces a diagnostic (instead of a hard compiler crash)
if an entrypoint file cannot be correctly determined.
PR Close#27743
@angular/forms declares several directives and a module which are not
exported from the package via the entrypoint, either intentionally or as a
historical accident.
Ivy's locality principle necessitates that directives used in user code be
importable from the package which defines them. This requires these forms
directives to be exported.
Several directives which define ControlValueAccessors are exported:
* NumberValueAccessor
* RangeValueAccessor
A few more directives and a module are exported privately (with a ɵ prefix):
* NgNoValidate
* NgSelectMultipleOption
* InternalFormsSharedModule
PR Close#27743
Upcoming work to implement import resolution will change the dependencies
of some higher-level classes in ngtsc & ngcc. This necessitates changes in
how these classes are created and the lifecycle of the ts.Program in ngtsc
& ngcc.
To avoid complicating the implementation work with refactoring as a result
of the new dependencies, the refactoring is performed in this commit as a
separate prepatory step.
In ngtsc, the testing harness is modified to allow easier access to some
aspects of the ts.Program.
In ngcc, the main change is that the DecorationAnalyzer is created with the
ts.Program as a constructor parameter. This is not a lifecycle change, as
it was previously created with the ts.TypeChecker which is derived from the
ts.Program anyways. This change requires some reorganization in ngcc to
accommodate, especially in testing harnesses where DecorationAnalyzer is
created manually in a number of specs.
PR Close#27743
This refactoring moves code around between a few of the ngtsc subpackages,
with the goal of having a more logical package structure. Additional
interfaces are also introduced where they make sense.
The 'metadata' package formerly contained both the partial evaluator,
the TypeScriptReflectionHost as well as some other reflection functions,
and the Reference interface and various implementations. This package
was split into 3 parts.
The partial evaluator now has its own package 'partial_evaluator', and
exists behind an interface PartialEvaluator instead of a top-level
function. In the future this will be useful for reducing churn as the
partial evaluator becomes more complicated.
The TypeScriptReflectionHost and other miscellaneous functions have moved
into a new 'reflection' package. The former 'host' package which contained
the ReflectionHost interface and associated types was also merged into this
new 'reflection' package.
Finally, the Reference APIs were moved to the 'imports' package, which will
consolidate all import-related logic in ngtsc.
PR Close#27743
This commit moves the FlatIndexGenerator to its own package, in preparation
to expand its capabilities and support re-exporting of private declarations
from NgModules.
PR Close#27743
Previously the appendChild / removeChild could take null as an argument for
a child to be added / removed. This is difficult to understand since the
mentioned methods are noop if a child is null.
This commit clarifies the appendChild / removeChild signature to systematically
require a child node to be added removed. It turns out that null could be passed
only for a very specific i18n cases so now we guard a call to removeChild with
an explicit check on the i18n side.
PR Close#27987
This update introduces support for global object (window, document, body) listeners, that can be defined via host listeners on Components and Directives.
PR Close#27772
`i18nAttributes` was throwing an error when it was called multiple times in the create part of the template function with the same index, for example when we create multiple components with the same template. It shouldn't throw in this case, and just use the cache when available.
FW-903 #resolve
PR Close#27911
test.sh is no longer needed... all the tests should now be executed via bazel.
if for whatever reason we need to run the legacy unit test setup, we should should follow the commands that we use to execute those tests in .circle/config.yaml
PR Close#27937
Moving the tests over to CircleCI in pretty much "as-is" state just so that we can drop the dependency on Travis.
In the followup changes we plan to migrate these tests to run on sauce under bazel. @gregmagolan is working on that.
I've previously verified that all the tests executed in legacy-unit-tests-local already under bazel.
Therefore the legacy-unit-tests-local job is strictly not necessary any more, but given how flaky legacy-unit-tests-saucelabs is,
it is good to have the -local job just so that we can quickly determine if any failure is a flake or legit issue
(the bazel version of these tests could theoretically run in a slightly different way and fail or not fail in a different way, so having -lcoal job is just an extra safety check).
This change was coauthored with @devversion
PR Close#27937
Fixes Ivy's `QueryList` not being an instance of the exported ViewEnginer `QueryList`.
Also reworks `first`, `last` and `length` to be regular properties, rather than setters. Reworking `length` was required to be able to extend the ViewEngine `QueryList`, but I reworked `first` and `last` as well since getters generate a lot more code when transpiled to ES5.
These changes fix FW-706.
PR Close#27942
* Currently the protractor utils assume that the specified Bazel server runfile can be resolved by just using the real file system. This is not the case on Windows because the runfiles are not symlinked into the working directory and need to be resolved through the runfile manifest.
PR Close#27915