Exemple #1
0
        public void VisitVariableDefinition(VariableDefinition variableDefinition)
        {
            if (variableDefinition.TypeSignature != null && variableDefinition.Initializer != null)
            {
                var variableType = TypeSignatureParser.ParseTypeSignature(
                    _context,
                    variableDefinition.TypeSignature);

                if (!ExpressionAnalyzer.IsExpressionValid(
                        _context,
                        _currentScope,
                        variableDefinition.Initializer))
                {
                    return;
                }

                var initializerType = Typer.GetExpressionType(
                    _context,
                    _currentScope,
                    variableDefinition.Initializer);

                if (variableType != null && !variableType.IsSame(initializerType))
                {
                    // We made sure in the StatementParser that a definition without both initializer
                    // and type signature is not a valid AST item and discarded it with an error.
                    Debug.Assert(variableDefinition.Initializer != null);
                    _context.Error(
                        variableDefinition.Initializer.Span,
                        $"expected type \"{variableType}\", but found \"{initializerType}\"");
                }

                _astContext.AddNodeType(variableDefinition.NodeId, variableType);
            }
            else if (variableDefinition.TypeSignature != null &&
                     variableDefinition.Initializer == null)
            {
                var variableType =
                    TypeSignatureParser.ParseTypeSignature(
                        _context,
                        variableDefinition.TypeSignature);

                _astContext.AddNodeType(variableDefinition.NodeId, variableType);
            }
            else // variableDefinition.TypeSignature == null && variableDefinition.Initializer != null
            {
                if (!ExpressionAnalyzer.IsExpressionValid(
                        _context,
                        _currentScope,
                        variableDefinition.Initializer))
                {
                    return;
                }

                var initializerType = Typer.GetExpressionType(
                    _context,
                    _currentScope,
                    variableDefinition.Initializer);
                switch (initializerType)
                {
                case VoidType _:
                    // Again, the linter is overly sensitive. There's no way for the Initializer
                    // field to be null at this point.
                    Debug.Assert(variableDefinition.Initializer != null);
                    _context.Error(
                        variableDefinition.Initializer.Span,
                        "type \"void\" cannot be assigned to a variable");
                    break;

                case null:
                    return;

                default:
                    _astContext.AddNodeType(variableDefinition.NodeId, initializerType);
                    break;
                }
            }

            if (!_currentScope.DefineSymbol(
                    variableDefinition,
                    _astContext.GetNodeType(variableDefinition.NodeId)))
            {
                _context.Error(
                    variableDefinition.Span,
                    $"redefined previously defined symbol \"{variableDefinition.Identifier}\"");
            }
        }
Exemple #2
0
        public static IType ParseTypeSignature(Context context, ITypeSignature typeSignature)
        {
            var self = new TypeSignatureParser(context);

            return(typeSignature.Accept(self));
        }