/// <summary>
        /// Checks that parenthesis are used correctly within a conditional logical expression.
        /// </summary>
        /// <param name="element">
        /// The parent element.
        /// </param>
        /// <param name="expression">
        /// The expression to check.
        /// </param>
        private void CheckConditionalLogicalExpressionParenthesis(CsElement element, ConditionalLogicalExpression expression)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expression, "expression");

            if (expression.LeftHandSide.ExpressionType == ExpressionType.ConditionalLogical)
            {
                if (!this.CheckConditionalLogicalParenthesisForExpressionAndChild(element, expression, (ConditionalLogicalExpression)expression.LeftHandSide))
                {
                    return;
                }
            }

            if (expression.RightHandSide.ExpressionType == ExpressionType.ConditionalLogical)
            {
                this.CheckConditionalLogicalParenthesisForExpressionAndChild(element, expression, (ConditionalLogicalExpression)expression.RightHandSide);
            }
        }
        /// <summary>
        /// Checks whether parenthesis are needed within the conditional logical expressions.
        /// </summary>
        /// <param name="element">
        /// The parent element.
        /// </param>
        /// <param name="expression">
        /// The parent conditional logical expression.
        /// </param>
        /// <param name="childExpression">
        /// The child conditional logical expression.
        /// </param>
        /// <returns>
        /// Returns true if there is no violation, or false if there is a violation.
        /// </returns>
        private bool CheckConditionalLogicalParenthesisForExpressionAndChild(
            CsElement element, ConditionalLogicalExpression expression, ConditionalLogicalExpression childExpression)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expression, "expression");
            Param.AssertNotNull(childExpression, "childExpression");

            // If the two expressions are both of the same type (OR or AND), then there is 
            // no need for parenthesis.
            if (expression.OperatorType != childExpression.OperatorType)
            {
                // The expressions are not of the same type. One of them should be enclosed
                // by parenthesis to indicate the precedence.
                this.AddViolation(element, expression.LineNumber, Rules.ConditionalExpressionsMustDeclarePrecedence);
                return false;
            }

            return true;
        }
        /// <summary>
        /// Reads a conditional logical expression.
        /// </summary>
        /// <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="parentReference">
        /// The parent code part.
        /// </param>
        /// <param name="unsafeCode">
        /// Indicates whether the code being parsed resides in an unsafe code block.
        /// </param>
        /// <returns>
        /// Returns the expression.
        /// </returns>
        private ConditionalLogicalExpression GetConditionalLogicalExpression(
            Expression leftHandSide, ExpressionPrecedence previousPrecedence, Reference<ICodePart> parentReference, bool unsafeCode)
        {
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.Ignore(previousPrecedence);
            Param.AssertNotNull(parentReference, "parentReference");
            Param.Ignore(unsafeCode);

            ConditionalLogicalExpression expression = null;
            Reference<ICodePart> expressionReference = new Reference<ICodePart>();

            // Read the details of the expression.
            OperatorSymbol operatorToken = this.PeekOperatorToken(parentReference, expressionReference);
            Debug.Assert(operatorToken.Category == OperatorCategory.Logical, "Expected a logical 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))
            {
                // 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);

                // Get the expression operator type.
                ConditionalLogicalExpression.Operator type;
                switch (operatorToken.SymbolType)
                {
                    case OperatorType.ConditionalAnd:
                        type = ConditionalLogicalExpression.Operator.And;
                        break;

                    case OperatorType.ConditionalOr:
                        type = ConditionalLogicalExpression.Operator.Or;
                        break;

                    default:
                        Debug.Fail("Unexpected operator type");
                        throw new InvalidOperationException();
                }

                // Create and return the expression.
                expression = new ConditionalLogicalExpression(partialTokens, type, leftHandSide, rightHandSide);
                expressionReference.Target = expression;
            }

            return expression;
        }
        /// <summary>
        /// Reads a conditional logical expression.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code containing the expression.
        /// </param>
        /// <param name="parentReference">
        /// The parent code unit.
        /// </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>
        /// <returns>
        /// Returns the expression.
        /// </returns>
        private ConditionalLogicalExpression GetConditionalPreprocessorAndOrExpression(
            SourceCode sourceCode, Reference<ICodePart> parentReference, Expression leftHandSide, ExpressionPrecedence previousPrecedence)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parentReference, "parentReference");
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.Ignore(previousPrecedence);

            ConditionalLogicalExpression expression = null;

            this.AdvanceToNextConditionalDirectiveCodeSymbol(parentReference);
            Symbol firstSymbol = this.symbols.Peek(1);
            if (firstSymbol == null)
            {
                throw new SyntaxException(sourceCode, firstSymbol.LineNumber);
            }

            Reference<ICodePart> expressionReference = new Reference<ICodePart>();

            // Create the operator symbol.
            OperatorType type;
            OperatorCategory category;
            GetOperatorType(firstSymbol, out type, out category);
            OperatorSymbol operatorToken = new OperatorSymbol(firstSymbol.Text, category, type, firstSymbol.Location, expressionReference, this.symbols.Generated);

            // 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.GetNextConditionalPreprocessorExpression(sourceCode, precedence);
                if (rightHandSide == null)
                {
                    throw new SyntaxException(sourceCode, operatorToken.LineNumber);
                }

                // Create the partial token list for the expression.
                CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last);

                // Get the expression operator type.
                ConditionalLogicalExpression.Operator conditionalType;
                switch (operatorToken.SymbolType)
                {
                    case OperatorType.ConditionalAnd:
                        conditionalType = ConditionalLogicalExpression.Operator.And;
                        break;

                    case OperatorType.ConditionalOr:
                        conditionalType = ConditionalLogicalExpression.Operator.Or;
                        break;

                    default:
                        throw new SyntaxException(sourceCode, operatorToken.LineNumber);
                }

                // Create and return the expression.
                expression = new ConditionalLogicalExpression(partialTokens, conditionalType, leftHandSide, rightHandSide);
            }

            return expression;
        }
