Browse Source

feat: add a tree structure for generic types

pull/5137/head
Arman Ozak 6 years ago
parent
commit
56bf0e6be1
  1. 1
      npm/ng-packs/packages/schematics/src/utils/index.ts
  2. 71
      npm/ng-packs/packages/schematics/src/utils/tree.ts

1
npm/ng-packs/packages/schematics/src/utils/index.ts

@ -7,4 +7,5 @@ export * from './rule';
export * from './service';
export * from './source';
export * from './text';
export * from './tree';
export * from './workspace';

71
npm/ng-packs/packages/schematics/src/utils/tree.ts

@ -0,0 +1,71 @@
export class TypeNode {
children: TypeNode[] = [];
index = 0;
constructor(
public data: string,
public parent: TypeNode | null,
public mapperFn = (node: TypeNode) => node.data,
) {}
toGenerics(): string[] {
const generics = this.children.length ? `<${this.children.map(n => `T${n.index}`)}>` : '';
return [this.data + generics].concat(
this.children.reduce((acc: string[], node) => acc.concat(node.toGenerics()), []),
);
}
toString() {
const self = this.mapperFn(this);
if (!self) return '';
const representation = self + this.children.filter(String || Boolean).join(', ');
if (!this.parent) return representation;
const siblings = this.parent.children;
return (
(siblings[0] === this ? '<' : '') +
representation +
(siblings[siblings.length - 1] === this ? '>' : '')
);
}
valueOf() {
return this.toString();
}
}
export function parseGenerics(type: string, mapperFn?: TypeNodeMapperFn) {
const [rootType, ...types] = type.split('<');
const root = new TypeNode(rootType, null, mapperFn);
types.reduce((parent, t) => {
const [left, right] = t.split(/>+,?\s*/);
const leftNode = new TypeNode(left, parent, mapperFn);
leftNode.index = parent.children.length;
parent.children.push(leftNode);
parent = leftNode;
let { length } = t.match(/>/g) || [];
while (length--) parent = parent.parent!;
if (right) {
parent = parent.parent!;
const rightNode = new TypeNode(right, parent, mapperFn);
rightNode.index = parent.children.length;
parent.children.push(rightNode);
parent = rightNode;
}
return parent;
}, root);
return root;
}
export type TypeNodeMapperFn = (node: TypeNode) => string;
Loading…
Cancel
Save