mirror of https://github.com/abpframework/abp.git
2 changed files with 72 additions and 0 deletions
@ -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…
Reference in new issue