Esempio n. 5
0
        /// <summary>
        /// Reads a conditional logical expression.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code containing the expression.
        /// </param>
        /// <param name="parentReference">
        /// The parent code unit.
        /// </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>
        /// <returns>
        /// Returns the expression.
        /// </returns>
        private ConditionalLogicalExpression GetConditionalPreprocessorAndOrExpression(
            SourceCode sourceCode, Reference <ICodePart> parentReference, Expression leftHandSide, ExpressionPrecedence previousPrecedence)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parentReference, "parentReference");
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.Ignore(previousPrecedence);

            ConditionalLogicalExpression expression = null;

            this.AdvanceToNextConditionalDirectiveCodeSymbol(parentReference);
            Symbol firstSymbol = this.symbols.Peek(1);

            if (firstSymbol == null)
            {
                throw new SyntaxException(sourceCode, firstSymbol.LineNumber);
            }

            Reference <ICodePart> expressionReference = new Reference <ICodePart>();

            // Create the operator symbol.
            OperatorType     type;
            OperatorCategory category;

            GetOperatorType(firstSymbol, out type, out category);
            OperatorSymbol operatorToken = new OperatorSymbol(firstSymbol.Text, category, type, firstSymbol.Location, expressionReference, this.symbols.Generated);

            // 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.GetNextConditionalPreprocessorExpression(sourceCode, precedence);
                if (rightHandSide == null)
                {
                    throw new SyntaxException(sourceCode, operatorToken.LineNumber);
                }

                // Create the partial token list for the expression.
                CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last);

                // Get the expression operator type.
                ConditionalLogicalExpression.Operator conditionalType;
                switch (operatorToken.SymbolType)
                {
                case OperatorType.ConditionalAnd:
                    conditionalType = ConditionalLogicalExpression.Operator.And;
                    break;

                case OperatorType.ConditionalOr:
                    conditionalType = ConditionalLogicalExpression.Operator.Or;
                    break;

                default:
                    throw new SyntaxException(sourceCode, operatorToken.LineNumber);
                }

                // Create and return the expression.
                expression = new ConditionalLogicalExpression(partialTokens, conditionalType, leftHandSide, rightHandSide);
            }

            return(expression);
        }
        /// <summary>
        /// The save.
        /// </summary>
        /// <param name="operator">
        /// The operator.
        /// </param>
        private void Save(ConditionalLogicalExpression.Operator @operator)
        {
            var operatorString = string.Empty;

            switch (@operator)
            {
                case ConditionalLogicalExpression.Operator.And:
                    operatorString = "&&";
                    break;
                case ConditionalLogicalExpression.Operator.Or:
                    operatorString = "||";
                    break;
                default:
                    break;
            }

            this.cppWriter.Write(' ');
            this.cppWriter.Write(operatorString);
            this.cppWriter.Write(' ');
        }
 /// <summary>
 /// The save.
 /// </summary>
 /// <param name="conditionalLogicalExpression">
 /// The conditional logical expression.
 /// </param>
 private void Save(ConditionalLogicalExpression conditionalLogicalExpression)
 {
     @switch(conditionalLogicalExpression.LeftHandSide);
     this.Save(conditionalLogicalExpression.OperatorType);
     @switch(conditionalLogicalExpression.RightHandSide);
 }