/// <summary> /// Checks length of specified code line. /// </summary> private void CheckLineLength( CsDocument document, string currentLine, int currentLineNumber, CustomRulesSettings settings) { int length = 0; foreach (char c in currentLine) { if (c == '\t') { length += settings.CharLimitOptions.TabSize.Value; } else { length += 1; } } if (length > settings.CharLimitOptions.Limit.Value) { AddViolation( document, currentLineNumber, Rules.CodeLineMustNotBeLongerThan, settings.CharLimitOptions.Limit.Value, length); } }
/// <summary> /// Analyzes method element. /// </summary> private void AnalyzeMethod(CsElement element, CustomRulesSettings settings) { CheckSizeLimit( element, Rules.MethodMustNotContainMoreLinesThan, settings.MethodSizeOptions.Limit); }
/// <summary> /// Analyzes specified element. /// </summary> private void AnalyzeElement(CsElement element, CustomRulesSettings settings) { switch (element.ElementType) { case ElementType.Constructor: AnalyzeConstructor(element, settings); break; case ElementType.Destructor: AnalyzeDestructor(element, settings); break; case ElementType.Indexer: AnalyzeIndexer(element, settings); break; case ElementType.Method: AnalyzeMethod(element, settings); break; case ElementType.Property: AnalyzeProperty(element, settings); break; } }
/// <summary> /// Analyzes source code as plain text. /// </summary> private void AnalyzePlainText(CsDocument document, CustomRulesSettings settings) { string source; using (TextReader reader = document.SourceCode.Read()) { source = reader.ReadToEnd(); } List <string> lines = new List <string>( source.Split( new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)); for (int i = 0; i < lines.Count; i++) { int currentLineNumber = i + 1; string currentLine = lines[i]; string previousLine = i > 0 ? lines[i - 1] : null; CheckLineEnding(document, currentLine, currentLineNumber); CheckIndentation(document, currentLine, previousLine, currentLineNumber, settings); CheckLineLength(document, currentLine, currentLineNumber, settings); } CheckLastLine(document, source, lines.Count, settings); }
/// <summary> /// Analyzes a collection of elements. /// </summary> private void AnalyzeElements(IEnumerable <CsElement> elements, CustomRulesSettings settings) { foreach (CsElement element in elements) { AnalyzeElement(element, settings); AnalyzeElements(element.ChildElements, settings); } }
/// <summary> /// Analyzes source document. /// </summary> public void AnalyzeDocument(CodeDocument document) { CustomRulesSettings settings = new CustomRulesSettings(); settings.Initialize(m_parent, document); CsDocument doc = (CsDocument)document; AnalyzePlainText(doc, settings); AnalyzeElements(doc.RootElement.ChildElements, settings); }
/// <summary> /// Checks indentation in specified code line. /// </summary> private void CheckIndentation( CsDocument document, string currentLine, string previousLine, int currentLineNumber, CustomRulesSettings settings) { if (currentLine.Trim().Length == 0) { return; } string currentIndent = ExtractIndentation(currentLine); bool failed = true; switch (settings.IndentOptions.Mode) { case IndentMode.Tabs: failed = currentIndent.Contains(" "); break; case IndentMode.Spaces: failed = currentIndent.Contains("\t"); break; case IndentMode.Both: failed = currentIndent.Contains(" ") && currentIndent.Contains("\t"); break; } if (!failed) { return; } if (settings.IndentOptions.AllowPadding) { if (previousLine != null) { string previousIndent = ExtractIndentation(previousLine); if (IsPaddingAllowed(document, currentIndent, previousIndent, currentLineNumber)) { return; } } } AddViolation( document, currentLineNumber, Rules.CheckAllowedIndentationCharacters, settings.IndentOptions.GetContextValues()); }
/// <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> /// 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> /// Checks the last code line. /// </summary> private void CheckLastLine( CsDocument document, string sourceText, int lastLineNumber, CustomRulesSettings settings) { if (sourceText.Length == 0) { return; } char lastChar = sourceText[sourceText.Length - 1]; bool endsWithLineBreak = lastChar == '\r' || lastChar == '\n'; bool passed = false; switch (settings.LastLineOptions.Mode) { case LastLineMode.Empty: passed = endsWithLineBreak; break; case LastLineMode.NotEmpty: passed = !endsWithLineBreak; break; } if (!passed) { AddViolation( document, lastLineNumber, Rules.CheckWhetherLastCodeLineIsEmpty, settings.LastLineOptions.GetContextValues()); } }