Пример #1
0
        /// <summary>
        /// Initializes a new instance of the TypeofExpression class.
        /// </summary>
        /// <param name="proxy">Proxy object for the expression.</param>
        /// <param name="type">The type literal to get the type of.</param>
        internal TypeofExpression(CodeUnitProxy proxy, LiteralExpression type)
            : base(proxy, ExpressionType.Typeof)
        {
            Param.AssertNotNull(proxy, "proxy");
            Param.AssertNotNull(type, "type");

            this.type.Value = CodeParser.ExtractTypeTokenFromLiteralExpression(type);
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the LabelStatement class.
        /// </summary>
        /// <param name="proxy">Proxy object for the statement.</param>
        /// <param name="identifier">The label identifier.</param>
        internal LabelStatement(CodeUnitProxy proxy, LiteralExpression identifier)
            : base(proxy, StatementType.Label)
        {
            Param.AssertNotNull(proxy, "proxy");
            Param.AssertNotNull(identifier, "identifier");

            this.identifier.Value = identifier;
        }
Пример #3
0
        /// <summary>
        /// Initializes a new instance of the CastExpression class.
        /// </summary>
        /// <param name="proxy">Proxy object for the expression.</param>
        /// <param name="type">The cast type.</param>
        /// <param name="castedExpression">The expression being casted.</param>
        internal CastExpression(CodeUnitProxy proxy, LiteralExpression type, Expression castedExpression)
            : base(proxy, ExpressionType.Cast)
        {
            Param.AssertNotNull(proxy, "proxy");
            Param.AssertNotNull(type, "type");
            Param.AssertNotNull(castedExpression, "castedExpression");

            this.type.Value = CodeParser.ExtractTypeTokenFromLiteralExpression(type);
            this.castedExpression.Value = castedExpression;
        }
        /// <summary>
        /// Initializes a new instance of the VariableDeclaratorExpression class.
        /// </summary>
        /// <param name="proxy">Proxy object for the expression.</param>
        /// <param name="identifier">The identifier name of the variable.</param>
        /// <param name="initializer">The initialization expression for the variable.</param>
        internal VariableDeclaratorExpression(CodeUnitProxy proxy, LiteralExpression identifier, Expression initializer)
            : base(proxy, ExpressionType.VariableDeclarator)
        {
            Param.AssertNotNull(proxy, "proxy");
            Param.AssertNotNull(identifier, "identifier");
            Param.Ignore(initializer);

            this.identifier.Value = identifier;
            this.initializer.Value = initializer;
        }
Пример #5
0
        /// <summary>
        /// Initializes a new instance of the AttributeExpression class.
        /// </summary>
        /// <param name="proxy">Proxy object for the expression.</param>
        /// <param name="target">The attribute target, if any.</param>
        /// <param name="initialization">The attribute initialization call.</param>
        internal AttributeExpression(CodeUnitProxy proxy, LiteralExpression target, Expression initialization)
            : base(proxy, ExpressionType.Attribute)
        {
            Param.AssertNotNull(proxy, "proxy");
            Param.Ignore(target);
            Param.AssertNotNull(initialization, "initialization");

            this.target.Value = target;
            this.initialization.Value = initialization;
        }
Пример #6
0
        /// <summary>
        /// Initializes a new instance of the AsExpression class.
        /// </summary>
        /// <param name="proxy">Proxy object for the expression.</param>
        /// <param name="value">The value to convert.</param>
        /// <param name="type">The type of the conversion.</param>
        internal AsExpression(CodeUnitProxy proxy, Expression value, LiteralExpression type)
            : base(proxy, ExpressionType.As)
        {
            Param.AssertNotNull(proxy, "proxy");
            Param.AssertNotNull(value, "value");
            Param.AssertNotNull(type, "type");

            this.value.Value = value;
            this.type.Value = CodeParser.ExtractTypeTokenFromLiteralExpression(type);
        }
        /// <summary>
        /// Initializes a new instance of the VariableDeclarationExpression class.
        /// </summary>
        /// <param name="proxy">Proxy object for the expression.</param>
        /// <param name="type">The type of the variable or variables being declared.</param>
        /// <param name="declarators">The collection of declarators on the expression.</param>
        internal VariableDeclarationExpression(CodeUnitProxy proxy, LiteralExpression type, ICollection<VariableDeclaratorExpression> declarators = null)
            : base(proxy, ExpressionType.VariableDeclaration)
        {
            Param.AssertNotNull(proxy, "proxy");
            Param.AssertNotNull(type, "type");
            Param.Ignore(declarators);

            this.type.Value = CodeParser.ExtractTypeTokenFromLiteralExpression(type);

            if (declarators != null && declarators.Count > 0)
            {
                this.declarators.Value = new List<VariableDeclaratorExpression>(declarators);
            }
        }
Пример #8
0
        /// <summary>
        /// Initializes a new instance of the ChildAccessExpression class.
        /// </summary>
        /// <param name="proxy">Proxy object for the expression.</param>
        /// <param name="type">The type of operation being performed.</param>
        /// <param name="leftHandSide">The left side of the operation.</param>
        /// <param name="rightHandSide">The member being accessed.</param>
        internal ChildAccessExpression(
            CodeUnitProxy proxy,
            ExpressionType type,
            Expression leftHandSide, 
            LiteralExpression rightHandSide)
            : base(proxy, (int)type)
        {
            Param.AssertNotNull(proxy, "proxy");
            Param.Ignore(type);
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.AssertNotNull(rightHandSide, "rightHandSide");

            this.leftHandSide.Value = leftHandSide;
            this.rightHandSide.Value = rightHandSide;
        }
        /// <summary>
        /// Reads an expression starting with an unknown word.
        /// </summary>
        /// <param name="parentProxy">Represents the parent item.</param>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <returns>Returns the expression.</returns>
        private LiteralExpression GetLiteralExpression(CodeUnitProxy parentProxy, bool unsafeCode)
        {
            Param.AssertNotNull(parentProxy, "parentProxy");
            Param.Ignore(unsafeCode);

            // Get the first symbol.
            this.AdvanceToNextCodeSymbol(parentProxy);
            Symbol symbol = this.PeekNextSymbol();

            var expressionProxy = new CodeUnitProxy(this.document);

            // First, check if this is a generic.
            Token literalToken = null;
            int temp;
            bool generic = false;
            if (symbol.SymbolType == SymbolType.Other && this.HasTypeSignature(1, false, out temp, out generic) && generic)
            {
                literalToken = this.GetGenericToken(expressionProxy, unsafeCode);
            }

            if (literalToken == null)
            {
                // This is not a generic. Just convert the symbol to a token.
                literalToken = this.GetToken(expressionProxy, TokenType.Literal, SymbolType.Other);
            }

            // Create a literal expression from this token.
            var literal = new LiteralExpression(expressionProxy, literalToken);
            parentProxy.Children.Add(literal);

            return literal;
        }
Пример #10
0
        /// <summary>
        /// Gets a token representing a type identifier.
        /// </summary>
        /// <param name="parentProxy">Represents the parent item.</param>
        /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param>
        /// <param name="includeArrayBrackets">Indicates whether to include array brackets in the type token.</param>
        /// <param name="isExpression">Indicates whether this type token comes at the end of an 'is' expression.</param>
        /// <returns>Returns the token.</returns>
        private LiteralExpression GetTypeTokenExpression(CodeUnitProxy parentProxy, bool unsafeCode, bool includeArrayBrackets, bool isExpression)
        {
            Param.AssertNotNull(parentProxy, "parentProxy");
            Param.Ignore(unsafeCode);
            Param.Ignore(includeArrayBrackets);
            Param.Ignore(isExpression);

            this.AdvanceToNextCodeSymbol(parentProxy);
            var expressionProxy = new CodeUnitProxy(this.document);

            TypeToken token = this.GetTypeToken(expressionProxy, unsafeCode, includeArrayBrackets, isExpression);

            // Create and return the literal expression.
            var expression = new LiteralExpression(expressionProxy, token);
            parentProxy.Children.Add(expression);

            return expression;
        }
Пример #11
0
        /// <summary>
        /// Parses and returns a constructor.
        /// </summary>
        /// <param name="elementProxy">Proxy for the element being created.</param>
        /// <param name="parent">The parent of the element.</param>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <param name="generated">Indicates whether the code is marked as generated code.</param>
        /// <param name="attributes">The attributes on the element.</param>
        /// <returns>Returns the element.</returns>
        private Constructor GetConstructor(CodeUnitProxy elementProxy, Element parent, bool unsafeCode, bool generated, ICollection<Attribute> attributes)
        {
            Param.AssertNotNull(elementProxy, "elementProxy");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);
            Param.Ignore(attributes);

            // Get the modifiers and access.
            AccessModifierType accessModifier = AccessModifierType.Private;
            Dictionary<TokenType, Token> modifiers = this.GetElementModifiers(elementProxy, ref accessModifier, ConstructorModifiers);

            unsafeCode |= modifiers.ContainsKey(TokenType.Unsafe);

            // Get the name of the constructor.
            Token name = this.GetElementNameToken(elementProxy, unsafeCode);

            // Get the parameter list.
            this.GetParameterList(elementProxy, unsafeCode, SymbolType.OpenParenthesis);

            // Get the constructor initializer if there is one.
            ConstructorInitializerStatement constructorInitializerStatement = null;

            Symbol symbol = this.PeekNextSymbol();
            if (symbol.SymbolType == SymbolType.Colon)
            {
                this.GetToken(elementProxy, TokenType.BaseColon, SymbolType.Colon);

                var constructorInitializerStatementProxy = new CodeUnitProxy(this.document);
                var constructorInitializerExpressionProxy = new CodeUnitProxy(this.document);

                // The next symbol must be the keyword base or this.
                symbol = this.PeekNextSymbol();
                if (symbol.SymbolType != SymbolType.This && symbol.SymbolType != SymbolType.Base)
                {
                    throw this.CreateSyntaxException();
                }

                var initializerNameExpressionProxy = new CodeUnitProxy(this.document);
                Token initializerNameToken = this.GetToken(initializerNameExpressionProxy, TokenType.Literal, symbol.SymbolType);

                // Get the name expression.
                var initializerNameExpression = new LiteralExpression(initializerNameExpressionProxy, initializerNameToken);
                constructorInitializerExpressionProxy.Children.Add(initializerNameExpression);

                // Get the initializer expression.
                var constructorInitializerExpression = this.GetMethodInvocationExpression(constructorInitializerExpressionProxy, initializerNameExpression, ExpressionPrecedence.None, unsafeCode);
                constructorInitializerStatementProxy.Children.Add(constructorInitializerExpression);

                // Create the constructor initializer statement
                constructorInitializerStatement = new ConstructorInitializerStatement(constructorInitializerStatementProxy, constructorInitializerExpression);
                elementProxy.Children.Add(constructorInitializerStatement);
            }

            var constructor = new Constructor(elementProxy, name.Text, attributes, unsafeCode);

            // If the constructor is extern, it will not have a body.
            if (modifiers.ContainsKey(TokenType.Extern))
            {
                // Get the closing semicolon.
                this.GetToken(elementProxy, TokenType.Semicolon, SymbolType.Semicolon);
            }
            else
            {
                // Get the body.
                this.ParseStatementContainer(elementProxy, constructor, true, unsafeCode);
            }

            return constructor;
        }
