2020-05-06 10:54:44 -04:00
|
|
|
load("@npm//@babel/cli:index.bzl", "babel")
|
2018-09-11 21:11:32 -04:00
|
|
|
load("//tools:defaults.bzl", "jasmine_node_test", "ts_library")
|
2018-07-16 03:49:56 -04:00
|
|
|
|
2019-01-16 04:19:01 -05:00
|
|
|
package(default_visibility = ["//visibility:public"])
|
|
|
|
|
2018-07-16 03:49:56 -04:00
|
|
|
ts_library(
|
|
|
|
name = "test_lib",
|
2018-10-16 02:24:22 -04:00
|
|
|
testonly = True,
|
2019-03-20 09:47:58 -04:00
|
|
|
srcs = glob(
|
|
|
|
["**/*.ts"],
|
|
|
|
exclude = ["integration/**/*.ts"],
|
|
|
|
),
|
2018-07-16 03:49:56 -04:00
|
|
|
deps = [
|
2019-11-04 12:29:01 -05:00
|
|
|
"//packages/compiler",
|
2020-06-04 03:43:05 -04:00
|
|
|
"//packages/compiler-cli",
|
2019-03-20 09:47:58 -04:00
|
|
|
"//packages/compiler-cli/ngcc",
|
2019-04-06 10:35:13 -04:00
|
|
|
"//packages/compiler-cli/ngcc/test/helpers",
|
2019-07-18 16:05:32 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/diagnostics",
|
2019-06-06 15:22:32 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/file_system",
|
|
|
|
"//packages/compiler-cli/src/ngtsc/file_system/testing",
|
2018-12-18 12:48:15 -05:00
|
|
|
"//packages/compiler-cli/src/ngtsc/imports",
|
perf(compiler-cli): detect semantic changes and their effect on an incremental rebuild (#40947)
In Angular programs, changing a file may require other files to be
emitted as well due to implicit NgModule dependencies. For example, if
the selector of a directive is changed then all components that have
that directive in their compilation scope need to be recompiled, as the
change of selector may affect the directive matching results.
Until now, the compiler solved this problem using a single dependency
graph. The implicit NgModule dependencies were represented in this
graph, such that a changed file would correctly also cause other files
to be re-emitted. This approach is limited in a few ways:
1. The file dependency graph is used to determine whether it is safe to
reuse the analysis data of an Angular decorated class. This analysis
data is invariant to unrelated changes to the NgModule scope, but
because the single dependency graph also tracked the implicit
NgModule dependencies the compiler had to consider analysis data as
stale far more often than necessary.
2. It is typical for a change to e.g. a directive to not affect its
public API—its selector, inputs, outputs, or exportAs clause—in which
case there is no need to re-emit all declarations in scope, as their
compilation output wouldn't have changed.
This commit implements a mechanism by which the compiler is able to
determine the impact of a change by comparing it to the prior
compilation. To achieve this, a new graph is maintained that tracks all
public API information of all Angular decorated symbols. During an
incremental compilation this information is compared to the information
that was captured in the most recently succeeded compilation. This
determines the exact impact of the changes to the public API, which
is then used to determine which files need to be re-emitted.
Note that the file dependency graph remains, as it is still used to
track the dependencies of analysis data. This graph does no longer track
the implicit NgModule dependencies, which allows for better reuse of
analysis data.
These changes also fix a bug where template type-checking would fail to
incorporate changes made to a transitive base class of a
directive/component. This used to be a problem because transitive base
classes were not recorded as a transitive dependency in the file
dependency graph, such that prior type-check blocks would erroneously
be reused.
This commit also fixes an incorrectness where a change to a declaration
in NgModule `A` would not cause the declarations in NgModules that
import from NgModule `A` to be re-emitted. This was intentionally
incorrect as otherwise the performance of incremental rebuilds would
have been far worse. This is no longer a concern, as the compiler is now
able to only re-emit when actually necessary.
Fixes #34867
Fixes #40635
Closes #40728
PR Close #40947
2020-11-20 15:18:46 -05:00
|
|
|
"//packages/compiler-cli/src/ngtsc/incremental/semantic_graph",
|
2020-05-14 15:06:12 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/logging/testing",
|
2018-12-18 12:48:15 -05:00
|
|
|
"//packages/compiler-cli/src/ngtsc/partial_evaluator",
|
|
|
|
"//packages/compiler-cli/src/ngtsc/reflection",
|
2021-02-04 17:35:14 -05:00
|
|
|
"//packages/compiler-cli/src/ngtsc/sourcemaps",
|
2018-07-16 03:49:56 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/testing",
|
2018-07-16 03:55:04 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/transform",
|
2019-04-28 15:48:33 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/translator",
|
2019-02-20 12:54:42 -05:00
|
|
|
"@npm//@types/convert-source-map",
|
2019-06-06 15:22:32 -04:00
|
|
|
"@npm//convert-source-map",
|
2019-08-28 08:01:39 -04:00
|
|
|
"@npm//dependency-graph",
|
2019-02-20 12:54:42 -05:00
|
|
|
"@npm//magic-string",
|
2020-02-16 15:07:30 -05:00
|
|
|
"@npm//sourcemap-codec",
|
2019-02-20 12:54:42 -05:00
|
|
|
"@npm//typescript",
|
2020-04-15 11:35:09 -04:00
|
|
|
"@npm//yargs",
|
2018-07-16 03:49:56 -04:00
|
|
|
],
|
|
|
|
)
|
|
|
|
|
|
|
|
jasmine_node_test(
|
|
|
|
name = "test",
|
2020-01-08 02:56:49 -05:00
|
|
|
bootstrap = ["//tools/testing:node_no_angular_es5"],
|
2019-06-06 15:22:32 -04:00
|
|
|
data = [
|
2020-11-04 15:27:19 -05:00
|
|
|
"//packages/compiler-cli/src/ngtsc/testing/fake_core:npm_package",
|
2019-06-06 15:22:32 -04:00
|
|
|
],
|
2018-07-16 03:49:56 -04:00
|
|
|
deps = [
|
|
|
|
":test_lib",
|
|
|
|
],
|
|
|
|
)
|
2019-03-20 09:47:58 -04:00
|
|
|
|
|
|
|
ts_library(
|
|
|
|
name = "integration_lib",
|
|
|
|
testonly = True,
|
|
|
|
srcs = glob(
|
|
|
|
["integration/**/*.ts"],
|
|
|
|
),
|
|
|
|
deps = [
|
|
|
|
"//packages/compiler-cli/ngcc",
|
2019-04-06 10:35:13 -04:00
|
|
|
"//packages/compiler-cli/ngcc/test/helpers",
|
2019-06-06 15:22:32 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/file_system",
|
|
|
|
"//packages/compiler-cli/src/ngtsc/file_system/testing",
|
2020-05-14 15:06:12 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/logging/testing",
|
2019-06-06 15:22:32 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/testing",
|
2019-03-20 09:47:58 -04:00
|
|
|
"@npm//rxjs",
|
feat(ngcc): add a migration for undecorated child classes (#33362)
In Angular View Engine, there are two kinds of decorator inheritance:
1) both the parent and child classes have decorators
This case is supported by InheritDefinitionFeature, which merges some fields
of the definitions (such as the inputs or queries).
2) only the parent class has a decorator
If the child class is missing a decorator, the compiler effectively behaves
as if the parent class' decorator is applied to the child class as well.
This is the "undecorated child" scenario, and this commit adds a migration
to ngcc to support this pattern in Ivy.
This migration has 2 phases. First, the NgModules of the application are
scanned for classes in 'declarations' which are missing decorators, but
whose base classes do have decorators. These classes are the undecorated
children. This scan is performed recursively, so even if a declared class
has a base class that itself inherits a decorator, this case is handled.
Next, a synthetic decorator (either @Component or @Directive) is created
on the child class. This decorator copies some critical information such
as 'selector' and 'exportAs', as well as supports any decorated fields
(@Input, etc). A flag is passed to the decorator compiler which causes a
special feature `CopyDefinitionFeature` to be included on the compiled
definition. This feature copies at runtime the remaining aspects of the
parent definition which `InheritDefinitionFeature` does not handle,
completing the "full" inheritance of the child class' decorator from its
parent class.
PR Close #33362
2019-10-23 15:00:49 -04:00
|
|
|
"@npm//typescript",
|
2019-03-20 09:47:58 -04:00
|
|
|
],
|
|
|
|
)
|
|
|
|
|
2020-06-08 15:04:20 -04:00
|
|
|
# As of version 10, the release packages do not contain esm5 output anymore. The ngcc integration
|
|
|
|
# tests intend to test ES5 features though, so we downlevel the flat esm2015 file to ES5 using
|
|
|
|
# Babel. We can then link that into the mock file system as if the Angular core package is still
|
|
|
|
# built with previous APF versions where esm5 output was shipped. This allows us to ensure that ngcc
|
|
|
|
# properly processes libraries with esm5 output.
|
|
|
|
# **Note**: We are using Babel instead of `tsc` as TypeScript does not allow us to downlevel the
|
|
|
|
# file without setting the module resolution to either `amd` or `system`. We want to preserve ES
|
|
|
|
# modules.
|
2020-05-06 10:54:44 -04:00
|
|
|
babel(
|
|
|
|
name = "fesm5_angular_core",
|
|
|
|
outs = ["fesm5_angular_core.js"],
|
|
|
|
args = [
|
|
|
|
"$(execpath //packages/core:npm_package)/fesm2015/core.js",
|
|
|
|
"--presets @babel/preset-env",
|
|
|
|
"--out-file $(execpath fesm5_angular_core.js)",
|
|
|
|
],
|
|
|
|
data = [
|
|
|
|
"//packages/core:npm_package",
|
|
|
|
"@npm//@babel/preset-env",
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
2019-03-20 09:47:58 -04:00
|
|
|
jasmine_node_test(
|
|
|
|
name = "integration",
|
2019-06-06 15:22:32 -04:00
|
|
|
timeout = "long",
|
2020-01-08 02:56:49 -05:00
|
|
|
bootstrap = ["//tools/testing:node_no_angular_es5"],
|
2019-03-20 09:47:58 -04:00
|
|
|
data = [
|
2020-05-06 10:54:44 -04:00
|
|
|
":fesm5_angular_core",
|
2019-03-20 09:47:58 -04:00
|
|
|
"//packages/common:npm_package",
|
|
|
|
"//packages/core:npm_package",
|
|
|
|
"@npm//rxjs",
|
|
|
|
],
|
2019-06-06 15:22:32 -04:00
|
|
|
shard_count = 4,
|
2019-03-20 09:47:58 -04:00
|
|
|
tags = [
|
|
|
|
# Disabled in AOT mode because we want ngcc to compile non-AOT Angular packages.
|
|
|
|
"no-ivy-aot",
|
|
|
|
],
|
2021-02-08 19:43:48 -05:00
|
|
|
templated_args = [
|
|
|
|
# TODO(josephperrott): update dependency usages to no longer need bazel patch module resolver
|
|
|
|
# See: https://github.com/bazelbuild/rules_nodejs/wiki#--bazel_patch_module_resolver-now-defaults-to-false-2324
|
|
|
|
"--bazel_patch_module_resolver",
|
|
|
|
],
|
2019-03-20 09:47:58 -04:00
|
|
|
deps = [
|
|
|
|
":integration_lib",
|
|
|
|
"@npm//canonical-path",
|
|
|
|
"@npm//convert-source-map",
|
|
|
|
],
|
|
|
|
)
|