Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export function parseTypeNode(typeNode: TypeNode): DataType {
// Type references must be parsed first to ensure internal type aliases are handled
if (TypeGuards.isTypeReferenceNode(typeNode)) {
return parseTypeReference(typeNode);
} else if (TypeGuards.isNullLiteral(typeNode)) {
return NULL;
} else if (TypeGuards.isBooleanKeyword(typeNode)) {
return BOOLEAN;
} else if (TypeGuards.isStringKeyword(typeNode)) {
return STRING;
} else if (TypeGuards.isNumberKeyword(typeNode)) {
return FLOAT;
} else if (TypeGuards.isLiteralTypeNode(typeNode)) {
return parseLiteralType(typeNode);
} else if (TypeGuards.isArrayTypeNode(typeNode)) {
return parseArrayType(typeNode);
} else if (TypeGuards.isTypeLiteralNode(typeNode)) {
return parseObjectLiteralType(typeNode);
} else if (TypeGuards.isUnionTypeNode(typeNode)) {
return parseUnionType(typeNode);
} else if (TypeGuards.isIndexedAccessTypeNode(typeNode)) {
return parseTypeNode(parseIndexedAccessType(typeNode));
} else {
throw new Error("unknown type");
}
}
if (typeNode.getType().isArray()) {
return parseArrayConstructorType(typeNode, typeTable, lociTable);
}
return parseTypeReference(typeNode, typeTable, lociTable);
} else if (TypeGuards.isNullLiteral(typeNode)) {
return ok(nullType());
// TODO: discourage native boolean keyword?
} else if (TypeGuards.isBooleanKeyword(typeNode)) {
return ok(booleanType());
// TODO: discourage native string keyword?
} else if (TypeGuards.isStringKeyword(typeNode)) {
return ok(stringType());
// TODO: discourage native number keyword?
} else if (TypeGuards.isNumberKeyword(typeNode)) {
return ok(floatType());
} else if (TypeGuards.isLiteralTypeNode(typeNode)) {
return parseLiteralType(typeNode);
} else if (TypeGuards.isArrayTypeNode(typeNode)) {
return parseArrayType(typeNode, typeTable, lociTable);
} else if (TypeGuards.isTypeLiteralNode(typeNode)) {
return parseObjectLiteralType(typeNode, typeTable, lociTable);
} else if (TypeGuards.isUnionTypeNode(typeNode)) {
return parseUnionType(typeNode, typeTable, lociTable);
} else if (TypeGuards.isIndexedAccessTypeNode(typeNode)) {
return parseIndexedAccessType(typeNode, typeTable, lociTable);
} else {
throw new TypeNotAllowedError("unknown type", {
file: typeNode.getSourceFile().getFilePath(),
position: typeNode.getPos()
});
}
}
function resolveLiteralTypesInIndexedAccessType(
typeNode: IndexedAccessTypeNode
): LiteralTypeNode[] {
const object = typeNode.getObjectTypeNode();
const index = typeNode.getIndexTypeNode();
if (!TypeGuards.isLiteralTypeNode(index)) {
throw new Error("indexed access type error: not a literal type node");
}
if (TypeGuards.isIndexedAccessTypeNode(object)) {
return [...resolveLiteralTypesInIndexedAccessType(object), index];
}
return [index];
}
function resolveIndexAccessPropertyAccessChain(
typeNode: IndexedAccessTypeNode,
accResult: Result = ok([])
): Result {
if (accResult.isErr()) return accResult;
const acc = accResult.unwrap();
const literalTypeNode = typeNode.getIndexTypeNode();
if (!TypeGuards.isLiteralTypeNode(literalTypeNode)) {
throw new Error("expected type literal");
}
const literalTypeResult = parseLiteralType(literalTypeNode);
if (literalTypeResult.isErr()) return literalTypeResult;
const literalType = literalTypeResult.unwrap();
if (literalType.kind !== TypeKind.STRING_LITERAL) {
throw new Error("expected string literal");
}
const chainParent = typeNode.getObjectTypeNode();
if (TypeGuards.isIndexedAccessTypeNode(chainParent)) {
return resolveIndexAccessPropertyAccessChain(
chainParent,
ok(acc.concat(literalType.value))
);
}