Пример #12
0
        /// <summary>
        /// Parses and returns a field.
        /// </summary>
        /// <param name="elementProxy">Proxy for the element being created.</param>
        /// <param name="parent">The parent of the element.</param>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <param name="generated">Indicates whether the code is marked as generated code.</param>
        /// <param name="attributes">The attributes on the element.</param>
        /// <returns>Returns the element.</returns>
        private Field GetField(CodeUnitProxy elementProxy, Element parent, bool unsafeCode, bool generated, ICollection<Attribute> attributes)
        {
            Param.AssertNotNull(elementProxy, "elementProxy");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);
            Param.Ignore(attributes);

            // Get the modifiers and access.
            AccessModifierType accessModifier = AccessModifierType.Private;
            Dictionary<TokenType, Token> modifiers = this.GetElementModifiers(elementProxy, ref accessModifier, FieldModifiers);

            unsafeCode |= modifiers.ContainsKey(TokenType.Unsafe);

            var declarationExpressionProxy = new CodeUnitProxy(this.document);

            // Get the field type.
            var fieldTypeExpressionProxy = new CodeUnitProxy(this.document);
            TypeToken fieldType = this.GetTypeToken(fieldTypeExpressionProxy, unsafeCode, true);
            var fieldTypeExpression = new LiteralExpression(fieldTypeExpressionProxy, fieldType);
            declarationExpressionProxy.Children.Add(fieldTypeExpression);

            // Get all of the variable declarators.
            string firstFieldName = this.GetFieldDeclarators(declarationExpressionProxy, unsafeCode, fieldType);

            if (string.IsNullOrWhiteSpace(firstFieldName))
            {
                throw this.CreateSyntaxException();
            }

            var variableDeclarationStatementProxy = new CodeUnitProxy(this.document);
            var declarationExpression = new VariableDeclarationExpression(declarationExpressionProxy, fieldTypeExpression);
            variableDeclarationStatementProxy.Children.Add(declarationExpression);

            var variableDeclarationStatement = new VariableDeclarationStatement(variableDeclarationStatementProxy, declarationExpression);
            elementProxy.Children.Add(variableDeclarationStatement);

            var field = new Field(elementProxy, firstFieldName, attributes, fieldType, unsafeCode);

            // Get the trailing semicolon.
            this.GetToken(elementProxy, TokenType.Semicolon, SymbolType.Semicolon);

            return field;
        }
        /// <summary>
        /// Creates a new token and adds it to a new literal expression.
        /// </summary>
        /// <param name="parentProxy">Represents the parent item.</param>
        /// <param name="symbolType">The type of the symbol.</param>
        /// <param name="tokenType">The type of the token.</param>
        /// <returns>Returns the literal expression.</returns>
        private LiteralExpression CreateLiteralExpression(CodeUnitProxy parentProxy, SymbolType symbolType, TokenType tokenType)
        {
            Param.AssertNotNull(parentProxy, "parentProxy");
            Param.Ignore(symbolType, tokenType);

            this.AdvanceToNextCodeSymbol(parentProxy);
            var expressionProxy = new CodeUnitProxy(this.document);

            Token token = this.GetToken(expressionProxy, tokenType, symbolType);

            var expression = new LiteralExpression(expressionProxy, token);
            parentProxy.Children.Add(expression);

            return expression;
        }
