/// <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); var 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. var 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); } var 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. var expression = new ParenthesizedExpression(partialTokens, innerExpression); expressionReference.Target = expression; return expression; }
private void CheckParenthesizedExpression(CsElement element, ParenthesizedExpression parenthesizedExpression) { if (parenthesizedExpression.InnerExpression != null) { Expression innerExpression = parenthesizedExpression.InnerExpression; if ((((((innerExpression.ExpressionType != ExpressionType.Arithmetic) && (innerExpression.ExpressionType != ExpressionType.As)) && ((innerExpression.ExpressionType != ExpressionType.Assignment) && (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)) { base.AddViolation(element, parenthesizedExpression.LineNumber, Microsoft.StyleCop.CSharp.Rules.StatementMustNotUseUnnecessaryParenthesis, new object[0]); } else if (!(parenthesizedExpression.Parent is Expression) || (parenthesizedExpression.Parent is VariableDeclaratorExpression)) { base.AddViolation(element, parenthesizedExpression.LineNumber, Microsoft.StyleCop.CSharp.Rules.StatementMustNotUseUnnecessaryParenthesis, new object[0]); } else { AssignmentExpression parent = parenthesizedExpression.Parent as AssignmentExpression; if ((parent != null) && (parent.RightHandSide == parenthesizedExpression)) { base.AddViolation(element, parenthesizedExpression.LineNumber, Microsoft.StyleCop.CSharp.Rules.StatementMustNotUseUnnecessaryParenthesis, new object[0]); } } } }
/// <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.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.LineNumber, 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) { this.AddViolation(element, parenthesizedExpression.LineNumber, 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.LineNumber, Rules.StatementMustNotUseUnnecessaryParenthesis); } } } } }