diff --git a/langserver/java/statementtypes/ReturnStatement.js b/langserver/java/statementtypes/ReturnStatement.js index 72a4939..561cf2e 100644 --- a/langserver/java/statementtypes/ReturnStatement.js +++ b/langserver/java/statementtypes/ReturnStatement.js @@ -1,6 +1,7 @@ /** * @typedef {import('../body-types').ResolvedIdent} ResolvedIdent * @typedef {import('../body-types').ValidateInfo} ValidateInfo + * @typedef {import('../body-types').ResolvedValue} ResolvedValue * @typedef {import('../tokenizer').Token} Token */ const { JavaType, PrimitiveType } = require('java-mti'); @@ -8,7 +9,7 @@ const { Statement } = require("./Statement"); const ParseProblem = require('../parsetypes/parse-problem'); const { isTypeAssignable } = require('../expression-resolver'); const { NumberLiteral } = require('../expressiontypes/literals/Number'); -const { MultiValueType } = require('../anys'); +const { LambdaType, MultiValueType } = require('../anys'); class ReturnStatement extends Statement { /** @type {ResolvedIdent} */ @@ -38,19 +39,27 @@ class ReturnStatement extends Statement { return; } 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 (!isTypeAssignable(method_return_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) { // 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 { - 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`)); } } }