Exemple #1
0
        /// <summary>
        /// Gets the name of the element.
        /// </summary>
        /// <returns>The name of the element.</returns>
        protected override string GetElementName()
        {
            // For a field, the name of the first variable declarator is the name of the field.
            VariableDeclaratorExpression declarator = this.FindFirstDescendent <VariableDeclaratorExpression>();

            if (declarator != null)
            {
                return(declarator.Identifier.Text);
            }

            throw new SyntaxException(this.Document, this.LineNumber);
        }
        /// <summary>
        /// Reads an expression beginning with two unknown words.
        /// </summary>
        /// <param name="expressionProxy">Proxy object for the expression being created.</param>
        /// <param name="parentProxy">Represents the parent item.</param>
        /// <param name="type">The type of the variable.</param>
        /// <param name="previousPrecedence">The precedence of the previous expression.</param>
        /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param>
        /// <returns>Returns the expression.</returns>
        private VariableDeclarationExpression GetVariableDeclarationExpression(
            CodeUnitProxy expressionProxy, CodeUnitProxy parentProxy, Expression type, ExpressionPrecedence previousPrecedence, bool unsafeCode)
        {
            Param.AssertNotNull(expressionProxy, "expressionProxy");
            Param.AssertNotNull(parentProxy, "parentProxy");
            Param.AssertNotNull(type, "type");
            Param.Ignore(previousPrecedence);
            Param.Ignore(unsafeCode);

            CsLanguageService.Debug.Assert(
                type.ExpressionType == ExpressionType.Literal || 
                type.ExpressionType == ExpressionType.MemberAccess ||
                type.ExpressionType == ExpressionType.QualifiedAlias,
                "The left side of a variable declaration must either be a literal or a member access.");

            VariableDeclarationExpression expression = null;
            if (CheckPrecedence(previousPrecedence, ExpressionPrecedence.None))
            {
                // Move past whitespace, etc, and add it to the expression proxy if we've already started the expression,
                // otherwise add it to the parent.
                this.AdvanceToNextCodeSymbol(expressionProxy.Children.Count > 0 ? expressionProxy : parentProxy);

                // Convert the type expression to a literal type token expression.
                LiteralExpression literalType = null;
                if (type.ExpressionType == ExpressionType.Literal)
                {
                    literalType = (LiteralExpression)type;
                    if (!literalType.Token.Is(TokenType.Type))
                    {
                        literalType = null;
                    }
                }

                if (literalType == null)
                {
                    literalType = this.ConvertTypeExpression(type);
                }

                // Get each declarator.
                while (true)
                {
                    var variableDeclaratorExpressionProxy = new CodeUnitProxy(this.document);

                    // Get the next word.
                    Symbol symbol = this.PeekNextSymbol();
                    if (symbol.SymbolType != SymbolType.Other)
                    {
                        throw this.CreateSyntaxException();
                    }

                    // Get the identifier.
                    LiteralExpression identifier = this.GetLiteralExpression(variableDeclaratorExpressionProxy, unsafeCode);
                    if (identifier == null || identifier.Children.Count == 0)
                    {
                        throw new SyntaxException(this.document, symbol.LineNumber);
                    }

                    // Get the initializer if it exists.
                    Expression initializer = null;

                    symbol = this.PeekNextSymbol();
                    if (symbol.SymbolType == SymbolType.Equals)
                    {
                        // Add the equals token.
                        this.GetOperatorSymbolToken(variableDeclaratorExpressionProxy, OperatorType.Equals);

                        // Check whether this is an array initializer.
                        symbol = this.PeekNextSymbol();

                        if (symbol.SymbolType == SymbolType.OpenCurlyBracket)
                        {
                            initializer = this.GetArrayInitializerExpression(variableDeclaratorExpressionProxy, unsafeCode);
                        }
                        else
                        {
                            initializer = this.GetNextExpression(variableDeclaratorExpressionProxy, ExpressionPrecedence.None, unsafeCode);
                        }
                    }

                    // Create and add the declarator.
                    var declarator = new VariableDeclaratorExpression(variableDeclaratorExpressionProxy, identifier, initializer);
                    expressionProxy.Children.Add(declarator);

                    // Now check if the next character is a comma. If so there is another declarator.
                    symbol = this.PeekNextSymbol();
                    if (symbol.SymbolType != SymbolType.Comma)
                    {
                        // There are no more declarators.
                        break;
                    }

                    // Add the comma.
                    this.GetToken(expressionProxy, TokenType.Comma, SymbolType.Comma);
                }

                // Create the expression.
                expression = new VariableDeclarationExpression(expressionProxy, literalType);
                parentProxy.Children.Add(expression);
            }

            return expression;
        }
        /// <summary>
        /// Parses and returns the declarators for a field.
        /// </summary>
        /// <param name="parentProxy">Represents the parent item.</param>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <param name="fieldType">The field type.</param>
        /// <returns>Returns the name of the first field.</returns>
        private string GetFieldDeclarators(CodeUnitProxy parentProxy, bool unsafeCode, TypeToken fieldType)
        {
            Param.AssertNotNull(parentProxy, "parentProxy");
            Param.Ignore(unsafeCode);
            Param.AssertNotNull(fieldType, "fieldType");

            string firstFieldName = null;
            Symbol symbol = this.PeekNextSymbol();

            while (symbol.SymbolType != SymbolType.Semicolon)
            {
                this.AdvanceToNextCodeSymbol(parentProxy);
                var declaratorProxy = new CodeUnitProxy(this.document);

                // Get the identifier.
                var identifierExpressionProxy = new CodeUnitProxy(this.document);
                Token identifier = this.GetElementNameToken(identifierExpressionProxy, unsafeCode, true);

                var identifierExpression = new LiteralExpression(identifierExpressionProxy, identifier);
                declaratorProxy.Children.Add(identifierExpression);

                if (firstFieldName == null)
                {
                    firstFieldName = identifier.Text;
                }

                Expression initialization = null;

                // Check whether there is an equals sign.
                symbol = this.PeekNextSymbol();
                if (symbol.SymbolType == SymbolType.Equals)
                {
                    this.GetOperatorSymbolToken(declaratorProxy, OperatorType.Equals);

                    // Get the expression after the equals sign. If the expression starts with an
                    // opening curly bracket, then this is an initialization expression or an
                    // anonymous type initialization expression.
                    symbol = this.PeekNextSymbol();
                    if (symbol.SymbolType == SymbolType.OpenCurlyBracket)
                    {
                        // Determine whether this is an array or an anonymous type.
                        if (fieldType.Text == "var" || (
                            fieldType.Text != "Array" && fieldType.Text != "System.Array" && !fieldType.Text.Contains("[")))
                        {
                            initialization = this.GetAnonymousTypeInitializerExpression(declaratorProxy, unsafeCode);
                        }
                        else
                        {
                            initialization = this.GetArrayInitializerExpression(declaratorProxy, unsafeCode);
                        }
                    }
                    else
                    {
                        initialization = this.GetNextExpression(declaratorProxy, ExpressionPrecedence.None, unsafeCode);
                    }

                    if (initialization == null)
                    {
                        throw this.CreateSyntaxException();
                    }
                }

                var declaratorExpression = new VariableDeclaratorExpression(declaratorProxy, identifierExpression, initialization);

                parentProxy.Children.Add(declaratorExpression);

                // If the next symbol is a comma, continue.
                symbol = this.PeekNextSymbol();
                if (symbol.SymbolType == SymbolType.Comma)
                {
                    this.GetToken(parentProxy, TokenType.Comma, SymbolType.Comma);
                    symbol = this.PeekNextSymbol();
                }
            }

            // Return the declarators as a read-only collection.
            return firstFieldName;
        }