Ejemplo n.º 1
0
        public override void ExitReturnStatement(ReturnStatement returnStatement)
        {
            var ancestor = returnStatement.NearestAncestorOfAnyType(typeof(MethodDeclaration), typeof(LambdaExpression), typeof(GetterDeclaration));

            if (ancestor is INamedDeclaration namedDeclaration)
            {
                ITypeNode returnType = null;
                switch (namedDeclaration)
                {
                case MethodDeclaration methodDeclaration:
                    returnType = methodDeclaration.ReturnType;
                    break;

                case GetterDeclaration getterDeclaration:
                    returnType = getterDeclaration.ReturnType;
                    break;
                }
                var returnStatementType = returnStatement?.Value.Type ?? new VoidType(returnStatement.Context);
                if (returnType != null)
                {
                    if (!returnStatementType.IsAssignableTo(returnType))
                    {
                        Errors.Add(new CompilationError(returnStatement.Context, $"{returnStatementType} is not assignable to the return type of the method: {returnType}."));
                    }
                }
                else if (!(returnStatementType is ITypeNode returnStatementTypeNode))
                {
                    Errors.Add(new CompilationError(returnStatement.Context, $"Invalid return value: {returnStatementType}"));
                }
                else
                {
                    var typeList = inferredMethodTypes[namedDeclaration];
                    if (!typeList.Any(x => x.IsEquivalentTo(returnStatementType)))
                    {
                        typeList.Add(returnStatementTypeNode);
                    }
                }
            }