fix(compiler-cli): use ModuleWithProviders type if static eval fails (#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
This commit is contained in:
@ -2390,6 +2390,45 @@ runInEachFileSystem(os => {
|
||||
});
|
||||
|
||||
describe('unwrapping ModuleWithProviders functions', () => {
|
||||
it('should use a local ModuleWithProviders-annotated return type if a function is not statically analyzable',
|
||||
() => {
|
||||
env.write(`module.ts`, `
|
||||
import {NgModule, ModuleWithProviders} from '@angular/core';
|
||||
|
||||
export function notStaticallyAnalyzable(): ModuleWithProviders<SomeModule> {
|
||||
console.log('this interferes with static analysis');
|
||||
return {
|
||||
ngModule: SomeModule,
|
||||
providers: [],
|
||||
};
|
||||
}
|
||||
|
||||
@NgModule()
|
||||
export class SomeModule {}
|
||||
`);
|
||||
|
||||
env.write('test.ts', `
|
||||
import {NgModule} from '@angular/core';
|
||||
import {notStaticallyAnalyzable} from './module';
|
||||
|
||||
@NgModule({
|
||||
imports: [notStaticallyAnalyzable()]
|
||||
})
|
||||
export class TestModule {}
|
||||
`);
|
||||
|
||||
env.driveMain();
|
||||
|
||||
const jsContents = env.getContents('test.js');
|
||||
expect(jsContents).toContain('imports: [notStaticallyAnalyzable()]');
|
||||
|
||||
const dtsContents = env.getContents('test.d.ts');
|
||||
expect(dtsContents).toContain(`import * as i1 from "./module";`);
|
||||
expect(dtsContents)
|
||||
.toContain(
|
||||
'i0.ɵɵNgModuleDefWithMeta<TestModule, never, [typeof i1.SomeModule], never>');
|
||||
});
|
||||
|
||||
it('should extract the generic type and include it in the module\'s declaration', () => {
|
||||
env.write(`test.ts`, `
|
||||
import {NgModule} from '@angular/core';
|
||||
|
Reference in New Issue
Block a user