Skip to content

Commit ae0f790

Browse files
alan-agius4vikerman
authored andcommitted
fix(@schematics/angular): change findNodes to stop recursive lookup for child nodes of kind
Curtrently, when a node of kind is found, we recursivly continue to look up it's child nodes until the end of the AST. This ends up returing other nodes which we were not looking for as typically we are looking for the first level of children of the specified kind. By default now, we stop recursivly looking for child nodes of kind when we encounter one. Closes #15117
1 parent 15ef15e commit ae0f790

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

packages/schematics/angular/utility/ast-utils.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,11 @@ export function insertImport(source: ts.SourceFile, fileToEdit: string, symbolNa
9393
* @param node
9494
* @param kind
9595
* @param max The maximum number of items to return.
96+
* @param recursive Continue looking for nodes of kind recursive until end
97+
* the last child even when node of kind has been found.
9698
* @return all nodes of kind, or [] if none is found
9799
*/
98-
export function findNodes(node: ts.Node, kind: ts.SyntaxKind, max = Infinity): ts.Node[] {
100+
export function findNodes(node: ts.Node, kind: ts.SyntaxKind, max = Infinity, recursive = false): ts.Node[] {
99101
if (!node || max == 0) {
100102
return [];
101103
}
@@ -105,7 +107,7 @@ export function findNodes(node: ts.Node, kind: ts.SyntaxKind, max = Infinity): t
105107
arr.push(node);
106108
max--;
107109
}
108-
if (max > 0) {
110+
if (max > 0 && (recursive || node.kind !== kind)) {
109111
for (const child of node.getChildren()) {
110112
findNodes(child, kind, max).forEach(node => {
111113
if (max > 0) {

packages/schematics/angular/utility/ast-utils_spec.ts

+35
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,41 @@ describe('ast utils', () => {
476476
// tslint:enable:max-line-length
477477
});
478478

479+
it('should add a route to the routes to the correct array when having nested object literal', () => {
480+
const moduleContent = `
481+
import { BrowserModule } from '@angular/platform-browser';
482+
import { NgModule } from '@angular/core';
483+
import { AppComponent } from './app.component';
484+
485+
const routes = [
486+
{ path: 'foo', component: FooComponent, data: { path: 'test' }}
487+
];
488+
489+
@NgModule({
490+
declarations: [
491+
AppComponent
492+
],
493+
imports: [
494+
BrowserModule,
495+
RouterModule.forRoot(routes)
496+
],
497+
bootstrap: [AppComponent]
498+
})
499+
export class AppModule { }
500+
`;
501+
502+
const source = getTsSource(modulePath, moduleContent);
503+
const changes = addRouteDeclarationToModule(
504+
source,
505+
'./src/app', `{ path: 'bar', component: BarComponent }`,
506+
);
507+
const output = applyChanges(modulePath, moduleContent, [changes]);
508+
expect(output).toMatch(
509+
// tslint:disable-next-line:max-line-length
510+
/const routes = \[\r?\n?\s*{ path: 'foo', component: FooComponent, data: { path: 'test' }},\r?\n?\s*{ path: 'bar', component: BarComponent }\r?\n?\s*\]/,
511+
);
512+
});
513+
479514
it('should add a route to the routes argument of RouteModule', () => {
480515
const moduleContent = `
481516
import { BrowserModule } from '@angular/platform-browser';

0 commit comments

Comments
 (0)