Skip to content

Commit

Permalink
feat: allow dereferencing references that are circular
Browse files Browse the repository at this point in the history
fixes #1276
  • Loading branch information
domoritz committed Mar 3, 2023
1 parent b692d84 commit e6a3b2b
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 10 deletions.
6 changes: 5 additions & 1 deletion factory/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import { UnknownTypeNodeParser } from "../src/NodeParser/UnknownTypeNodeParser";
import { VoidTypeNodeParser } from "../src/NodeParser/VoidTypeNodeParser";
import { SubNodeParser } from "../src/SubNodeParser";
import { TopRefNodeParser } from "../src/TopRefNodeParser";
import { BaseType } from "../src/Type/BaseType";

export type ParserAugmentor = (parser: MutableParser) => void;

Expand All @@ -83,8 +84,11 @@ export function createParser(program: ts.Program, config: Config, augmentor?: Pa
return nodeParser;
}
}

const circular: Map<string, BaseType> = new Map();

function withCircular(nodeParser: SubNodeParser): SubNodeParser {
return new CircularReferenceNodeParser(nodeParser);
return new CircularReferenceNodeParser(nodeParser, circular);
}

if (augmentor) {
Expand Down
7 changes: 4 additions & 3 deletions src/CircularReferenceNodeParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { ReferenceType } from "./Type/ReferenceType";
import { getKey } from "./Utils/nodeKey";

export class CircularReferenceNodeParser implements SubNodeParser {
protected circular: Map<string, BaseType> = new Map();

public constructor(protected childNodeParser: SubNodeParser) {}
public constructor(
protected childNodeParser: SubNodeParser,
protected circular: Map<string, BaseType> = new Map()
) {}

public supportsNode(node: ts.Node): boolean {
return this.childNodeParser.supportsNode(node);
Expand Down
4 changes: 4 additions & 0 deletions src/Type/ReferenceType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export class ReferenceType extends BaseType {
return this.type;
}

public hasType(): boolean {
return this.type != null;
}

public setType(type: BaseType): void {
this.type = type;
this.setId(type.getId());
Expand Down
13 changes: 7 additions & 6 deletions src/Utils/derefType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { BaseType } from "../Type/BaseType";
import { DefinitionType } from "../Type/DefinitionType";
import { ReferenceType } from "../Type/ReferenceType";

/**
* Dereference the type as far as possible.
*/
export function derefType(type: BaseType): BaseType {
if (
type instanceof ReferenceType ||
type instanceof DefinitionType ||
type instanceof AliasType ||
type instanceof AnnotatedType
) {
if (type instanceof DefinitionType || type instanceof AliasType || type instanceof AnnotatedType) {
return derefType(type.getType());
}
if (type instanceof ReferenceType && type.hasType()) {
return derefType(type.getType());
}

Expand Down

0 comments on commit e6a3b2b

Please sign in to comment.