/// <summary> /// Gets an object initializer expression. /// </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 expression.</returns> private ObjectInitializerExpression GetObjectInitializerExpression(CodeUnitProxy parentProxy, bool unsafeCode) { Param.AssertNotNull(parentProxy, "parentProxy"); Param.Ignore(unsafeCode); this.AdvanceToNextCodeSymbol(parentProxy); var expressionProxy = new CodeUnitProxy(this.document); var initializerExpressions = new List<EqualsExpression>(); // Add and move past the opening curly bracket. BracketToken openingBracket = (BracketToken)this.GetToken(expressionProxy, TokenType.OpenCurlyBracket, SymbolType.OpenCurlyBracket); while (true) { // If the next symbol is the closing curly bracket, then we are done. Symbol symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.CloseCurlyBracket) { break; } var initializerExpressionProxy = new CodeUnitProxy(this.document); // Get the identifier. this.AdvanceToNextCodeSymbol(expressionProxy); LiteralExpression identifier = this.GetLiteralExpression(initializerExpressionProxy, unsafeCode); // Get the equals sign. symbol = this.PeekNextSymbol(); if (symbol.SymbolType != SymbolType.Equals) { throw this.CreateSyntaxException(); } this.GetOperatorSymbolToken(initializerExpressionProxy, OperatorType.Equals); // Get the initializer value. If this begins with an opening curly bracket, // this is an embedded object or collection initializer. Otherwise, it is // some other kind of expression. Expression initializerValue = null; symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.OpenCurlyBracket) { initializerValue = this.GetObjectOrCollectionInitializerExpression(initializerExpressionProxy, unsafeCode); } else { initializerValue = this.GetNextExpression(initializerExpressionProxy, ExpressionPrecedence.None, unsafeCode); } // Create and add this initializer. var initializerExpression = new EqualsExpression(initializerExpressionProxy, identifier, initializerValue); expressionProxy.Children.Add(initializerExpression); initializerExpressions.Add(initializerExpression); // Check whether we're done. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Comma) { this.GetToken(expressionProxy, TokenType.Comma, SymbolType.Comma); // If the next symbol after this is the closing curly bracket, then we are done. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.CloseCurlyBracket) { break; } } else { break; } } // Add and move past the closing curly bracket. BracketToken closingBracket = (BracketToken)this.GetToken(expressionProxy, TokenType.CloseCurlyBracket, SymbolType.CloseCurlyBracket); openingBracket.MatchingBracket = closingBracket; closingBracket.MatchingBracket = openingBracket; // Create and return the expression. var expression = new ObjectInitializerExpression(expressionProxy, initializerExpressions.AsReadOnly()); parentProxy.Children.Add(expression); return expression; }
/// <summary> /// Reads an assignment expression. /// </summary> /// <param name="expressionProxy">Proxy object for the expression being created.</param> /// <param name="leftHandSide">The expression on the left hand side of the operator.</param> /// <param name="previousPrecedence">The precedence of the expression just before this one.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <returns>Returns the expression.</returns> private AssignmentExpression GetAssignmentExpression( CodeUnitProxy expressionProxy, Expression leftHandSide, ExpressionPrecedence previousPrecedence, bool unsafeCode) { Param.AssertNotNull(expressionProxy, "expressionProxy"); Param.AssertNotNull(leftHandSide, "leftHandSide"); Param.Ignore(previousPrecedence); Param.Ignore(unsafeCode); AssignmentExpression expression = null; // Read the details of the expression. OperatorSymbolToken operatorToken = this.PeekOperatorSymbolToken(); CsLanguageService.Debug.Assert(operatorToken.Category == OperatorCategory.Assignment, "Expected an assignment operator"); // Check the precedence of the operators to make sure we can gather this statement now. ExpressionPrecedence precedence = GetOperatorPrecedence(operatorToken.SymbolType); if (CheckPrecedence(previousPrecedence, precedence)) { // Create the operator toke again and save it. operatorToken = this.GetOperatorSymbolToken(expressionProxy); // Get the expression on the right-hand side of the operator. Expression rightHandSide = this.GetOperatorRightHandExpression(expressionProxy, precedence, unsafeCode); // Get the expression operator type. switch (operatorToken.SymbolType) { case OperatorType.Equals: expression = new EqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.PlusEquals: expression = new PlusEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.MinusEquals: expression = new MinusEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.MultiplicationEquals: expression = new MultiplicationEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.DivisionEquals: expression = new DivisionEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.AndEquals: expression = new AndEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.OrEquals: expression = new OrEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.XorEquals: expression = new XorEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.ModEquals: expression = new ModEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.LeftShiftEquals: expression = new LeftShiftEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; case OperatorType.RightShiftEquals: expression = new RightShiftEqualsExpression(expressionProxy, leftHandSide, rightHandSide); break; default: CsLanguageService.Debug.Fail("Unexpected operator type"); throw new InvalidOperationException(); } } return expression; }