Пример #14
0
        /// <summary>
        /// Reads the next goto-statement from the file and returns it.
        /// </summary>
        /// <param name="parentProxy">Represents the parent item.</param>
        /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param>
        /// <returns>Returns the statement.</returns>
        private GotoStatement GetGotoStatement(CodeUnitProxy parentProxy, bool unsafeCode)
        {
            Param.Ignore(unsafeCode);
            Param.AssertNotNull(parentProxy, "parentProxy");

            var statementProxy = new CodeUnitProxy(this.document);
            
            // Move past the goto keyword.
            this.GetToken(statementProxy, TokenType.Goto, SymbolType.Goto);

            // Get the next symbol.
            Symbol symbol = this.PeekNextSymbol();

            Expression identifier = null;
            if (symbol.SymbolType == SymbolType.Default)
            {
                CodeUnitProxy identifierProxy = new CodeUnitProxy(this.document);
                Token token = this.GetToken(identifierProxy, TokenType.Literal, SymbolType.Default);
                identifier = new LiteralExpression(identifierProxy, token);
                statementProxy.Children.Add(identifier);
            }
            else if (symbol.SymbolType == SymbolType.Case)
            {
                this.GetToken(statementProxy, TokenType.Literal, SymbolType.Case);
                identifier = this.GetNextExpression(statementProxy, ExpressionPrecedence.None, unsafeCode);
            }
            else
            {
                identifier = this.GetNextExpression(statementProxy, ExpressionPrecedence.None, unsafeCode);
            }

            // Get the closing semicolon.
            this.GetToken(statementProxy, TokenType.Semicolon, SymbolType.Semicolon);

            // Create and return the goto-statement.
            var statement = new GotoStatement(statementProxy, identifier);
            parentProxy.Children.Add(statement);

            return statement;
        }
