X Tutup
The Wayback Machine - https://web.archive.org/web/20220131204458/https://github.com/angular/angular/pull/44092
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(compiler): use base class parameters for any non-decorated class … #44092

Closed
wants to merge 1 commit into from

Conversation

@JoostK
Copy link
Member

@JoostK JoostK commented Nov 5, 2021

…without constructor parameters

Previously, the JIT compiler would take into consideration whether a
type had a constructor function that appeared to have been synthesized.
For synthesized constructors, the JIT compiler would fall back to using
the parameter metadata from the base class, if any. However, the
detection of synthesized constructors was rather error-prone: it
required complex regexes to support various syntax forms, i.e. ES2015 vs
ES5 code, minified vs non-minified code, TypeScript versus Rollup
generated constructors etc.

The primary driver for this change has been the inability of these
regexes to deal with constructors that have been instrumented with code
coverage reporting logic. This logic affects the syntax forms of
constructors, which threw off the JIT compiler in no longer considering
these constructors as synthesized. Consequently, the compiler would not
fall back to using the base type's parameters but would generate a
factory function without any dependencies. At runtime, this causes
instances created using these factories to be missing their
dependencies.

The detection of synthesized constructors used to be necessary back in
the day, when Angular supported classes without decorators to take part
in DI. This is no longer allowed since Angular 10, as any class that
takes part in Angular's DI mechanism is required to have a decorator.
When a decorator is present, the JIT compiler is able to use the
decorator metadata to derive whether a constructor was originally
present. Additionally, microsoft/TypeScript#12439 used to be a blocking
issue for which manual detection of synthesized constructors was a
necessity. This issue has long been solved so is no longer relevant
today.

This commit removes all logic to detect synthesized constructors
altogether, per the above observation that decorators must be used for
DI to work correctly. Hence, when no metadata is present and the
constructor function does not have any parameters, we now conclude that
the type does not have its own constructor and fall back to the base
type. This resolves the limitations with the regexes altogether.

Fixes #15212
Fixes #31337

@ngbot ngbot bot added this to the Backlog milestone Nov 5, 2021
@ngbot ngbot bot added this to the Backlog milestone Nov 5, 2021
@google-cla google-cla bot added the cla: yes label Nov 5, 2021
@JoostK
Copy link
Member Author

@JoostK JoostK commented Nov 5, 2021

This is an alternative to #37811 and greatly simplifies things.

@JoostK JoostK force-pushed the remove-delegate-ctor-logic branch 2 times, most recently from b7dcede to 233ca9a Nov 6, 2021
…without constructor parameters

Previously, the JIT compiler would take into consideration whether a
type had a constructor function that appeared to have been synthesized.
For synthesized constructors, the JIT compiler would fall back to using
the parameter metadata from the base class, if any. However, the
detection of synthesized constructors was rather error-prone: it
required complex regexes to support various syntax forms, i.e. ES2015 vs
ES5 code, minified vs non-minified code, TypeScript versus Rollup
generated constructors etc.

The primary driver for this change has been the inability of these
regexes to deal with constructors that have been instrumented with code
coverage reporting logic. This logic affects the syntax forms of
constructors, which threw off the JIT compiler in no longer considering
these constructors as synthesized. Consequently, the compiler would not
fall back to using the base type's parameters but would generate a
factory function without any dependencies. At runtime, this causes
instances created using these factories to be missing their
dependencies.

The detection of synthesized constructors used to be necessary back in
the day, when Angular supported classes without decorators to take part
in DI. This is no longer allowed since Angular 10, as any class that
takes part in Angular's DI mechanism is required to have a decorator.
When a decorator is present, the JIT compiler is able to use the
decorator metadata to derive whether a constructor was originally
present. Additionally, microsoft/TypeScript#12439 used to be a blocking
issue for which manual detection of synthesized constructors was a
necessity. This issue has long been solved so is no longer relevant
today.

This commit removes all logic to detect synthesized constructors
altogether, per the above observation that decorators must be used for
DI to work correctly. Hence, when no metadata is present and the
constructor function does not have any parameters, we now conclude that
the type does not have its own constructor and fall back to the base
type. This resolves the limitations with the regexes altogether.

Fixes angular#15212
Fixes angular#31337
@JoostK JoostK force-pushed the remove-delegate-ctor-logic branch from 233ca9a to bd7211d Nov 6, 2021
@@ -40,18 +40,21 @@ class TestInterceptor implements HttpInterceptor {
}
}

@Injectable()
Copy link
Member Author

@JoostK JoostK Nov 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes show the risk involved with this change; we may need to consider this a breaking change if we go ahead with it.

The primary question is whether a class with its own, empty constructor is a valid candidate for usage with useClass providers even if it does not have a decorator. It used to be, but will no longer be with the changes in this PR.

@JoostK
Copy link
Member Author

@JoostK JoostK commented Jan 16, 2022

Closing this in favor of #44732, as this change is too breaking.

@JoostK JoostK closed this Jan 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
X Tutup