fix return type check

This commit is contained in:
Dave Holoway
2020-06-22 19:52:13 +01:00
parent 56464ef537
commit 085f027856

View File

@@ -1,6 +1,7 @@
/** /**
* @typedef {import('../body-types').ResolvedIdent} ResolvedIdent * @typedef {import('../body-types').ResolvedIdent} ResolvedIdent
* @typedef {import('../body-types').ValidateInfo} ValidateInfo * @typedef {import('../body-types').ValidateInfo} ValidateInfo
* @typedef {import('../body-types').ResolvedValue} ResolvedValue
* @typedef {import('../tokenizer').Token} Token * @typedef {import('../tokenizer').Token} Token
*/ */
const { JavaType, PrimitiveType } = require('java-mti'); const { JavaType, PrimitiveType } = require('java-mti');
@@ -8,7 +9,7 @@ const { Statement } = require("./Statement");
const ParseProblem = require('../parsetypes/parse-problem'); const ParseProblem = require('../parsetypes/parse-problem');
const { isTypeAssignable } = require('../expression-resolver'); const { isTypeAssignable } = require('../expression-resolver');
const { NumberLiteral } = require('../expressiontypes/literals/Number'); const { NumberLiteral } = require('../expressiontypes/literals/Number');
const { MultiValueType } = require('../anys'); const { LambdaType, MultiValueType } = require('../anys');
class ReturnStatement extends Statement { class ReturnStatement extends Statement {
/** @type {ResolvedIdent} */ /** @type {ResolvedIdent} */
@@ -38,19 +39,27 @@ class ReturnStatement extends Statement {
return; return;
} }
const type = this.expression.resolveExpression(vi); const type = this.expression.resolveExpression(vi);
checkType(type); checkType(type, () => this.expression.tokens);
function checkType(type) { /**
* @param {ResolvedValue} type
* @param {() => Token[]} tokens
*/
function checkType(type, tokens) {
if (type instanceof JavaType || type instanceof NumberLiteral) { if (type instanceof JavaType || type instanceof NumberLiteral) {
if (!isTypeAssignable(method_return_type, type)) { if (!isTypeAssignable(method_return_type, type)) {
const expr_type = type instanceof NumberLiteral ? type.type : type; const expr_type = type instanceof NumberLiteral ? type.type : type;
vi.problems.push(ParseProblem.Error(this.expression.tokens, `Incompatible types: expression of type '${expr_type.fullyDottedTypeName}' cannot be returned from a method of type '${method_return_type.fullyDottedTypeName}'`)); vi.problems.push(ParseProblem.Error(tokens(), `Incompatible types: expression of type '${expr_type.fullyDottedTypeName}' cannot be returned from a method of type '${method_return_type.fullyDottedTypeName}'`));
} }
} else if (type instanceof MultiValueType) { } else if (type instanceof MultiValueType) {
// ternary, eg. return x > 0 ? 1 : 2; // ternary, eg. return x > 0 ? 1 : 2;
type.types.forEach(type => checkType(type)); type.types.forEach(type => checkType(type, tokens));
} else if (type instanceof LambdaType) {
if (!isTypeAssignable(method_return_type, type)) {
vi.problems.push(ParseProblem.Error(tokens(), `Incompatible types: lambda expression is not compatible with method type '${method_return_type.fullyDottedTypeName}'`));
}
} else { } else {
vi.problems.push(ParseProblem.Error(this.expression.tokens, `'${method_return_type.fullyDottedTypeName}' type expression expected`)); vi.problems.push(ParseProblem.Error(tokens(), `'${method_return_type.fullyDottedTypeName}' type expression expected`));
} }
} }
} }