Пример #15
0
        /// <summary>
        /// Parses and returns the declarators for an event.
        /// </summary>
        /// <param name="parentProxy">Represents the parent item.</param>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <param name="eventHandlerType">The event type.</param>
        /// <returns>Returns the name of the first event.</returns>
        private string GetEventDeclarators(CodeUnitProxy parentProxy, bool unsafeCode, TypeToken eventHandlerType)
        {
            Param.AssertNotNull(parentProxy, "parentProxy");
            Param.Ignore(unsafeCode);
            Param.AssertNotNull(eventHandlerType, "eventHandlerType");

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

            while (symbol.SymbolType != SymbolType.Semicolon && symbol.SymbolType != SymbolType.OpenCurlyBracket)
            {
                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);

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

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

                Expression initialization = null;

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

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

                var declaratorExpression = new EventDeclaratorExpression(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 firstEventName;
        }
Пример #16
0
        /// <summary>
        /// Parses and returns a event.
        /// </summary>
        /// <param name="elementProxy">Proxy for the element being created.</param>
        /// <param name="parent">The parent of the element.</param>
        /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param>
        /// <param name="generated">Indicates whether the code is marked as generated code.</param>
        /// <param name="attributes">The attributes on the element.</param>
        /// <returns>Returns the element.</returns>
        private Event GetEvent(CodeUnitProxy elementProxy, Element parent, bool unsafeCode, bool generated, ICollection<Attribute> attributes)
        {
            Param.AssertNotNull(elementProxy, "elementProxy");
            Param.AssertNotNull(parent, "parent");
            Param.Ignore(unsafeCode);
            Param.Ignore(generated);
            Param.Ignore(attributes);

            // Get the modifiers and access.
            AccessModifierType accessModifier = AccessModifierType.Private;

            // Events within interfaces always have the access of the parent interface.
            Interface parentInterface = parent as Interface;
            if (parentInterface != null)
            {
                accessModifier = parentInterface.AccessModifierType;
            }

            // Get declared modifiers.
            Dictionary<TokenType, Token> modifiers = this.GetElementModifiers(elementProxy, ref accessModifier, EventModifiers);
            unsafeCode |= modifiers.ContainsKey(TokenType.Unsafe);

            // Get the event keyword.
            this.GetToken(elementProxy, TokenType.Event, SymbolType.Event);

            // Get the event type.
            var eventHandlerTypeExpressionProxy = new CodeUnitProxy(this.document);
            TypeToken eventHandlerType = this.GetTypeToken(eventHandlerTypeExpressionProxy, unsafeCode, true);
            var eventHandlerTypeExpression = new LiteralExpression(eventHandlerTypeExpressionProxy, eventHandlerType);
            elementProxy.Children.Add(eventHandlerTypeExpression);

            // Get all of the event declarators.
            string firstEventName = this.GetEventDeclarators(elementProxy, unsafeCode, eventHandlerType);

            if (string.IsNullOrWhiteSpace(firstEventName))
            {
                throw this.CreateSyntaxException();
            }

            Event @event = new Event(elementProxy, firstEventName, attributes, eventHandlerType, unsafeCode);

            Symbol symbol = this.PeekNextSymbol();

            if (symbol.SymbolType == SymbolType.Semicolon)
            {
                this.GetToken(elementProxy, TokenType.Semicolon, SymbolType.Semicolon);
            }
            else
            {
                // Parse the body of the event.
                this.ParseElementContainer(elementProxy, @event, unsafeCode);
            }

            return @event;
        }
Пример #17
0
        /// <summary>
        /// Extracts a TypeToken from the literal expression, assuming that one exists.
        /// </summary>
        /// <param name="literal">The literal expression.</param>
        /// <returns>Returns the type token.</returns>
        internal static TypeToken ExtractTypeTokenFromLiteralExpression(LiteralExpression literal)
        {
            Param.AssertNotNull(literal, "literal");

            TypeToken type = literal.Token as TypeToken;
            if (type == null)
            {
                throw new SyntaxException(literal.Document, literal.LineNumber, Strings.LiteralExpressionDoesNotContainTypeToken);
            }

            return type;
        }
        /// <summary>
        /// Reads an expression starting with an unknown word.
        /// </summary>
        /// <param name="parentProxy">Proxy object for the parent item.</param>
        /// <returns>Returns the expression.</returns>
        private LiteralExpression GetConditionalPreprocessorConstantExpression(CodeUnitProxy parentProxy)
        {
            Param.AssertNotNull(parentProxy, "parentProxy");

            this.AdvanceToNextConditionalDirectiveCodeSymbol(parentProxy);
            var expressionProxy = new CodeUnitProxy(this.document);

            // Get the first symbol.
            Symbol symbol = this.symbols.Peek(1);
            CsLanguageService.Debug.Assert(symbol != null && symbol.SymbolType == SymbolType.Other, "Expected a text symbol");

            // Convert the symbol to a token.
            this.symbols.Advance();

            var literalToken = new LiteralToken(this.document, symbol.Text, symbol.Location, this.symbols.Generated);
            expressionProxy.Children.Add(literalToken);

            // Create a literal expression from this token.
            var literalExpression = new LiteralExpression(expressionProxy, literalToken);
            parentProxy.Children.Add(literalExpression);

            return literalExpression;
        }
Пример #19
0
        /// <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;
        }