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)) {
export function parseType(
typeNode: TypeNode,
typeTable: TypeTable,
lociTable: LociTable
): Result {
// Type references must be parsed first to ensure internal type aliases are handled
if (TypeGuards.isTypeReferenceNode(typeNode)) {
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)) {
function parseTypeReference(
typeNode: TypeReferenceNode
): ReferenceType | PrimitiveType | CustomPrimitiveType {
const declaration = getTargetDeclarationFromTypeReference(typeNode);
const name = declaration.getName();
if (TypeGuards.isTypeAliasDeclaration(declaration)) {
const targetTypeNode = declaration.getTypeNodeOrThrow();
// if the type name is one of of the internal ones ensure they have not been redefined
if (SPOT_TYPE_ALIASES.includes(name)) {
if (TypeGuards.isTypeReferenceNode(targetTypeNode)) {
throw new Error(`Internal type ${name} must not be redefined`);
} else if (declaration.getType().isString()) {
switch (name) {
case "String":
return STRING;
case "Date":
return DATE;
case "DateTime":
return DATETIME;
default:
throw new Error(`Internal type ${name} must not be redefined`);
}
} else if (declaration.getType().isNumber()) {
switch (name) {
case "Number":
case "Float":
| Int32Type
| Int64Type,
ParserError
> {
const declarationResult = getTargetDeclarationFromTypeReference(typeNode);
if (declarationResult.isErr()) return declarationResult;
const declaration = declarationResult.unwrap();
const name = declaration.getName();
if (TypeGuards.isTypeAliasDeclaration(declaration)) {
const decTypeNode = declaration.getTypeNodeOrThrow();
// if the type name is one of of the internal ones ensure they have not been redefined
// TODO: introduce some more type safety
if (SPOT_TYPE_ALIASES.includes(name)) {
if (TypeGuards.isTypeReferenceNode(decTypeNode)) {
throw new Error(`Internal type ${name} must not be redefined`);
} else if (declaration.getType().isString()) {
switch (name) {
case "String":
return ok(stringType());
case "Date":
return ok(dateType());
case "DateTime":
return ok(dateTimeType());
default:
throw new Error(`Internal type ${name} must not be redefined`);
}
} else if (declaration.getType().isNumber()) {
switch (name) {
case "Number":
case "Float":
const propertyType = propertiesParentDeclaration
.getPropertyOrThrow(literalChain[0].getLiteralText())
.getTypeNodeOrThrow();
if (TypeGuards.isTypeLiteralNode(propertyType)) {
return resolveIndexedAccessTypeReference(
propertyType,
literalChain.slice(1)
);
}
if (TypeGuards.isExpression(propertyType)) {
return propertyType;
}
if (!TypeGuards.isTypeReferenceNode(propertyType)) {
throw new Error("indexed access type error: expected type reference node");
}
return resolveIndexedAccessTypeReference(
getTargetDeclarationFromTypeReference(propertyType),
literalChain.slice(1)
);
}
export function isDeclarationOfInterface(node: sast.VariableDeclaration) : boolean {
const properties = node.getDescendantsOfKind(SyntaxKind.PropertySignature);
for (let i = 0; i < properties.length; i++)
{
const propName = properties[i].getName();
if (properties[i].getName() === "prototype")
{
const propType = properties[i].getTypeNode();
if (TypeGuards.isTypeReferenceNode(propType))
{
const typeName = propType.getText();
const interfaceDec = propType.getSourceFile().getInterface(typeName);
return (typeof interfaceDec !== "undefined");
}
}
}
return false;
}