Skip to content

converts "module:foo~bar" to import #144

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
51 changes: 49 additions & 2 deletions src/type_resolve_helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum ENodeType {
TUPLE, // [a,b] has types for children
TYPE, // string, X has no children
OBJECT, // {a:b, c:d} has name value pairs for children
MODULE, // module:foo/bar~baz
}
export class StringTreeNode {
children: StringTreeNode[] = [];
Expand Down Expand Up @@ -59,12 +60,19 @@ export class StringTreeNode {
return 'TYPE';
case ENodeType.OBJECT:
return 'OBJECT';
case ENodeType.MODULE:
return 'MODULE';
default:
return 'UNKNOWN'
}
}
}

export class ModuleTreeNode extends StringTreeNode {
constructor(public name: string, public type: ENodeType, public parent: StringTreeNode | null, public qualifier?: string)
{ super(name, type, parent); }
}

export function resolveComplexTypeName(name: string, doclet?: TTypedDoclet): ts.TypeNode
{
// parse the string into a tree of tsNodeType's
Expand All @@ -80,6 +88,15 @@ export function resolveComplexTypeName(name: string, doclet?: TTypedDoclet): ts.
return resolveTree(root);
}

export function createModuleImport(name: string, qualifier?: string | null, typeArguments?: ts.TypeNode[] | null): ts.ImportTypeNode
{
const nameLiteral: ts.StringLiteral = ts.createStringLiteral(name);
const nameNode: ts.LiteralTypeNode = ts.createLiteralTypeNode(nameLiteral);
const qualifierIdentifier: ts.Identifier = ts.createIdentifier(qualifier || 'default');
const innerTypeArguments: ts.TypeNode[] = Array.isArray(typeArguments) ? typeArguments.slice() : [];
return ts.createImportTypeNode(nameNode, qualifierIdentifier, innerTypeArguments);
}

export function generateTree(name: string, parent: StringTreeNode | null = null) : StringTreeNode | null
{
const anyNode = new StringTreeNode('any', ENodeType.TYPE, parent);
Expand Down Expand Up @@ -189,6 +206,29 @@ export function generateTree(name: string, parent: StringTreeNode | null = null)
continue;
}

if (partUpper === 'MODULE') {
let generic;
const templateIndex = parts.indexOf('<');
if (templateIndex > -1) {
const genericClosingIndex = findMatchingBracket(parts, templateIndex, '<', '>');
if (genericClosingIndex > -1) {
generic = parts.slice(templateIndex + 1, genericClosingIndex).join('')
}
}

const endAt = templateIndex < 0 ? parts.length : templateIndex;
const [name, qualifier] = parts.slice(i + 2, endAt).join('').split('~');
const node = new ModuleTreeNode(name, ENodeType.MODULE, parent, qualifier.replace(/\.$/, ''));
if (generic)
generateTree(generic, node);
if (!parent)
return node;

parent.children.push(node);
i = parts.length;
continue;
}

// TODO: Tuples?

// skip separators, our handling below takes them into account
Expand Down Expand Up @@ -236,7 +276,7 @@ function findMatchingBracket(parts: string[], startIndex: number, openBracket: s
return -1;
}

function resolveTree(node: StringTreeNode, parentTypes: ts.TypeNode[] | null = null) : ts.TypeNode
function resolveTree(node: StringTreeNode | ModuleTreeNode, parentTypes: ts.TypeNode[] | null = null) : ts.TypeNode
{
// this nodes resolved child types
const childTypes: ts.TypeNode[] = [];
Expand Down Expand Up @@ -372,7 +412,14 @@ function resolveTree(node: StringTreeNode, parentTypes: ts.TypeNode[] | null = n

parentTypes.push(genericNode);
break;
case ENodeType.MODULE:
const moduleNode: ModuleTreeNode = node;
const importNode: ts.ImportTypeNode = createModuleImport(moduleNode.name, moduleNode.qualifier, childTypes);
if (!parentTypes)
return importNode;

parentTypes.push(importNode);
break;
case ENodeType.UNION:
if (childTypes.length === 0 )
{
Expand Down Expand Up @@ -716,7 +763,7 @@ export function resolveTypeName(name: string, doclet?: TTypedDoclet): ts.TypeNod
);
}
}

return resolveComplexTypeName(name);
}

Expand Down