Skip to content

Allow TraverseCallback to bail out early #1034

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

Merged
merged 3 commits into from
May 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,14 @@
"documentation",
"generator",
"gruntplugin"
]
],
"nyc": {
"extension": [
".ts",
".tsx"
],
"exclude": [
"**/*.d.ts"
]
}
}
24 changes: 10 additions & 14 deletions src/lib/models/reflections/abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,11 @@ export enum TraverseProperty {
}

export interface TraverseCallback {
(reflection: Reflection, property: TraverseProperty): void;
/**
* May return false to bail out of any further iteration. To preserve backwards compatibility, if
* a function returns undefined, iteration must continue.
*/
(reflection: Reflection, property: TraverseProperty): boolean | void;
}

/**
Expand Down Expand Up @@ -468,20 +472,11 @@ export abstract class Reflection {
return false;
}

/**
* @param name The name of the child to look for. Might contain a hierarchy.
*/
getChildByName(name: string): Reflection;

/**
* @param names The name hierarchy of the child to look for.
*/
getChildByName(names: string[]): Reflection;

/**
* Return a child by its name.
*
* @returns The found child or NULL.
* @param names The name hierarchy of the child to look for.
* @returns The found child or undefined.
*/
getChildByName(arg: string | string[]): Reflection | undefined {
const names: string[] = Array.isArray(arg) ? arg : arg.split('.');
Expand All @@ -492,9 +487,10 @@ export abstract class Reflection {
if (child.name === name) {
if (names.length <= 1) {
result = child;
} else if (child) {
} else {
result = child.getChildByName(names.slice(1));
}
return false;
}
});

Expand Down Expand Up @@ -610,7 +606,7 @@ export abstract class Reflection {
const lines = [indent + this.toString()];

indent += ' ';
this.traverse((child, property) => {
this.traverse((child) => {
lines.push(child.toStringHierarchy(indent));
});

Expand Down
9 changes: 5 additions & 4 deletions src/lib/models/reflections/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Reflection, ReflectionKind, TraverseCallback, TraverseProperty } from '
import { ReflectionCategory } from '../ReflectionCategory';
import { ReflectionGroup } from '../ReflectionGroup';
import { DeclarationReflection } from './declaration';
import { toArray } from 'lodash';

export class ContainerReflection extends Reflection {
/**
Expand Down Expand Up @@ -38,10 +39,10 @@ export class ContainerReflection extends Reflection {
* @param callback The callback function that should be applied for each child reflection.
*/
traverse(callback: TraverseCallback) {
if (this.children) {
this.children.slice().forEach((child: DeclarationReflection) => {
callback(child, TraverseProperty.Children);
});
for (const child of toArray(this.children)) {
if (callback(child, TraverseProperty.Children) === false) {
return;
}
}
}

Expand Down
29 changes: 21 additions & 8 deletions src/lib/models/reflections/declaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Type, ReflectionType } from '../types/index';
import { ContainerReflection } from './container';
import { SignatureReflection } from './signature';
import { TypeParameterReflection } from './type-parameter';
import { toArray } from 'lodash';

/**
* Stores hierarchical type data.
Expand Down Expand Up @@ -152,28 +153,40 @@ export class DeclarationReflection extends ContainerReflection implements Defaul
* @param callback The callback function that should be applied for each child reflection.
*/
traverse(callback: TraverseCallback) {
if (this.typeParameters) {
this.typeParameters.slice().forEach((parameter) => callback(parameter, TraverseProperty.TypeParameter));
for (const parameter of toArray(this.typeParameters)) {
if (callback(parameter, TraverseProperty.TypeParameter) === false) {
return;
}
}

if (this.type instanceof ReflectionType) {
callback(this.type.declaration, TraverseProperty.TypeLiteral);
if (callback(this.type.declaration, TraverseProperty.TypeLiteral) === false) {
return;
}
}

if (this.signatures) {
this.signatures.slice().forEach((signature) => callback(signature, TraverseProperty.Signatures));
for (const signature of toArray(this.signatures)) {
if (callback(signature, TraverseProperty.Signatures) === false) {
return;
}
}

if (this.indexSignature) {
callback(this.indexSignature, TraverseProperty.IndexSignature);
if (callback(this.indexSignature, TraverseProperty.IndexSignature) === false) {
return;
}
}

if (this.getSignature) {
callback(this.getSignature, TraverseProperty.GetSignature);
if (callback(this.getSignature, TraverseProperty.GetSignature) === false) {
return;
}
}

if (this.setSignature) {
callback(this.setSignature, TraverseProperty.SetSignature);
if (callback(this.setSignature, TraverseProperty.SetSignature) === false) {
return;
}
}

super.traverse(callback);
Expand Down
4 changes: 3 additions & 1 deletion src/lib/models/reflections/parameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ export class ParameterReflection extends Reflection implements DefaultValueConta
*/
traverse(callback: TraverseCallback) {
if (this.type instanceof ReflectionType) {
callback(this.type.declaration, TraverseProperty.TypeLiteral);
if (callback(this.type.declaration, TraverseProperty.TypeLiteral) === false) {
return;
}
}

super.traverse(callback);
Expand Down
13 changes: 2 additions & 11 deletions src/lib/models/reflections/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,13 @@ export class ProjectReflection extends ContainerReflection {
return values;
}

/**
* @param name The name to look for. Might contain a hierarchy.
*/
findReflectionByName(name: string): Reflection;

/**
* @param names The name hierarchy to look for.
*/
findReflectionByName(names: string[]): Reflection;

/**
* Try to find a reflection by its name.
*
* @param names The name hierarchy to look for, if a string, the name will be split on "."
* @return The found reflection or undefined.
*/
findReflectionByName(arg: any): Reflection | undefined {
findReflectionByName(arg: string | string[]): Reflection | undefined {
const names: string[] = Array.isArray(arg) ? arg : arg.split('.');
const name = names.pop();

Expand Down
17 changes: 12 additions & 5 deletions src/lib/models/reflections/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Reflection, TypeContainer, TypeParameterContainer, TraverseProperty, Tr
import { ContainerReflection } from './container';
import { ParameterReflection } from './parameter';
import { TypeParameterReflection } from './type-parameter';
import { toArray } from 'lodash';

export class SignatureReflection extends Reflection implements TypeContainer, TypeParameterContainer {
parent?: ContainerReflection;
Expand Down Expand Up @@ -57,15 +58,21 @@ export class SignatureReflection extends Reflection implements TypeContainer, Ty
*/
traverse(callback: TraverseCallback) {
if (this.type instanceof ReflectionType) {
callback(this.type.declaration, TraverseProperty.TypeLiteral);
if (callback(this.type.declaration, TraverseProperty.TypeLiteral) === false) {
return;
}
}

if (this.typeParameters) {
this.typeParameters.slice().forEach((parameter) => callback(parameter, TraverseProperty.TypeParameter));
for (const parameter of toArray(this.typeParameters)) {
if (callback(parameter, TraverseProperty.TypeParameter) === false) {
return;
}
}

if (this.parameters) {
this.parameters.slice().forEach((parameter) => callback(parameter, TraverseProperty.Parameters));
for (const parameter of toArray(this.parameters)) {
if (callback(parameter, TraverseProperty.Parameters) === false) {
return;
}
}

super.traverse(callback);
Expand Down