public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { CodePoint startPoint = null; CodePoint endPoint = null; foreach (var token in from token in csElement.ElementTokens where token.LineNumber >= violation.Line select token) { if (token.CsTokenType == CsTokenType.UsingDirective || token.CsTokenType == CsTokenType.Using) { startPoint = token.Location.StartPoint; continue; } if (token.CsTokenType == CsTokenType.Semicolon) { endPoint = token.Location.EndPoint; } if (startPoint != null && endPoint != null) { var sourceRange = new SourceRange(startPoint.LineNumber, startPoint.IndexOnLine + 1, endPoint.LineNumber, endPoint.IndexOnLine + 2); yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, sourceRange); } } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { int prefixLength = "The call to ".Length; var memberName = violation.Message.Substring(prefixLength, violation.Message.IndexOf(" must") - prefixLength); var thisFound = false; foreach (var token in from token in csElement.ElementTokens where token.LineNumber == violation.Line && token.CsTokenType != CsTokenType.WhiteSpace select token) { if (token.CsTokenType == CsTokenType.This || (thisFound && token.Text == ".")) { thisFound = true; } else { if (token.Text == memberName && !thisFound) { var sourceRange = new SourceRange(token.Location.StartPoint.LineNumber, token.Location.StartPoint.IndexOnLine + 1, token.Location.EndPoint.LineNumber, token.Location.EndPoint.IndexOnLine + 2); yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, sourceRange); } thisFound = false; } } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { foreach (BinaryOperatorExpression operation in from x in enumerate(new ElementTypeFilter(LanguageElementType.BinaryOperatorExpression)) let binaryOperation = (BinaryOperatorExpression)x.ToLanguageElement() where binaryOperation.RecoveredRange.Start.Line == violation.Line && (binaryOperation.LeftSide.ElementType == LanguageElementType.BinaryOperatorExpression || binaryOperation.RightSide.ElementType == LanguageElementType.BinaryOperatorExpression) select binaryOperation) { var parentType = operators[operation.Name]; var leftChildType = operation.LeftSide.ElementType == LanguageElementType.BinaryOperatorExpression ? operators[operation.LeftSide.Name] : parentType; var rightChildType = operation.RightSide.ElementType == LanguageElementType.BinaryOperatorExpression ? operators[operation.RightSide.Name] : parentType; var isLeftModulo = operation.LeftSide.ElementType == LanguageElementType.BinaryOperatorExpression ? operation.LeftSide.Name == "%" : operation.Name == "%"; var isRightModulo = operation.RightSide.ElementType == LanguageElementType.BinaryOperatorExpression ? operation.RightSide.Name == "%" : operation.Name == "%"; if (rightChildType > parentType) { yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, operation.RightSide.RecoveredRange); } else if (leftChildType > parentType || (leftChildType == rightChildType && isLeftModulo != isRightModulo)) { yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, operation.LeftSide.RecoveredRange); } } }
/// <summary> /// Checks whether specified element conforms custom rule CR0001. /// </summary> private bool CheckClasses( CsElement element, CsElement parentElement, object context) { // if current element is not a class then continue walking if (element.ElementType != ElementType.Class) return true; // check whether class name contains "a" letter Class classElement = (Class)element; if (classElement.Declaration.Name.Contains("a")) { // add violation // (note how custom message arguments could be used) AddViolation( classElement, classElement.Location, "AvoidUsingAInClassNames", classElement.FriendlyTypeText); } // continue walking in order to find all classes in file return true; }
/// <summary> /// Checks whether specified element conforms to custom rule GP0001 /// </summary> /// <param name="element"> /// The current element that is to be inspected. /// </param> /// <param name="parentElement"> /// The parent element for the element currently being inspected. /// </param> /// <param name="context"> /// The context. /// </param> /// <returns> /// True/False indicating whether to continue walking the elements within the class. /// </returns> private bool CheckClasses(CsElement element, CsElement parentElement, object context) { // If the overall StyleCop is cancelled externally, then stop processing if (Cancel) { return false; } // if current element is not a class then continue walking if (element.ElementType != ElementType.Class) { return true; } // check whether class name contains "a" letter var classElement = (Class)element; if (classElement.Declaration.Name.Contains("a")) { // add violation // (note how custom message arguments could be used) AddViolation( classElement, classElement.Location, "AvoidUsingAInClassNames", classElement.FriendlyTypeText); } if (classElement.Declaration.Name.Length > MaximumClassNameLength) { // add violation // (note how custom message arguments could be used) AddViolation(classElement, classElement.Location, "AvoidLongClassNames", classElement.FriendlyTypeText); } // continue walking in order to find all classes in file return true; }
public override void VisitElement(CsElement element, CsElement parentElement, object context) { if ((element.ElementType == ElementType.Method && ((Method)element).ReturnType.Text != "void") // Func || (element.ElementType == ElementType.Accessor && ((Accessor)element).AccessorType == AccessorType.Get)) // Getter { if (element.ElementTokens.Count(x => x.CsTokenType == CsTokenType.Return) > 1) { this.SourceAnalyzer.AddViolation(element, ContribRule.SingleReturnStatement); } } else if (element.ElementType == ElementType.Constructor || (element.ElementType == ElementType.Method && ((Method)element).ReturnType.Text == "void") // Proc || (element.ElementType == ElementType.Accessor && ((Accessor)element).AccessorType != AccessorType.Get)) // Setter, Add, Remove { if (element.ElementTokens.Any(x => x.CsTokenType == CsTokenType.Return)) { this.SourceAnalyzer.AddViolation(element, ContribRule.ReturnStatementOnlyInFunctions); } } else if (element.ElementType == ElementType.Class) { if (element.Declaration.Name.Length > MaximumClassNameLength) { this.SourceAnalyzer.AddViolation(element, ContribRule.ClassNameLengthExceeded); } } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { bool specialPredecessorFound = true; bool whitespaceFound = false; foreach (var token in this.getTokens(csElement).Flatten().Where(x => x.LineNumber == violation.Line)) { if (!specialPredecessorFound && whitespaceFound && this.reportIssueFor(token, violation)) { whitespaceFound = false; yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, new SourceRange(token.Location.StartPoint.LineNumber, token.Location.StartPoint.IndexOnLine + 1, token.Location.EndPoint.LineNumber, token.Location.EndPoint.IndexOnLine + 2)); } else if (this.specialPredecessors.Contains(token.CsTokenType)) { specialPredecessorFound = true; whitespaceFound = false; } else if (token.CsTokenType == CsTokenType.WhiteSpace) { whitespaceFound = true; } else { specialPredecessorFound = false; whitespaceFound = false; } } }
private bool elementCallback(CsElement element, CsElement parentElement, object context) { if (element.Header != null) { XDocument xml; try { var xmlText = string.Format("<root>{0}</root>", element.Header.RawText); xml = XDocument.Parse(xmlText, LoadOptions.PreserveWhitespace); // Header.Text / Header.RawText の違いを気にしていない } catch { return true; // XMLコメントの形式ミスはこのルールで検出しない } foreach (var xpathRule in rules) { if (xml.XPathEvaluate<XObject>(xpathRule.XPath).Any()) { this.Violate(element, element.Header.Location, xpathRule.Message); } } } return true; }
/// <summary> /// Initializes a new instance of the Destructor 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="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 Destructor( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(document, parent, ElementType.Destructor, "destructor " + 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.Ignore(unsafeCode); Param.Ignore(generated); // Static destructors are always public. if (this.Declaration.ContainsModifier(CsTokenType.Static)) { this.Declaration.AccessModifierType = AccessModifierType.Public; } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { var preprocessorToken = (from token in csElement.ElementTokens where token.LineNumber == violation.Line && token.CsTokenType == CsTokenType.PreprocessorDirective select token).FirstOrDefault(); if (preprocessorToken != null) { int underlineLength = 1; while (preprocessorToken.Text[underlineLength] == ' ' || preprocessorToken.Text[underlineLength] == '\t') { underlineLength++; } while (underlineLength < preprocessorToken.Text.Length && preprocessorToken.Text[underlineLength] != ' ' && preprocessorToken.Text[underlineLength] != '\t') { underlineLength++; } var startPoint = preprocessorToken.Location.StartPoint; var sourceRange = new SourceRange(startPoint.LineNumber, startPoint.IndexOnLine + 1, startPoint.LineNumber, startPoint.IndexOnLine + 1 + underlineLength); yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, sourceRange); } }
/// <summary> /// Initializes a new instance of the ClassBase class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="type"> /// The element type. /// </param> /// <param name="name"> /// The name of this 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="typeConstraints"> /// The list of type constraints on the element. /// </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 ClassBase( CsDocument document, CsElement parent, ElementType type, string name, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, ICollection<TypeParameterConstraintClause> typeConstraints, bool unsafeCode, bool generated) : base(document, parent, type, name, header, attributes, declaration, unsafeCode, generated) { Param.Ignore(document, parent, type, name, header, attributes, declaration, typeConstraints, unsafeCode, generated); this.typeConstraints = typeConstraints; // Set the parent of the type constraint clauses. if (typeConstraints != null) { Debug.Assert(typeConstraints.IsReadOnly, "The typeconstraints collection should be read-only."); foreach (TypeParameterConstraintClause constraint in typeConstraints) { constraint.ParentElement = this; } } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { SourcePoint? startPoint = null; SourcePoint? endPoint = null; foreach (var token in from token in csElement.ElementTokens where token.LineNumber == violation.Line && token.CsTokenType != CsTokenType.WhiteSpace select token) { if (token.CsTokenType == CsTokenType.Namespace) { startPoint = endPoint = new SourcePoint(token.Location.StartPoint.LineNumber, token.Location.StartPoint.IndexOnLine + 1); } else if (token.CsTokenType == CsTokenType.OpenCurlyBracket || token.CsTokenType == CsTokenType.EndOfLine) { if (startPoint != null) { var sourceRange = new SourceRange(startPoint.Value, endPoint.Value); yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, sourceRange); } yield break; } else if (startPoint != null) { endPoint = new SourcePoint(token.Location.EndPoint.LineNumber, token.Location.EndPoint.IndexOnLine + 2); } } }
/// <summary> /// Initializes a new instance of the Accessor class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="accessorType"> /// The type of the accessor. /// </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="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 Accessor( CsDocument document, CsElement parent, AccessorType accessorType, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(document, parent, ElementType.Accessor, declaration.Name + " accessor", header, attributes, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.Ignore(accessorType); Param.Ignore(header); Param.Ignore(attributes); Param.AssertNotNull(declaration, "declaration"); Param.Ignore(unsafeCode); Param.Ignore(generated); this.accessorType = accessorType; // Make sure the type and name match. Debug.Assert( (accessorType == AccessorType.Get && declaration.Name == "get") || (accessorType == AccessorType.Set && declaration.Name == "set") || (accessorType == AccessorType.Add && declaration.Name == "add") || (accessorType == AccessorType.Remove && declaration.Name == "remove"), "The accessor type does not match its name."); this.FillDetails(parent); }
internal Field(CsDocument document, CsElement parent, XmlHeader header, ICollection<Microsoft.StyleCop.CSharp.Attribute> attributes, Declaration declaration, TypeToken fieldType, bool unsafeCode, bool generated) : base(document, parent, ElementType.Field, "field " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { this.type = fieldType; this.isConst = base.Declaration.ContainsModifier(new CsTokenType[] { CsTokenType.Const }); this.isReadOnly = base.Declaration.ContainsModifier(new CsTokenType[] { CsTokenType.Readonly }); }
internal Method(CsDocument document, CsElement parent, XmlHeader header, ICollection<Microsoft.StyleCop.CSharp.Attribute> attributes, Declaration declaration, TypeToken returnType, IList<Parameter> parameters, ICollection<TypeParameterConstraintClause> typeConstraints, bool unsafeCode, bool generated) : base(document, parent, ElementType.Method, "method " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { this.returnType = returnType; this.parameters = parameters; this.typeConstraints = typeConstraints; if ((this.parameters.Count > 0) && base.Declaration.ContainsModifier(new CsTokenType[] { CsTokenType.Static })) { foreach (Parameter parameter in this.parameters) { if ((parameter.Modifiers & ParameterModifiers.This) != ParameterModifiers.None) { this.extensionMethod = true; } break; } } base.QualifiedName = CodeParser.AddQualifications(this.parameters, base.QualifiedName); if ((base.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1) && !base.Declaration.Name.StartsWith("this.", StringComparison.Ordinal)) { base.Declaration.AccessModifierType = AccessModifierType.Public; } if (typeConstraints != null) { foreach (TypeParameterConstraintClause clause in typeConstraints) { clause.ParentElement = this; } } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { CsToken potentialViolation = null; bool whitespaceFound = false; foreach (var token in this.getTokens(csElement).Flatten().Where(x => x.LineNumber == violation.Line)) { if (potentialViolation != null && token.CsTokenType == CsTokenType.WhiteSpace) { whitespaceFound = true; } else if (potentialViolation != null && whitespaceFound && isBannedFollower(token)) { yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, new SourceRange(potentialViolation.Location.StartPoint.LineNumber, potentialViolation.Location.StartPoint.IndexOnLine + 1, potentialViolation.Location.EndPoint.LineNumber, potentialViolation.Location.EndPoint.IndexOnLine + 2)); whitespaceFound = false; potentialViolation = null; } else if (this.reportIssueFor(token, violation)) { potentialViolation = token; whitespaceFound = false; } else { whitespaceFound = false; potentialViolation = null; } } }
/// <summary> /// Initializes a new instance of the UsingDirective class. /// </summary> /// <param name="document">The document that contains the element.</param> /// <param name="parent">The parent of the element.</param> /// <param name="declaration">The declaration code for this element.</param> /// <param name="generated">Indicates whether the code element was generated or written by hand.</param> /// <param name="namespace">The namespace being used.</param> /// <param name="alias">Optional alias for the namespace, if any.</param> internal UsingDirective( CsDocument document, CsElement parent, Declaration declaration, bool generated, string @namespace, string alias) : base(document, parent, ElementType.UsingDirective, "using " + declaration.Name, null, null, declaration, false, generated) { Param.Ignore(document); Param.Ignore(parent); Param.Ignore(declaration); Param.Ignore(generated); Param.AssertValidString(@namespace, "namespace"); Param.Ignore(alias); this.namespaceType = @namespace; if (alias != null) { this.alias = alias; } }
/// <summary> /// Determines whether the given element contains any partial members. /// </summary> /// <param name="element"> /// The element to check. /// </param> /// <returns> /// Returns true if the element contains at least one partial member. /// </returns> public static bool ContainsPartialMembers(CsElement element) { Param.AssertNotNull(element, "element"); if (element.ElementType == ElementType.Class || element.ElementType == ElementType.Struct || element.ElementType == ElementType.Interface) { if (element.Declaration.ContainsModifier(CsTokenType.Partial)) { return true; } } if (element.ElementType == ElementType.Root || element.ElementType == ElementType.Namespace || element.ElementType == ElementType.Class || element.ElementType == ElementType.Struct) { foreach (CsElement child in element.ChildElements) { if (ContainsPartialMembers(child)) { return true; } } } return false; }
/// <summary> /// Initializes a new instance of the Property class. /// </summary> /// <param name="document"> /// The document 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="returnType"> /// The property return type. /// </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 Property( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, TypeToken returnType, bool unsafeCode, bool generated) : base(document, parent, ElementType.Property, "property " + 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(returnType, "returnType"); Param.Ignore(unsafeCode); Param.Ignore(generated); this.returnType = returnType; // If this is an explicit interface member implementation and our access modifier // is currently set to private because we don't have one, then it should be public instead. if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal)) { this.Declaration.AccessModifierType = AccessModifierType.Public; } }
/// <summary> /// Initializes a new instance of the Field 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="fieldType">The type of the field.</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 Field( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, TypeToken fieldType, bool unsafeCode, bool generated) : base(document, parent, ElementType.Field, "field " + 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(fieldType, "fieldType"); Param.Ignore(unsafeCode); Param.Ignore(generated); this.type = fieldType; // Determine whether the item is const or readonly. this.isConst = this.Declaration.ContainsModifier(CsTokenType.Const); this.isReadOnly = this.Declaration.ContainsModifier(CsTokenType.Readonly); }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { CodePoint startPoint = null; CodePoint endPoint = null; bool emptyLine = true; foreach (var token in csElement.ElementTokens.Flatten().Where(x => x.LineNumber == violation.Line)) { if (startPoint == null) { startPoint = token.Location.StartPoint; endPoint = token.Location.EndPoint; emptyLine = token.CsTokenType == CsTokenType.WhiteSpace || token.CsTokenType == CsTokenType.EndOfLine; } if (token.CsTokenType != CsTokenType.WhiteSpace && token.CsTokenType != CsTokenType.EndOfLine) { if (emptyLine) { startPoint = token.Location.StartPoint; emptyLine = false; } endPoint = token.Location.EndPoint; } else if (token.CsTokenType == CsTokenType.EndOfLine) { yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, new SourceRange(startPoint.LineNumber, startPoint.IndexOnLine + 1, endPoint.LineNumber, endPoint.IndexOnLine + 2)); } } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { CsToken startToken = null; foreach (var token in from token in csElement.ElementTokens where violation.Line == token.Location.StartPoint.LineNumber && (token.CsTokenType == CsTokenType.OpenCurlyBracket || token.CsTokenType == CsTokenType.CloseCurlyBracket) select token) { if (token.CsTokenType == CsTokenType.OpenCurlyBracket) { startToken = token; continue; } if (token.CsTokenType == CsTokenType.CloseCurlyBracket) { var sourceRange = new SourceRange(startToken.Location.StartPoint.LineNumber, startToken.Location.StartPoint.IndexOnLine + 1, token.Location.EndPoint.LineNumber, token.Location.EndPoint.IndexOnLine + 2); yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, sourceRange); } } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { bool predecessorFound = true; CodeLocation issueLocation = null; foreach (var token in this.getTokens(csElement).Flatten().Where(x => x.LineNumber == violation.Line)) { if (!predecessorFound && !requiredFollowers.Contains(token.CsTokenType) && issueLocation != null) { yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, new SourceRange(issueLocation.StartPoint.LineNumber, issueLocation.StartPoint.IndexOnLine + 1, issueLocation.EndPoint.LineNumber, issueLocation.EndPoint.IndexOnLine + 2)); predecessorFound = false; issueLocation = null; } else if (reportIssueFor(token, violation)) { issueLocation = token.Location; } else if (requiredPredecessors.Contains(token.CsTokenType)) { predecessorFound = true; } else { predecessorFound = false; issueLocation = null; } } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { foreach (var operation in from x in enumerate(new ElementTypeFilter(LanguageElementType.LogicalOperation)) let logicalOperation = (LogicalOperation)x.ToLanguageElement() where logicalOperation.RecoveredRange.Start.Line == violation.Line && (logicalOperation.LeftSide.ElementType == LanguageElementType.LogicalOperation || logicalOperation.RightSide.ElementType == LanguageElementType.LogicalOperation) select logicalOperation) { var parentType = operators[operation.Name]; var leftChildType = operation.LeftSide.ElementType == LanguageElementType.LogicalOperation ? operators[operation.LeftSide.Name] : parentType; var rightChildType = operation.RightSide.ElementType == LanguageElementType.LogicalOperation ? operators[operation.RightSide.Name] : parentType; if (rightChildType > parentType) { yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, operation.RightSide.RecoveredRange); } else if (leftChildType > parentType) { yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, operation.LeftSide.RecoveredRange); } } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { foreach (var method in from x in enumerate(new ElementTypeFilter(LanguageElementType.Method)) let method = (DX.Method)x.ToLanguageElement() where method.RecoveredRange.Start.Line == violation.Line && method.IsStatic && method.IsConstructor && method.FirstChild == null select method) { yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, method.NameRange); } foreach (var statement in from x in enumerate(new ElementTypeFilter(deleteWhenEmpty)) let statement = x.ToLanguageElement() where statement.RecoveredRange.Start.Line == violation.Line && (statement.ElementType == LanguageElementType.Try || statement.FirstChild == null) select statement) { yield return new StyleCopCodeIssue(CodeIssueType.CodeSmell, statement.GetKeywordRange()); } }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { return this.issueLocators.SelectMany(locator => locator.GetCodeIssues(sourceCode, enumerate, violation, csElement)); }
public IEnumerable<StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func<ElementTypeFilter, IEnumerable<IElement>> enumerate, Violation violation, CsElement csElement) { return Enumerable.Empty<StyleCopCodeIssue>(); }
internal Property(CsDocument document, CsElement parent, XmlHeader header, ICollection<Microsoft.StyleCop.CSharp.Attribute> attributes, Declaration declaration, TypeToken returnType, bool unsafeCode, bool generated) : base(document, parent, ElementType.Property, "property " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { this.returnType = returnType; if ((base.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1) && !base.Declaration.Name.StartsWith("this.", StringComparison.Ordinal)) { base.Declaration.AccessModifierType = AccessModifierType.Public; } }
/// <summary> /// Initializes a new instance of the EmptyElement class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </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 EmptyElement(CsDocument document, CsElement parent, Declaration declaration, bool unsafeCode, bool generated) : base(document, parent, ElementType.EmptyElement, Strings.EmptyElement, null, null, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(declaration, "declaration"); Param.Ignore(unsafeCode); Param.Ignore(generated); }
private bool VisitElement(CsElement element, CsElement parentelement, object context) { if (element.ElementType == ElementType.Field) { VisitField((Field)element); } return true; }
/// <summary> /// Handles SA1502 violation. /// </summary> private void Handle1502(ViolationEventArgs e) { CsElement element = (CsElement)e.Element; if (ReadSetting(e, AllowConstructorsFor1502)) { if (element.ElementType == ElementType.Constructor) { return; } } m_parent.AddViolation( element, e.LineNumber, Rules.ElementMustNotBeOnSingleLine, element.FriendlyTypeText); }
/// <summary> /// Checks whether specified name is correct. /// </summary> private void CheckNamingRules( CsElement element, int?lineNumber, CurrentNamingSettings settings, string settingName, string nameToCheck) { if (settings.CheckNamingRule(settingName, nameToCheck)) { return; } AddViolation( element, lineNumber, settings, settingName, nameToCheck); }
/// <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); }
private bool VisitClass(CsElement element, CsElement parentElement, object context) { if (!(element is Class elClass)) { return(false); } if (elClass.BaseClass != nameof(Controller)) { AddViolation(elClass, PostfixNameRule); if (elClass.Attributes.All(x => x.Text != nameof(AuthorizeAttribute))) { elClass.WalkElement(VisitMethod); } } return(true); }
/// <summary> /// Verifies that elements have access modifiers. /// </summary> /// <param name="element">The element to check.</param> private void CheckForAccessModifier(CsElement element) { Param.AssertNotNull(element, "element"); if (element.ElementType == ElementType.Method || element.ElementType == ElementType.Property || element.ElementType == ElementType.Indexer || element.ElementType == ElementType.Event) { // A Method, property, indexer or event must have access an modifier unless it // is an explicit implementation of an interface member, in which case it is public by // default and you are not allowed to specify an access modifier. Partial methods are not allowed // to have access modifier so we skip those as well. if (!element.Declaration.AccessModifier && !element.Declaration.ContainsModifier(CsTokenType.Partial)) { if (element.Name.IndexOf(".", StringComparison.Ordinal) == -1 || element.Name.StartsWith("this.", StringComparison.Ordinal)) { this.AddViolation(element, Rules.AccessModifierMustBeDeclared, element.FriendlyTypeText); } } } else if (element.ElementType == ElementType.Class || element.ElementType == ElementType.Field || element.ElementType == ElementType.Enum || element.ElementType == ElementType.Struct || element.ElementType == ElementType.Interface || element.ElementType == ElementType.Delegate) { if (!element.Declaration.AccessModifier) { this.AddViolation(element, Rules.AccessModifierMustBeDeclared, element.FriendlyTypeText); } } else if (element.ElementType == ElementType.Constructor) { // If a constructor is not static it must have an access modifier. if (!element.Declaration.AccessModifier && !element.Declaration.ContainsModifier(CsTokenType.Static)) { this.AddViolation(element, Rules.AccessModifierMustBeDeclared, element.FriendlyTypeText); } } }
private void ValidateConstantAccessibility(CsElement element) { // not target element if (element.Generated || element.ElementType != ElementType.Field) { return; } // the ProtectedAndInternal case seems not applied to AccessModifier if (element.AccessModifier == AccessModifierType.Private || element.AccessModifier == AccessModifierType.Internal || element.ActualAccess == AccessModifierType.ProtectedAndInternal) { return; } AddViolation(element, Rules.ConstantMustRestrictedInAssembly); }
private bool RegionNameMustHaveFirstLetterCapitalized( CsElement element, CsElement parentElement, object context) { if (element.ElementType == ElementType.Root) { for (Node <CsToken> node = element.Tokens.First; node != element.Tokens.Last.Next; node = node.Next) { if (node.Value.CsTokenClass == CsTokenClass.RegionDirective) { var region = (Region)node.Value; if (region.Text.Contains("#region")) { var regionText = region.Text.Split(' '); if (regionText.Length <= 1) { this.AddViolation( element, node.Value.LineNumber, "RegionNameMustHaveFirstLetterCapitalized"); } else { if (!regionText[1].HasValue()) { this.AddViolation( element, node.Value.LineNumber, "RegionNameMustHaveFirstLetterCapitalized"); } else { var firstChar = regionText[1].Trim().ToCharArray(); if (firstChar.Length <= 1 || !char.IsUpper(firstChar[0])) { this.AddViolation( element, node.Value.LineNumber, "RegionNameMustHaveFirstLetterCapitalized"); } } } } } } } return(true); }
/// <summary> /// Checks that empty parenthesis do not exist for attributes. /// </summary> /// <param name="element">The element to check.</param> private void CheckParenthesisForAttributeConstructors(CsElement element) { Param.AssertNotNull(element, "element"); if (element.Attributes != null && element.Attributes.Count > 0) { foreach (var attribute in element.Attributes) { var attributeExpressions = attribute.AttributeExpressions; foreach (var attributeExpression in attributeExpressions) { if (attributeExpression.Initialization.ExpressionType == ExpressionType.MethodInvocation) { var invocationExpression = (MethodInvocationExpression)attributeExpression.Initialization; if (invocationExpression.Arguments.Count == 0) { var elementTokens = attribute.ChildTokens; // Check for parenthesis. for (Node <CsToken> tokenNode = elementTokens.First; tokenNode != elementTokens.Last; tokenNode = tokenNode.Next) { if (tokenNode.Value.CsTokenType == CsTokenType.OpenParenthesis) { Node <CsToken> nextToken = tokenNode.Next; if (nextToken.Value.CsTokenType == CsTokenType.CloseParenthesis) { this.AddViolation(element, tokenNode.Value.LineNumber, Rules.AttributeConstructorMustNotUseUnnecessaryParenthesis); } break; } } } break; } } } } }
public IEnumerable <StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func <ElementTypeFilter, IEnumerable <IElement> > enumerate, Violation violation, CsElement csElement) { int tabSize = sourceCode is FileSourceCode ? 4 : CodeRush.VSSettings.GetTabSettings(ParserLanguageID.CSharp).TabSize; int charIndex = 1; int start = 0; int end = 0; bool inTabs = false; foreach (char character in sourceCode.GetText(violation.Line)) { if (character == '\t') { if (inTabs) { end += tabSize; } else { start = charIndex; inTabs = true; end = charIndex + tabSize - ((charIndex - 1) % tabSize); } } else { if (inTabs) { inTabs = false; charIndex = end + 1; yield return(new StyleCopCodeIssue(CodeIssueType.CodeSmell, new SourceRange(violation.Line, start, violation.Line, end))); } else { charIndex++; } } } }
/// <summary> /// Analyzes indexer element. /// </summary> private void AnalyzeIndexer(CsElement element, CustomRulesSettings settings) { Indexer indexer = (Indexer)element; if (indexer.GetAccessor != null) { CheckSizeLimit( indexer.GetAccessor, Rules.PropertyMustNotContainMoreLinesThan, settings.PropertySizeOptions.Limit); } if (indexer.SetAccessor != null) { CheckSizeLimit( indexer.SetAccessor, Rules.PropertyMustNotContainMoreLinesThan, settings.PropertySizeOptions.Limit); } }
/// <summary> /// Analyzes property element. /// </summary> private void AnalyzeProperty(CsElement element, CustomRulesSettings settings) { Property property = (Property)element; if (property.GetAccessor != null) { CheckSizeLimit( property.GetAccessor, Rules.PropertyMustNotContainMoreLinesThan, settings.PropertySizeOptions.Limit); } if (property.SetAccessor != null) { CheckSizeLimit( property.SetAccessor, Rules.PropertyMustNotContainMoreLinesThan, settings.PropertySizeOptions.Limit); } }
/// <summary> /// Delegate for a callback executed when a statement is visited. /// </summary> /// <param name="statement">The statement being visited.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentElement">The parent element, if any.</param> /// <param name="context">The optional visitor context data.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool VisitStatement( Statement statement, Expression parentExpression, Statement parentStatement, CsElement parentElement, ref T context) { Param.AssertNotNull(statement, "statement"); Param.Ignore(parentExpression); Param.Ignore(parentStatement); Param.Ignore(parentElement); Param.Ignore(context); if (this.statementCallback != null) { return(this.statementCallback(statement, parentExpression, parentStatement, parentElement, context)); } return(true); }
/// <summary> /// Delegate for a callback executed when an expression is visited. /// </summary> /// <param name="expression">The expression being visited.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentElement">The parent element, if any.</param> /// <param name="context">The optional visitor context data.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool VisitExpression( Expression expression, Expression parentExpression, Statement parentStatement, CsElement parentElement, ref T context) { Param.AssertNotNull(expression, "expression"); Param.Ignore(parentExpression); Param.Ignore(parentStatement); Param.Ignore(parentElement); Param.Ignore(context); if (this.expressionCallback != null) { return(this.expressionCallback(expression, parentExpression, parentStatement, parentElement, context)); } return(true); }
/// <summary> /// Checks that parenthesis are used correctly within an arithmetic expression. /// </summary> /// <param name="element">The parent element.</param> /// <param name="expression">The expression to check.</param> private void CheckArithmeticExpressionParenthesis(CsElement element, ArithmeticExpression expression) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(expression, "expression"); if (expression.LeftHandSide.ExpressionType == ExpressionType.Arithmetic) { if (!this.CheckArithmeticParenthesisForExpressionAndChild( element, expression, (ArithmeticExpression)expression.LeftHandSide)) { return; } } if (expression.RightHandSide.ExpressionType == ExpressionType.Arithmetic) { this.CheckArithmeticParenthesisForExpressionAndChild( element, expression, (ArithmeticExpression)expression.RightHandSide); } }
/// <summary> /// Walks the children of the given query clause. /// </summary> /// <param name="clause">The clause.</param> /// <param name="parentClause">The parent clause, if any.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentElement">The parent element, if any.</param> /// <param name="context">The optional visitor context data.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool WalkQueryClause( QueryClause clause, QueryClause parentClause, Expression parentExpression, Statement parentStatement, CsElement parentElement, T context) { Param.Ignore(clause, parentClause, parentExpression, parentStatement, parentElement, context); if (clause != null) { T childContext = context; if (!this.VisitQueryClause(clause, parentClause, parentExpression, parentStatement, parentElement, ref childContext)) { return(false); } foreach (Expression childExpression in clause.ChildExpressions) { if (!this.WalkExpression(childExpression, parentExpression, parentStatement, parentElement, childContext)) { return(false); } } if (clause.QueryClauseType == QueryClauseType.Continuation) { QueryContinuationClause continuationClause = (QueryContinuationClause)clause; foreach (QueryClause childClause in continuationClause.ChildClauses) { if (!this.WalkQueryClause(childClause, clause, parentExpression, parentStatement, parentElement, childContext)) { return(false); } } } } return(true); }
/// <summary> /// Tries to find code element by line. /// </summary> private static bool FindByLineElementVisitor( CsElement element, CsElement parentElement, object context) { object[] args = (object[])context; int lineNumber = (int)args[0]; if (element.Location.StartPoint.LineNumber > lineNumber) { return(false); } if (element.Location.StartPoint.LineNumber <= lineNumber && element.Location.EndPoint.LineNumber >= lineNumber) { args[1] = element; } return(true); }
/// <summary> /// Processes the given element. /// </summary> /// <param name="element">The element being visited.</param> /// <param name="parentElement">The parent of the element.</param> /// <param name="topLevelElements">The number of classes and namespaces seen in the document.</param> private static void CheckFileContents( CsElement element, CsElement parentElement, TopLevelElements topLevelElements) { Param.AssertNotNull(element, "element"); Param.Ignore(parentElement); Param.AssertNotNull(topLevelElements, "topLevelElements"); if (element.ElementType == ElementType.Class) { if (parentElement == null || parentElement.ElementType == ElementType.Root || parentElement.ElementType == ElementType.Namespace) { topLevelElements.Classes.Add((Class)element); } } else if (element.ElementType == ElementType.Namespace) { topLevelElements.Namespaces.Add((Namespace)element); } }
/// <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 name follows length agreement. /// </summary> private void CheckNameLength( CsElement element, int?lineNumber, CurrentNamingSettings settings, string settingName, string nameToCheck) { if (settings.CheckNameLength(settingName, nameToCheck)) { return; } string friendlyName = settings.GetFriendlyName(settingName); string example = EntitySettingResources.CheckLengthExample; AddViolation( element, lineNumber, friendlyName, nameToCheck, example); }
public IEnumerable <StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func <ElementTypeFilter, IEnumerable <IElement> > enumerate, Violation violation, CsElement csElement) { CodePoint startPoint = null; CodePoint endPoint = null; foreach (var token in from token in csElement.ElementTokens where token.LineNumber == violation.Line && token.CsTokenType != CsTokenType.WhiteSpace select token) { if (token.CsTokenType == CsTokenType.OpenParenthesis || token.CsTokenType == CsTokenType.OpenSquareBracket) { startPoint = null; endPoint = null; } else if (startPoint == null) { startPoint = token.Location.StartPoint; endPoint = token.Location.EndPoint; } if (startPoint != null && endPoint != null && (token.CsTokenType == CsTokenType.CloseSquareBracket || token.CsTokenType == CsTokenType.CloseParenthesis || token.CsTokenType == CsTokenType.Comma)) { var sourceRange = new SourceRange(startPoint.LineNumber, startPoint.IndexOnLine + 1, endPoint.LineNumber, endPoint.IndexOnLine + 2); return(new[] { new StyleCopCodeIssue(CodeIssueType.CodeSmell, sourceRange) }); } endPoint = token.Location.EndPoint; } return(Enumerable.Empty <StyleCopCodeIssue>()); }
public IEnumerable <StyleCopCodeIssue> GetCodeIssues( ISourceCode sourceCode, Func <ElementTypeFilter, IEnumerable <IElement> > enumerate, Violation violation, CsElement csElement) { foreach (var token in csElement.ElementTokens.Flatten().Where( x => x.LineNumber == violation.Line && (x.CsTokenType == CsTokenType.Other || x.CsTokenType == CsTokenType.Add || x.CsTokenType == CsTokenType.Remove || x.CsTokenType == CsTokenType.Get || x.CsTokenType == CsTokenType.Set) && csElement.Name.Contains(x.Text) && this.reportViolation(x))) { var startPoint = token.Location.StartPoint; var endPoint = token.Location.EndPoint; var range = new SourceRange(startPoint.LineNumber, startPoint.IndexOnLine + 1, endPoint.LineNumber, endPoint.IndexOnLine + 2); yield return(new StyleCopCodeIssue(CodeIssueType.CodeSmell, range)); } }
/// <summary> /// Initializes a new instance of the CodeWalker class. /// </summary> /// <param name="element">The element to walk through.</param> /// <param name="elementCallback">Callback executed when an element is visited.</param> /// <param name="statementCallback">Callback executed when a statement is visited.</param> /// <param name="expressionCallback">Callback executed when an expression is visited.</param> /// <param name="queryClauseCallback">Callback executed when a query clause is visited.</param> /// <param name="context">The optional visitor context data.</param> private CodeWalker( CsElement element, CodeWalkerElementVisitor <T> elementCallback, CodeWalkerStatementVisitor <T> statementCallback, CodeWalkerExpressionVisitor <T> expressionCallback, CodeWalkerQueryClauseVisitor <T> queryClauseCallback, T context) { Param.AssertNotNull(element, "element"); Param.Ignore(elementCallback); Param.Ignore(statementCallback); Param.Ignore(expressionCallback); Param.Ignore(queryClauseCallback); Param.Ignore(context); this.elementCallback = elementCallback; this.statementCallback = statementCallback; this.expressionCallback = expressionCallback; this.queryClauseCallback = queryClauseCallback; this.WalkElement(element, element.FindParentElement(), context); }
/// <summary> /// Analyzes statements for getting labels. /// </summary> private static bool GetLabelsStatementVisitor( Statement statement, Expression parentExpression, Statement parentStatement, CsElement parentElement, List <LabelItem> result) { if (statement.StatementType != StatementType.Label) { return(true); } LabelStatement label = (LabelStatement)statement; result.Add(new LabelItem { Name = label.Identifier.Text, Tokens = label.Tokens, LineNumber = label.LineNumber }); return(true); }
/// <summary> /// Delegate for a callback executed when a query clause is visited. /// </summary> /// <param name="clause">The query clause being visited.</param> /// <param name="parentClause">The parent query clause, if any.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentElement">The parent element, if any.</param> /// <param name="context">The optional visitor context data.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool VisitQueryClause( QueryClause clause, QueryClause parentClause, Expression parentExpression, Statement parentStatement, CsElement parentElement, ref T context) { Param.AssertNotNull(clause, "clause"); Param.Ignore(parentClause); Param.Ignore(parentExpression); Param.Ignore(parentStatement); Param.Ignore(parentElement); Param.Ignore(context); if (this.queryClauseCallback != null) { return(this.queryClauseCallback( clause, parentClause, parentExpression, parentStatement, parentElement, context)); } return(true); }
/// <summary> /// Tries to find expression by line. /// </summary> private static bool FindByLineExpressionVisitor( Expression expression, Expression parentExpression, Statement parentStatement, CsElement parentElement, object context) { object[] args = (object[])context; int lineNumber = (int)args[0]; if (expression.Location.StartPoint.LineNumber > lineNumber) { return(false); } if (expression.Location.StartPoint.LineNumber <= lineNumber && expression.Location.EndPoint.LineNumber >= lineNumber) { args[1] = expression; } return(true); }
public static void Start( CsElement element, CodeWalkerElementVisitor <T> elementCallback, CodeWalkerStatementVisitor <T> statementCallback, CodeWalkerExpressionVisitor <T> expressionCallback, CodeWalkerQueryClauseVisitor <T> queryClauseCallback, T context) { Param.AssertNotNull(element, "element"); Param.Ignore(elementCallback); Param.Ignore(statementCallback); Param.Ignore(expressionCallback); Param.Ignore(queryClauseCallback); Param.Ignore(context); new CodeWalker <T>( element, elementCallback, statementCallback, expressionCallback, queryClauseCallback, context); }
/// <summary> /// Records information about the given element, under the given node. /// </summary> /// <param name="element"> /// The element to record. /// </param> /// <param name="parentNode"> /// The Xml node to record this element beneath. /// </param> /// <returns> /// Returns the new Xml node describing this element. /// </returns> private static XmlNode RecordElement(CsElement element, XmlNode parentNode) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(parentNode, "parentNode"); // Create a new node for this element and add it to the parent. XmlNode elementNode = parentNode.OwnerDocument.CreateElement("Element"); parentNode.AppendChild(elementNode); // Add the name and type of the element. XmlAttribute name = parentNode.OwnerDocument.CreateAttribute("Name"); name.Value = element.Declaration.Name; elementNode.Attributes.Append(name); XmlAttribute type = parentNode.OwnerDocument.CreateAttribute("Type"); type.Value = element.GetType().Name; elementNode.Attributes.Append(type); return(elementNode); }
/// <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 (ArgumentTokensMatchStringEmpty(secondArgument)) { // The message argument contains an empty string or null. this.AddViolation(element, debugAssertMethodCall.LineNumber, Rules.DebugAssertMustProvideMessageText); } }
/// <summary> /// Walks the children of the given statement. /// </summary> /// <param name="statement">The statement.</param> /// <param name="parentExpression">The parent expression, if any.</param> /// <param name="parentStatement">The parent statement, if any.</param> /// <param name="parentElement">The parent element, if any.</param> /// <param name="context">The optional visitor context data.</param> /// <returns>Returns true to continue, or false to stop the walker.</returns> private bool WalkStatement( Statement statement, Expression parentExpression, Statement parentStatement, CsElement parentElement, T context) { Param.Ignore(statement, parentExpression, parentStatement, parentElement, context); if (statement != null) { T childContext = context; if (!this.VisitStatement(statement, parentExpression, parentStatement, parentElement, ref childContext)) { return(false); } foreach (Expression childExpression in statement.ChildExpressions) { if (!this.WalkExpression(childExpression, parentExpression, statement, parentElement, childContext)) { return(false); } } foreach (Statement childStatement in statement.ChildStatements) { if (!this.WalkStatement(childStatement, parentExpression, statement, parentElement, childContext)) { return(false); } } } return(true); }
private void ExpressionWalk(Expression expression, CsElement parentElement) { foreach (var child in expression.ChildExpressions) { if (child.Tokens.Count(t => t.CsTokenType == CsTokenType.String && t.Location.StartPoint.LineNumber != t.Location.EndPoint.LineNumber) == 0 && expression.Tokens.Count(t => t.CsTokenType == CsTokenType.String && t.Location.StartPoint.LineNumber != t.Location.EndPoint.LineNumber) == 0) { if (child.LineNumber != expression.LineNumber) { var minIndex = parentElement.Tokens.Where(e => e.LineNumber == child.LineNumber && e.CsTokenType != CsTokenType.WhiteSpace).Min(t => t.Location.StartPoint.IndexOnLine); if (parentElement.Tokens.FirstOrDefault(t => t.LineNumber == child.LineNumber && t.Location.StartPoint.IndexOnLine == GetMinIndex(parentElement, child.LineNumber)) .CsTokenType != CsTokenType.CloseCurlyBracket) { if (minIndex - GetMinIndex(parentElement, expression.LineNumber) != _tabSpaces) { var tok = expression.Tokens.FirstOrDefault(t => t.Location.StartPoint.LineNumber == child.LineNumber); if (expression.ExpressionType == ExpressionType.MethodInvocation) { if (CheckPreviousTokens(parentElement, expression, child.LineNumber, GetMinIndex(parentElement, child.LineNumber))) { continue; } } this.AddViolation(parentElement, child.LineNumber, "MoreOrLessThenOneTabToRightPosition"); continue; } } } ExpressionWalk(child, parentElement); } } }