Issue proper errors for unsupported types
This commit is contained in:
parent
02aa1c4ee0
commit
c5807c4b57
2 changed files with 30 additions and 9 deletions
|
@ -530,7 +530,7 @@ export class Transformer {
|
|||
}
|
||||
|
||||
// resolveTypeToken takes a concrete TypeScript Type resolves it to a fully qualified MuIL type token name.
|
||||
private async resolveTypeToken(ty: ts.Type): Promise<tokens.TypeToken | undefined> {
|
||||
private async resolveTypeToken(node: ts.Node, ty: ts.Type): Promise<tokens.TypeToken | undefined> {
|
||||
if (ty.flags & ts.TypeFlags.Any) {
|
||||
return tokens.dynamicType;
|
||||
}
|
||||
|
@ -557,16 +557,19 @@ export class Transformer {
|
|||
else if (tyre.target === this.builtinArrayType) {
|
||||
// Produce a token of the form "[]<elem>".
|
||||
contract.assert(tyre.typeArguments.length === 1);
|
||||
let elem: tokens.TypeToken | undefined = await this.resolveTypeToken(tyre.typeArguments[0]);
|
||||
let elem: tokens.TypeToken | undefined =
|
||||
await this.resolveTypeToken(node, tyre.typeArguments[0]);
|
||||
contract.assert(!!elem);
|
||||
return `${tokens.arrayTypePrefix}${elem}`;
|
||||
}
|
||||
else if (tyre.target === this.builtinMapType) {
|
||||
// Produce a token of the form "map[<key>]<elem>".
|
||||
contract.assert(tyre.typeArguments.length === 2);
|
||||
let key: tokens.TypeToken | undefined = await this.resolveTypeToken(tyre.typeArguments[0]);
|
||||
let key: tokens.TypeToken | undefined =
|
||||
await this.resolveTypeToken(node, tyre.typeArguments[0]);
|
||||
contract.assert(!!key);
|
||||
let value: tokens.TypeToken | undefined = await this.resolveTypeToken(tyre.typeArguments[1]);
|
||||
let value: tokens.TypeToken | undefined =
|
||||
await this.resolveTypeToken(node, tyre.typeArguments[1]);
|
||||
contract.assert(!!value);
|
||||
return `${tokens.mapTypePrefix}${key}${tokens.mapTypeSeparator}${value}`;
|
||||
}
|
||||
|
@ -577,8 +580,9 @@ export class Transformer {
|
|||
return await this.resolveTokenFromSymbol(ty.symbol);
|
||||
}
|
||||
|
||||
// Finally, if we got here, it's not a type we support yet; issue an error and return `dynamic`.
|
||||
// TODO[marapongo/mu#36]: detect more cases: unions, literals, complex types, generics, more.
|
||||
contract.fail(`Unimplemented ts.Type node: ${ts.TypeFlags[ty.flags]}`);
|
||||
this.diagnostics.push(this.dctx.newInvalidTypeError(node, ty));
|
||||
return tokens.dynamicType;
|
||||
}
|
||||
|
||||
|
@ -619,7 +623,7 @@ export class Transformer {
|
|||
contract.assert(!!ty);
|
||||
return this.withLocation(node, <ast.TypeToken>{
|
||||
kind: ast.typeTokenKind,
|
||||
tok: await this.resolveTypeToken(ty),
|
||||
tok: await this.resolveTypeToken(node, ty),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1325,7 +1329,8 @@ export class Transformer {
|
|||
let returnType: ast.TypeToken | undefined;
|
||||
if (node.kind !== ts.SyntaxKind.Constructor) {
|
||||
let signature: ts.Signature = this.checker().getSignatureFromDeclaration(node);
|
||||
let typeToken: tokens.TypeToken | undefined = await this.resolveTypeToken(signature.getReturnType());
|
||||
let typeToken: tokens.TypeToken | undefined =
|
||||
await this.resolveTypeToken(node, signature.getReturnType());
|
||||
if (typeToken) {
|
||||
returnType = <ast.TypeToken>{
|
||||
kind: ast.typeTokenKind,
|
||||
|
@ -2260,7 +2265,7 @@ export class Transformer {
|
|||
// note that we intentionally leave object blank, since the token is fully qualified.
|
||||
}
|
||||
else {
|
||||
let tytok: tokens.TypeToken | undefined = await this.resolveTypeToken(ty);
|
||||
let tytok: tokens.TypeToken | undefined = await this.resolveTypeToken(node.expression, ty);
|
||||
contract.assert(!!tytok);
|
||||
tok = this.createClassMemberToken(tytok!, id.ident);
|
||||
object = await this.transformExpression(node.expression);
|
||||
|
@ -2280,7 +2285,7 @@ export class Transformer {
|
|||
// To transform the new expression, find the signature TypeScript has bound it to.
|
||||
let signature: ts.Signature = this.checker().getResolvedSignature(node);
|
||||
contract.assert(!!signature);
|
||||
let typeToken: tokens.TypeToken | undefined = await this.resolveTypeToken(signature.getReturnType());
|
||||
let typeToken: tokens.TypeToken | undefined = await this.resolveTypeToken(node, signature.getReturnType());
|
||||
contract.assert(!!typeToken);
|
||||
let args: ast.Expression[] = [];
|
||||
for (let expr of node.arguments) {
|
||||
|
|
|
@ -255,6 +255,22 @@ export class Context {
|
|||
loc: this.locationFrom(node),
|
||||
};
|
||||
}
|
||||
|
||||
public newInvalidTypeError(node: ts.Node, ty: ts.Type): Diagnostic {
|
||||
let name: string;
|
||||
if (ty.symbol) {
|
||||
name = `'${ty.symbol.name}' `;
|
||||
}
|
||||
else {
|
||||
name = "";
|
||||
}
|
||||
return {
|
||||
category: DiagnosticCategory.Error,
|
||||
code: 501,
|
||||
message: `Type ${name}(kind ${ts.TypeFlags[ty.flags]}) is not supported in MuJS`,
|
||||
loc: this.locationFrom(node),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// FormatOptions controls the kind of formatting to apply, such as colorization, extended diagnostics, etc.
|
||||
|
|
Loading…
Reference in a new issue