/// <summary> /// Reads an expression wrapped in parenthesis. /// </summary> /// <param name="sourceCode"> /// The source code containing the expression. /// </param> /// <param name="parentReference"> /// The parent code part. /// </param> /// <returns> /// Returns the expression. /// </returns> private ParenthesizedExpression GetConditionalPreprocessorParenthesizedExpression(SourceCode sourceCode, Reference <ICodePart> parentReference) { Param.AssertNotNull(sourceCode, "sourceCode"); Param.AssertNotNull(parentReference, "parentReference"); // Get the opening parenthesis. this.AdvanceToNextConditionalDirectiveCodeSymbol(parentReference); Symbol firstSymbol = this.symbols.Peek(1); if (firstSymbol == null || firstSymbol.SymbolType != SymbolType.OpenParenthesis) { throw new SyntaxException(sourceCode, firstSymbol.LineNumber); } Reference <ICodePart> expressionReference = new Reference <ICodePart>(); this.symbols.Advance(); Bracket openParenthesis = new Bracket(firstSymbol.Text, CsTokenType.OpenParenthesis, firstSymbol.Location, expressionReference, this.symbols.Generated); Node <CsToken> openParenthesisNode = this.tokens.InsertLast(openParenthesis); // Get the inner expression. Expression innerExpression = this.GetNextConditionalPreprocessorExpression(sourceCode, ExpressionPrecedence.None); if (innerExpression == null) { throw new SyntaxException(sourceCode, firstSymbol.LineNumber); } // Get the closing parenthesis. this.AdvanceToNextConditionalDirectiveCodeSymbol(expressionReference); Symbol symbol = this.symbols.Peek(1); if (symbol == null || symbol.SymbolType != SymbolType.CloseParenthesis) { throw new SyntaxException(sourceCode, firstSymbol.LineNumber); } this.symbols.Advance(); Bracket closeParenthesis = new Bracket(symbol.Text, CsTokenType.CloseParenthesis, symbol.Location, expressionReference, this.symbols.Generated); Node <CsToken> closeParenthesisNode = this.tokens.InsertLast(closeParenthesis); openParenthesis.MatchingBracketNode = closeParenthesisNode; closeParenthesis.MatchingBracketNode = openParenthesisNode; // Create the token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, openParenthesisNode, this.tokens.Last); // Create and return the expression. ParenthesizedExpression expression = new ParenthesizedExpression(partialTokens, innerExpression); expressionReference.Target = expression; return(expression); }
/// <summary> /// Checks the given parenthesized expression to make sure that it is not unnecessary. /// </summary> /// <param name="element"> /// The element containing the expression. /// </param> /// <param name="parenthesizedExpression"> /// The parenthesized expression to check. /// </param> private void CheckParenthesizedExpression(CsElement element, ParenthesizedExpression parenthesizedExpression) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(parenthesizedExpression, "parenthesizedExpression"); // Check the type of the inner expression to determine if it is one of types allowed to be wrapped within parenthesis. if (parenthesizedExpression.InnerExpression != null) { // The following types of expressions are allowed to be placed within a set of parenthesis. Expression innerExpression = parenthesizedExpression.InnerExpression; if (innerExpression.ExpressionType != ExpressionType.Arithmetic && innerExpression.ExpressionType != ExpressionType.As && innerExpression.ExpressionType != ExpressionType.Assignment && innerExpression.ExpressionType != ExpressionType.Await && innerExpression.ExpressionType != ExpressionType.Cast && innerExpression.ExpressionType != ExpressionType.Conditional && innerExpression.ExpressionType != ExpressionType.ConditionalLogical && innerExpression.ExpressionType != ExpressionType.Decrement && innerExpression.ExpressionType != ExpressionType.Increment && innerExpression.ExpressionType != ExpressionType.Is && innerExpression.ExpressionType != ExpressionType.Lambda && innerExpression.ExpressionType != ExpressionType.Logical && innerExpression.ExpressionType != ExpressionType.New && innerExpression.ExpressionType != ExpressionType.NewArray && innerExpression.ExpressionType != ExpressionType.NullCoalescing && innerExpression.ExpressionType != ExpressionType.Query && innerExpression.ExpressionType != ExpressionType.Relational && innerExpression.ExpressionType != ExpressionType.Unary && innerExpression.ExpressionType != ExpressionType.UnsafeAccess) { this.AddViolation(element, parenthesizedExpression.Location, Rules.StatementMustNotUseUnnecessaryParenthesis); } else { // These types of expressions are allowed in some cases to be surrounded by parenthesis, // as long as the parenthesized expression is within another expression. They are not allowed // to be within parenthesis within a variable declarator expression. For example: // int x = (2 + 3); if (!(parenthesizedExpression.Parent is Expression) || parenthesizedExpression.Parent is VariableDeclaratorExpression || parenthesizedExpression.Parent is CheckedExpression || parenthesizedExpression.Parent is UncheckedExpression || parenthesizedExpression.Parent is MethodInvocationExpression) { if (parenthesizedExpression.Parent is MethodInvocationExpression) { MethodInvocationExpression parentMethodInvocationExpression = parenthesizedExpression.Parent as MethodInvocationExpression; foreach (Argument argument in parentMethodInvocationExpression.Arguments) { if (argument.Expression.Equals(parenthesizedExpression)) { this.AddViolation(element, parenthesizedExpression.Location, Rules.StatementMustNotUseUnnecessaryParenthesis); } } } else { this.AddViolation(element, parenthesizedExpression.Location, Rules.StatementMustNotUseUnnecessaryParenthesis); } } else { // This is also not allowed when the expression is on the right-hand side of an assignment. AssignmentExpression assignment = parenthesizedExpression.Parent as AssignmentExpression; if (assignment != null && assignment.RightHandSide == parenthesizedExpression) { this.AddViolation(element, parenthesizedExpression.Location, Rules.StatementMustNotUseUnnecessaryParenthesis); } } } } }
/// <summary> /// Reads an expression wrapped in parenthesis expression. /// </summary> /// <param name="unsafeCode"> /// Indicates whether the code being parsed resides in an unsafe code block. /// </param> /// <returns> /// Returns the expression. /// </returns> private ParenthesizedExpression GetParenthesizedExpression(bool unsafeCode) { Param.Ignore(unsafeCode); Reference<ICodePart> expressionReference = new Reference<ICodePart>(); // Get the opening parenthesis. Bracket openParenthesis = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis, expressionReference); Node<CsToken> openParenthesisNode = this.tokens.InsertLast(openParenthesis); // Get the inner expression. Expression innerExpression = this.GetNextExpression(ExpressionPrecedence.None, expressionReference, unsafeCode); if (innerExpression == null) { throw this.CreateSyntaxException(); } // Get the closing parenthesis. Bracket closeParenthesis = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis, expressionReference); Node<CsToken> closeParenthesisNode = this.tokens.InsertLast(closeParenthesis); openParenthesis.MatchingBracketNode = closeParenthesisNode; closeParenthesis.MatchingBracketNode = openParenthesisNode; // Create the token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, openParenthesisNode, this.tokens.Last); // Create and return the expression. ParenthesizedExpression expression = new ParenthesizedExpression(partialTokens, innerExpression); expressionReference.Target = expression; return expression; }
/// <summary> /// Reads an expression wrapped in parenthesis. /// </summary> /// <param name="sourceCode"> /// The source code containing the expression. /// </param> /// <param name="parentReference"> /// The parent code part. /// </param> /// <returns> /// Returns the expression. /// </returns> private ParenthesizedExpression GetConditionalPreprocessorParenthesizedExpression(SourceCode sourceCode, Reference<ICodePart> parentReference) { Param.AssertNotNull(sourceCode, "sourceCode"); Param.AssertNotNull(parentReference, "parentReference"); // Get the opening parenthesis. this.AdvanceToNextConditionalDirectiveCodeSymbol(parentReference); Symbol firstSymbol = this.symbols.Peek(1); if (firstSymbol == null || firstSymbol.SymbolType != SymbolType.OpenParenthesis) { throw new SyntaxException(sourceCode, firstSymbol.LineNumber); } Reference<ICodePart> expressionReference = new Reference<ICodePart>(); this.symbols.Advance(); Bracket openParenthesis = new Bracket(firstSymbol.Text, CsTokenType.OpenParenthesis, firstSymbol.Location, expressionReference, this.symbols.Generated); Node<CsToken> openParenthesisNode = this.tokens.InsertLast(openParenthesis); // Get the inner expression. Expression innerExpression = this.GetNextConditionalPreprocessorExpression(sourceCode, ExpressionPrecedence.None); if (innerExpression == null) { throw new SyntaxException(sourceCode, firstSymbol.LineNumber); } // Get the closing parenthesis. this.AdvanceToNextConditionalDirectiveCodeSymbol(expressionReference); Symbol symbol = this.symbols.Peek(1); if (symbol == null || symbol.SymbolType != SymbolType.CloseParenthesis) { throw new SyntaxException(sourceCode, firstSymbol.LineNumber); } this.symbols.Advance(); Bracket closeParenthesis = new Bracket(symbol.Text, CsTokenType.CloseParenthesis, symbol.Location, expressionReference, this.symbols.Generated); Node<CsToken> closeParenthesisNode = this.tokens.InsertLast(closeParenthesis); openParenthesis.MatchingBracketNode = closeParenthesisNode; closeParenthesis.MatchingBracketNode = openParenthesisNode; // Create the token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, openParenthesisNode, this.tokens.Last); // Create and return the expression. ParenthesizedExpression expression = new ParenthesizedExpression(partialTokens, innerExpression); expressionReference.Target = expression; return expression; }
/// <summary> /// The save. /// </summary> /// <param name="parenthesizedExpression"> /// The parenthesized expression. /// </param> private void Save(ParenthesizedExpression parenthesizedExpression) { this.cppWriter.Write('('); @switch(parenthesizedExpression.InnerExpression); this.cppWriter.Write(')'); }