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-cli): use ModuleWithProviders type if static eval fails #37126

Closed
wants to merge 1 commit into from

Conversation

alxhub
Copy link
Member

@alxhub alxhub commented May 15, 2020

When the compiler encounters a function call within an NgModule imports
section, it attempts to resolve it to an NgModule-annotated class by
looking at the function body and evaluating the statements there. This
evaluation can only understand simple functions which have a single
return statement as their body. If the function the user writes is more
complex than that, the compiler won't be able to understand it and
previously the PartialEvaluator would return a "DynamicValue" for
that import.

With this change, in the event the function body resolution fails the
PartialEvaluator will now attempt to use its foreign function resolvers to
determine the correct result from the function's type signtaure instead. If
the function is annotated with a correct ModuleWithProviders type, the
compiler will be able to understand the import without static analysis of
the function body.

@pullapprove pullapprove bot requested a review from JoostK May 15, 2020 00:56
Copy link
Member

@JoostK JoostK left a comment

Choose a reason for hiding this comment

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

I believe this would address #36415 (FW-2048) and make #14410 obsolete.

@@ -584,7 +584,7 @@ export class NgModuleDecoratorHandler implements
throw new FatalDiagnosticError(
ErrorCode.VALUE_HAS_WRONG_TYPE, expr,
`Value at position ${idx} in the NgModule.${arrayName} of ${
className} is not a reference: ${entry}`);
className} is not a reference: ${entry!.constructor.name}`);
Copy link
Member

Choose a reason for hiding this comment

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

This seems to me like a dangerous change to make, given that entry could legitimately be null/undefined.

env.write(`module.ts`, `
import {NgModule, ModuleWithProviders} from '@angular/core';

export function notStaticallyAnalyzable(): ModuleWithProviders<SomeModule> {
Copy link
Member

Choose a reason for hiding this comment

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

How about adding a test where the return type is missing. We can then assert on the insightful diagnostic that should be reported by the FFR (i.e. here) which would address the poor UX that we had until this change.

Copy link
Member Author

@alxhub alxhub May 15, 2020

Choose a reason for hiding this comment

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

Oh, that's an interesting idea. Although in 10.x the MWP type is mandatory, so I don't think that case really applies anymore.

Copy link
Member

@JoostK JoostK May 15, 2020

Choose a reason for hiding this comment

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

It can still occur when someone leaves off the return type altogether.

edit: oh, but if that were the case then the FFR wouldn't produce a diagnostic, as it wouldn't consider the function to be a ModuleWithProviders in the first place. So not having a return type at all will still result in poor UX, without a hint that an explicit return type should be used.

@kara kara added the area: compiler Issues related to `ngc`, Angular's template compiler label May 15, 2020
@ngbot ngbot bot added this to the needsTriage milestone May 15, 2020
When the compiler encounters a function call within an NgModule imports
section, it attempts to resolve it to an NgModule-annotated class by
looking at the function body and evaluating the statements there. This
evaluation can only understand simple functions which have a single
return statement as their body. If the function the user writes is more
complex than that, the compiler won't be able to understand it and
previously the PartialEvaluator would return a "DynamicValue" for
that import.

With this change, in the event the function body resolution fails the
PartialEvaluator will now attempt to use its foreign function resolvers to
determine the correct result from the function's type signtaure instead. If
the function is annotated with a correct ModuleWithProviders type, the
compiler will be able to understand the import without static analysis of
the function body.
@alxhub
Copy link
Member Author

alxhub commented May 20, 2020

Presubmit

@alxhub alxhub added action: merge The PR is ready for merge by the caretaker target: patch This PR is targeted for the next patch release labels May 20, 2020
@alxhub
Copy link
Member Author

alxhub commented Jun 1, 2020

Presubmit

@atscott atscott closed this in 965a688 Jun 3, 2020
atscott pushed a commit that referenced this pull request Jun 3, 2020
…37126)

When the compiler encounters a function call within an NgModule imports
section, it attempts to resolve it to an NgModule-annotated class by
looking at the function body and evaluating the statements there. This
evaluation can only understand simple functions which have a single
return statement as their body. If the function the user writes is more
complex than that, the compiler won't be able to understand it and
previously the PartialEvaluator would return a "DynamicValue" for
that import.

With this change, in the event the function body resolution fails the
PartialEvaluator will now attempt to use its foreign function resolvers to
determine the correct result from the function's type signtaure instead. If
the function is annotated with a correct ModuleWithProviders type, the
compiler will be able to understand the import without static analysis of
the function body.

PR Close #37126
ngwattcos pushed a commit to ngwattcos/angular that referenced this pull request Jun 25, 2020
…ngular#37126)

When the compiler encounters a function call within an NgModule imports
section, it attempts to resolve it to an NgModule-annotated class by
looking at the function body and evaluating the statements there. This
evaluation can only understand simple functions which have a single
return statement as their body. If the function the user writes is more
complex than that, the compiler won't be able to understand it and
previously the PartialEvaluator would return a "DynamicValue" for
that import.

With this change, in the event the function body resolution fails the
PartialEvaluator will now attempt to use its foreign function resolvers to
determine the correct result from the function's type signtaure instead. If
the function is annotated with a correct ModuleWithProviders type, the
compiler will be able to understand the import without static analysis of
the function body.

PR Close angular#37126
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jul 4, 2020
profanis pushed a commit to profanis/angular that referenced this pull request Sep 5, 2020
…ngular#37126)

When the compiler encounters a function call within an NgModule imports
section, it attempts to resolve it to an NgModule-annotated class by
looking at the function body and evaluating the statements there. This
evaluation can only understand simple functions which have a single
return statement as their body. If the function the user writes is more
complex than that, the compiler won't be able to understand it and
previously the PartialEvaluator would return a "DynamicValue" for
that import.

With this change, in the event the function body resolution fails the
PartialEvaluator will now attempt to use its foreign function resolvers to
determine the correct result from the function's type signtaure instead. If
the function is annotated with a correct ModuleWithProviders type, the
compiler will be able to understand the import without static analysis of
the function body.

PR Close angular#37126
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: compiler Issues related to `ngc`, Angular's template compiler cla: yes target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants