Skip to content

Commit 28995db

Browse files
devversionmatsko
authored andcommitted
fix(core): missing-injectable migration should not migrate @NgModule classes (#36369)
Based on the migration guide, provided classes which don't have either `@Injectable`, `@Directive`, `@Component` or `@Pipe` need to be migrated. This is not correct as provided classes with an `@NgModule` also have a factory function that can be read by the r3 injector. It's unclear in which cases the `@NgModule` decorator is used for provided classes, but this scenario has been reported. Either we fix this in the migration, or we make sure to report this as unsupported in the Ivy compiler. Fixes #35700. PR Close #36369
1 parent f186c32 commit 28995db

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

packages/core/schematics/migrations/missing-injectable/transform.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ import {ResolvedDirective, ResolvedNgModule} from './definition_collector';
1818
import {ProviderLiteral, ProvidersEvaluator} from './providers_evaluator';
1919
import {UpdateRecorder} from './update_recorder';
2020

21-
22-
23-
/** Name of decorators which imply that a given class does not need to be migrated. */
24-
const NO_MIGRATE_DECORATORS = ['Injectable', 'Directive', 'Component', 'Pipe'];
21+
/**
22+
* Name of decorators which imply that a given class does not need to be migrated.
23+
* - `@Injectable`, `@Directive`, `@Component` and `@Pipe` instruct the compiler
24+
* to generate a factory definition.
25+
* - `@NgModule` instructs the compiler to generate a provider definition that holds
26+
* the factory function.
27+
*/
28+
const NO_MIGRATE_DECORATORS = ['Injectable', 'Directive', 'Component', 'Pipe', 'NgModule'];
2529

2630
export interface AnalysisFailure {
2731
node: ts.Node;

packages/core/schematics/test/missing_injectable_migration_spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,24 @@ describe('Missing injectable migration', () => {
350350
expect(tree.readContent('/index.ts')).not.toContain('@Injectable');
351351
});
352352

353+
it('should not migrate provider which is already decorated with @NgModule', async () => {
354+
const importedSymbols = type !== 'NgModule' ? ['NgModule', type] : ['NgModule'];
355+
writeFile('/index.ts', `
356+
import {${importedSymbols.join(', ')}} from '@angular/core';
357+
358+
@NgModule()
359+
export class MyOtherModule {}
360+
361+
@${type}({${propName}: [MyOtherModule]})
362+
export class TestClass {}
363+
`);
364+
365+
await runMigration();
366+
367+
expect(warnOutput.length).toBe(0);
368+
expect(tree.readContent('/index.ts')).not.toContain('@Injectable');
369+
});
370+
353371
it(`should migrate multiple providers in same ${type}`, async () => {
354372
writeFile('/index.ts', `
355373
import {${type}} from '@angular/core';

0 commit comments

Comments
 (0)