/// <summary> /// Reads a null condition expression from the code. /// </summary> /// <param name="leftHandSide">The left hand side.</param> /// <param name="previousPrecedence">The previous precedence.</param> /// <param name="parentReference">The parent code unit.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <returns> /// Returns the expression. /// </returns> private Expression GetNullConditionExpression( Expression leftHandSide, ExpressionPrecedence previousPrecedence, Reference<ICodePart> parentReference, bool unsafeCode) { Param.AssertNotNull(leftHandSide, "leftHandSide"); Param.Ignore(previousPrecedence); Param.AssertNotNull(parentReference, "parentReference"); Param.Ignore(unsafeCode); NullConditionExpression expression = null; Reference<ICodePart> expressionReference = new Reference<ICodePart>(); // Read the details of the expression. OperatorSymbol operatorToken = this.PeekOperatorToken(parentReference, expressionReference); Debug.Assert(operatorToken.SymbolType == OperatorType.NullConditional, "Expected a null-conditional symbol"); // Check the precedence of the operators to make sure we can gather this statement now. ExpressionPrecedence precedence = GetOperatorPrecedence(operatorToken.SymbolType); if (CheckPrecedence(previousPrecedence, precedence)) { // Add the operator token to the document and advance the symbol manager up to it. this.symbols.Advance(); this.tokens.Add(operatorToken); Expression rightHandSide = null; Symbol nextSymbol = this.symbols.Peek(1); // Check if next symbol is an open square bracket. if (nextSymbol.SymbolType == SymbolType.OpenSquareBracket) { rightHandSide = this.GetArrayAccessExpression(leftHandSide, previousPrecedence, unsafeCode); } else { rightHandSide = this.GetOperatorRightHandExpression(precedence, expressionReference, unsafeCode); } // We must find an expression else there is a syntax exception. if (rightHandSide == null) { this.CreateSyntaxException(); } // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last); // Create and return the expression. expression = new NullConditionExpression(partialTokens, leftHandSide, rightHandSide); expressionReference.Target = expression; } return expression; }
/// <summary> /// Reads a null condition expression from the code. /// </summary> /// <param name="leftHandSide">The left hand side.</param> /// <param name="previousPrecedence">The previous precedence.</param> /// <param name="parentReference">The parent code unit.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <returns> /// Returns the expression. /// </returns> private Expression GetNullConditionExpression( Expression leftHandSide, ExpressionPrecedence previousPrecedence, Reference<ICodePart> parentReference, bool unsafeCode) { Param.AssertNotNull(leftHandSide, "leftHandSide"); Param.Ignore(previousPrecedence); Param.AssertNotNull(parentReference, "parentReference"); Param.Ignore(unsafeCode); NullConditionExpression expression = null; Reference<ICodePart> expressionReference = new Reference<ICodePart>(); // Read the details of the expression. OperatorSymbol operatorToken = this.PeekOperatorToken(parentReference, expressionReference); Debug.Assert(operatorToken.SymbolType == OperatorType.NullConditional, "Expected a null-conditional symbol"); // Check the precedence of the operators to make sure we can gather this statement now. ExpressionPrecedence precedence = GetOperatorPrecedence(operatorToken.SymbolType); if (CheckPrecedence(previousPrecedence, precedence)) { // Add the operator token to the document and advance the symbol manager up to it. this.symbols.Advance(); this.tokens.Add(operatorToken); // Get the expression on the right-hand side of the operator. Expression rightHandSide = this.GetOperatorRightHandExpression(precedence, expressionReference, unsafeCode); // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last); // Create and return the expression. expression = new NullConditionExpression(partialTokens, leftHandSide, rightHandSide); expressionReference.Target = expression; } return expression; }