/// <summary> /// Initializes a new instance of the ConstructorInitializerStatement class. /// </summary> /// <param name="tokens">The list of tokens that form the statement.</param> /// <param name="expression">The expression within this statement.</param> internal ConstructorInitializerStatement(CsTokenList tokens, MethodInvocationExpression expression) : base(StatementType.ConstructorInitializer, tokens) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(expression, "expression"); this.expression = expression; this.AddExpression(expression); }
/// <summary> /// Initializes a new instance of the Constructor class. /// </summary> /// <param name="document">The documenent that contains the element.</param> /// <param name="parent">The parent of the element.</param> /// <param name="header">The Xml header for this element.</param> /// <param name="attributes">The list of attributes attached to this element.</param> /// <param name="declaration">The declaration code for this element.</param> /// <param name="parameters">The parameters to the constructor.</param> /// <param name="initializerExpression">The constructor initializer, if there is one.</param> /// <param name="unsafeCode">Indicates whether the element resides within a block of unsafe code.</param> /// <param name="generated">Indicates whether the code element was generated or written by hand.</param> internal Constructor( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, IList<Parameter> parameters, MethodInvocationExpression initializerExpression, bool unsafeCode, bool generated) : base(document, parent, ElementType.Constructor, "constructor " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.Ignore(header); Param.Ignore(attributes); Param.AssertNotNull(declaration, "declaration"); Param.AssertNotNull(parameters, "parameters"); Param.Ignore(initializerExpression); Param.Ignore(unsafeCode); Param.Ignore(generated); // Static constructors are always public. if (this.Declaration.ContainsModifier(CsTokenType.Static)) { this.Declaration.AccessModifierType = AccessModifierType.Public; } this.parameters = parameters; Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only."); // Add the qualifications this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName); // If there is an initializer expression, add it to the statement list for this constructor. if (initializerExpression != null) { this.initializer = initializerExpression; ConstructorInitializerStatement initializerStatement = new ConstructorInitializerStatement( initializerExpression.Tokens, initializerExpression); this.AddStatement(initializerStatement); } }
/// <summary> /// Extracts the CheckID for the rule being suppressed, from the given Code Analysis SuppressMessage attribute expression. /// </summary> /// <param name="codeAnalysisAttributeExpression">The expression to parse.</param> /// <param name="ruleId">Returns the rule ID.</param> /// <param name="ruleName">Returns the rule name.</param> /// <param name="ruleNamespace">Returns the namespace that contains the rule.</param> /// <returns>Returns true if the ID, name, and namespace were successfully extracted from the suppression.</returns> private static bool TryCrackCodeAnalysisSuppression(MethodInvocationExpression codeAnalysisAttributeExpression, out string ruleId, out string ruleName, out string ruleNamespace) { Param.AssertNotNull(codeAnalysisAttributeExpression, "codeAnalysisAttributeExpression"); // Initialize all out fields to null. ruleId = ruleName = ruleNamespace = null; if (codeAnalysisAttributeExpression.Arguments != null && codeAnalysisAttributeExpression.Arguments.Count >= 2) { // The rule namespace sits in the first argument. ruleNamespace = ExtractStringFromAttributeExpression(codeAnalysisAttributeExpression.Arguments[0].Expression); if (string.IsNullOrEmpty(ruleNamespace)) { return false; } // The checkID and rule name sit in the second argument. string nameAndId = ExtractStringFromAttributeExpression(codeAnalysisAttributeExpression.Arguments[1].Expression); if (string.IsNullOrEmpty(nameAndId)) { return false; } // When the nameAndId field just contains a *, this means to supress all rules in the given namespace. if (nameAndId == "*") { ruleId = "*"; return true; } // Split the rule name and ID. int separatorIndex = nameAndId.IndexOf(':'); if (separatorIndex == -1) { return false; } ruleId = nameAndId.Substring(0, separatorIndex); ruleName = nameAndId.Substring(separatorIndex + 1, nameAndId.Length - separatorIndex - 1); return ruleId.Length > 0 && ruleName.Length > 0; } return false; }
/// <summary> /// Reads a method access expression. /// </summary> /// <param name="methodName">The name of the method being called.</param> /// <param name="previousPrecedence">The precedence of the previous expression.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <returns>Returns the expression.</returns> private MethodInvocationExpression GetMethodInvocationExpression( Expression methodName, ExpressionPrecedence previousPrecedence, bool unsafeCode) { Param.AssertNotNull(methodName, "methodName"); Param.Ignore(previousPrecedence); Param.Ignore(unsafeCode); MethodInvocationExpression expression = null; if (CheckPrecedence(previousPrecedence, ExpressionPrecedence.Primary)) { var expressionReference = new Reference<ICodePart>(); // The next symbol will be the opening parenthesis. Bracket openParenthesis = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis, expressionReference); Node<CsToken> openParenthesisNode = this.tokens.InsertLast(openParenthesis); // Get the argument list now. IList<Argument> argumentList = this.GetArgumentList(SymbolType.CloseParenthesis, expressionReference, unsafeCode); // 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; // Pull out the first token from the method name. Debug.Assert(methodName.Tokens.First != null, "The method name should not be empty"); Node<CsToken> firstTokenNode = methodName.Tokens.First; // Create the token list for the method invocation expression. CsTokenList partialTokens = new CsTokenList(this.tokens, firstTokenNode, this.tokens.Last); // Create and return the expression. expression = new MethodInvocationExpression(partialTokens, methodName, argumentList); expressionReference.Target = expression; } return expression; }
private MethodInvocationExpression GetMethodInvocationExpression(Expression methodName, ExpressionPrecedence previousPrecedence, bool unsafeCode) { MethodInvocationExpression expression = null; if (CheckPrecedence(previousPrecedence, ExpressionPrecedence.Primary)) { Bracket bracketToken = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis); Microsoft.StyleCop.Node<CsToken> node = this.tokens.InsertLast(bracketToken); IList<Expression> argumentList = this.GetArgumentList(SymbolType.CloseParenthesis, unsafeCode); Bracket item = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis); Microsoft.StyleCop.Node<CsToken> node2 = this.tokens.InsertLast(item); bracketToken.MatchingBracketNode = node2; item.MatchingBracketNode = node; Microsoft.StyleCop.Node<CsToken> first = methodName.Tokens.First; CsTokenList tokens = new CsTokenList(this.tokens, first, this.tokens.Last); expression = new MethodInvocationExpression(tokens, methodName, argumentList); } return expression; }
private static bool TryCrackCodeAnalysisSuppression(MethodInvocationExpression codeAnalysisAttributeExpression, out string ruleId, out string ruleName, out string ruleNamespace) { string str2; ruleNamespace = (string) (str2 = null); ruleId = ruleName = str2; if ((codeAnalysisAttributeExpression.Arguments == null) || (codeAnalysisAttributeExpression.Arguments.Count < 2)) { return false; } ruleNamespace = ExtractStringFromAttributeExpression(codeAnalysisAttributeExpression.Arguments[0]); if (string.IsNullOrEmpty(ruleNamespace)) { return false; } string str = ExtractStringFromAttributeExpression(codeAnalysisAttributeExpression.Arguments[1]); if (string.IsNullOrEmpty(str)) { return false; } int index = str.IndexOf(':'); if (index == -1) { return false; } ruleId = str.Substring(0, index); ruleName = str.Substring(index + 1, (str.Length - index) - 1); return ((ruleId.Length > 0) && (ruleName.Length > 0)); }
private static bool IsSuppressMessage(MethodInvocationExpression expression) { Microsoft.StyleCop.Node<CsToken> first = expression.Name.Tokens.First; if (first != null) { if (first.Value.Text.Equals("SuppressMessage", StringComparison.Ordinal)) { return true; } if (first.Value.Text.Equals("System")) { return expression.Name.Tokens.MatchTokens(new string[] { "System", ".", "Diagnostics", ".", "CodeAnalysis", ".", "SuppressMessage" }); } } return false; }
private void CheckDebugFailMessage(CsElement element, MethodInvocationExpression debugFailMethodCall) { Expression expression = null; foreach (Expression expression2 in debugFailMethodCall.Arguments) { expression = expression2; break; } if ((expression == null) || (expression.Tokens.First == null)) { base.AddViolation(element, debugFailMethodCall.LineNumber, Microsoft.StyleCop.CSharp.Rules.DebugFailMustProvideMessageText, new object[0]); } else if ((expression.Tokens.First.Value.CsTokenType == CsTokenType.String) && IsEmptyString(expression.Tokens.First.Value.Text)) { base.AddViolation(element, debugFailMethodCall.LineNumber, Microsoft.StyleCop.CSharp.Rules.DebugFailMustProvideMessageText, new object[0]); } }
private void CheckCodeAnalysisSuppressionForJustification(CsElement element, MethodInvocationExpression suppression) { bool flag = false; foreach (Expression expression in suppression.Arguments) { if (expression.ExpressionType == ExpressionType.Assignment) { AssignmentExpression expression2 = (AssignmentExpression) expression; if (expression2.LeftHandSide.Tokens.First.Value.Text.Equals("Justification", StringComparison.Ordinal)) { Microsoft.StyleCop.Node<CsToken> first = expression2.RightHandSide.Tokens.First; if (((first != null) && (first.Value.CsTokenType == CsTokenType.String)) && ((first.Value.Text != null) && !IsEmptyString(first.Value.Text))) { flag = true; break; } } } } if (!flag) { base.AddViolation(element, suppression.LineNumber, Microsoft.StyleCop.CSharp.Rules.CodeAnalysisSuppressionMustHaveJustification, new object[0]); } }
/// <summary> /// Checks the given call into Debug.Fail to ensure that it contains a valid debug message. /// </summary> /// <param name="element">The parent element.</param> /// <param name="debugFailMethodCall">The call to Debug.Fail.</param> private void CheckDebugFailMessage(CsElement element, MethodInvocationExpression debugFailMethodCall) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(debugFailMethodCall, "debugFailMethodCall"); // Extract the first argument. Argument firstArgument = null; foreach (Argument argument in debugFailMethodCall.Arguments) { firstArgument = argument; break; } if (firstArgument == null || firstArgument.Tokens.First == null) { // There is no message argument or the message argument is empty. this.AddViolation(element, debugFailMethodCall.LineNumber, Rules.DebugFailMustProvideMessageText); } else if (firstArgument.Tokens.First.Value.CsTokenType == CsTokenType.String && IsEmptyString(firstArgument.Tokens.First.Value.Text)) { // The message argument contains an empty string. this.AddViolation(element, debugFailMethodCall.LineNumber, Rules.DebugFailMustProvideMessageText); } }
/// <summary> /// Checks the given call into Debug.Assert to ensure that it contains a valid debug message. /// </summary> /// <param name="element">The parent element.</param> /// <param name="debugAssertMethodCall">The call to Debug.Assert.</param> private void CheckDebugAssertMessage(CsElement element, MethodInvocationExpression debugAssertMethodCall) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(debugAssertMethodCall, "debugAssertMethodCall"); // Extract the second argument. Argument secondArgument = null; if (debugAssertMethodCall.Arguments.Count >= 2) { secondArgument = debugAssertMethodCall.Arguments[1]; } if (secondArgument == null || secondArgument.Tokens.First == null) { // There is no message argument or the message argument is empty. this.AddViolation(element, debugAssertMethodCall.LineNumber, Rules.DebugAssertMustProvideMessageText); } else if (secondArgument.Tokens.First.Value.CsTokenType == CsTokenType.String && IsEmptyString(secondArgument.Tokens.First.Value.Text)) { // The message argument contains an empty string. this.AddViolation(element, debugAssertMethodCall.LineNumber, Rules.DebugAssertMustProvideMessageText); } }
/// <summary> /// Checks the given code analysis suppression call to ensure that it contains a justifiction parameter. /// </summary> /// <param name="element">The element that contains the suppression attribute.</param> /// <param name="suppression">The suppression to check.</param> private void CheckCodeAnalysisSuppressionForJustification(CsElement element, MethodInvocationExpression suppression) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(suppression, "suppression"); bool justifiction = false; foreach (Argument argument in suppression.Arguments) { if (argument.Expression.ExpressionType == ExpressionType.Assignment) { AssignmentExpression assignmentExpression = (AssignmentExpression)argument.Expression; if (assignmentExpression.LeftHandSide.Tokens.First.Value.Text.Equals("Justification", StringComparison.Ordinal)) { Node<CsToken> rightSideTokenNode = assignmentExpression.RightHandSide.Tokens.First; if (rightSideTokenNode != null && rightSideTokenNode.Value.CsTokenType == CsTokenType.String && rightSideTokenNode.Value.Text != null && !IsEmptyString(rightSideTokenNode.Value.Text)) { justifiction = true; break; } } } } if (!justifiction) { this.AddViolation(element, suppression.LineNumber, Rules.CodeAnalysisSuppressionMustHaveJustification); } }
/// <summary> /// Determines whether the given method invocation expression contains a code analysis SuppressMessage call. /// </summary> /// <param name="expression">The expression.</param> /// <returns>Returns true if the method is SuppressMessage.</returns> private static bool IsSuppressMessage(MethodInvocationExpression expression) { Param.AssertNotNull(expression, "expression"); Node<CsToken> first = expression.Name.Tokens.First; if (first != null) { if (first.Value.Text.Equals("SuppressMessage", StringComparison.Ordinal)) { return true; } else if (first.Value.Text.Equals("System")) { return expression.Name.Tokens.MatchTokens("System", ".", "Diagnostics", ".", "CodeAnalysis", ".", "SuppressMessage"); } } return false; }
internal ConstructorInitializerStatement(CsTokenList tokens, MethodInvocationExpression expression) : base(StatementType.ConstructorInitializer, tokens) { this.expression = expression; base.AddExpression(expression); }
/// <summary> /// Checks a method invocation expression to make that the parameters are positioned correctly. /// </summary> /// <param name="element">The element containing the expression.</param> /// <param name="expression">The expression to check.</param> private void CheckMethodInvocationParameters(CsElement element, MethodInvocationExpression expression) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(expression, "expression"); if (expression.Tokens.First != null && !expression.Tokens.First.Value.Generated) { ArgumentList argumentList = new ArgumentList(expression.Arguments); CsTokenList argumentListTokens = GetArgumentListTokens(expression.Tokens, expression.Name.Tokens.Last, CsTokenType.OpenParenthesis, CsTokenType.CloseParenthesis); if (argumentListTokens != null) { this.CheckParameters(element, argumentListTokens, argumentList, expression.LineNumber, CsTokenType.OpenParenthesis, CsTokenType.CloseParenthesis); } } }