//#################### PUBLIC METHODS #################### #region /// <summary> /// Computes line count metrics for the specified input text. /// </summary> /// <param name="input">The input text for which to compute line count metrics.</param> /// <returns>The computed metrics.</returns> public static LineCounts ComputeLineCounts(string input) { var counts = new LineCounts(); var context = new Context(); char?cur, prev = null; while ((cur = GetNext(input, context)) != null) { if (IsNewLine(cur)) { RegisterNewLine(counts, context); cur = null; } else if (cur == '*' && prev == '/') { ReadMultiLineComment(input, counts, context); cur = null; } else if (cur == '/' && prev == '/') { ReadEOLComment(input, context); context.HasComment = true; cur = null; } else if (cur == '"') { ReadRestOfString(input, context); context.HasCode = true; cur = null; } else if (cur == '\'') { ReadRestOfChar(input, context); context.HasCode = true; cur = null; } else if (!IsWhitespace(cur) && cur != '/') // exclude '/' to avoid counting comments as code { context.HasCode = true; } prev = cur; } // The final line of text should always be counted, even if it's empty. RegisterNewLine(counts, context); return(counts); }
/// <summary> /// Consumes the input text up to the end of a multi-line comment. /// </summary> /// <param name="input">The input text.</param> /// <param name="counts">The line count metrics for the input text.</param> /// <param name="context">The contextual information required during line counting.</param> private static void ReadMultiLineComment(string input, LineCounts counts, Context context) { char?cur = '\0', prev = null; context.HasComment = true; while (cur != null && ((cur = GetNext(input, context)) != '/' || prev != '*')) { if (IsNewLine(cur)) { RegisterNewLine(counts, context); context.HasComment = true; } prev = cur; } }
/// <summary> /// Updates the line count metrics when a newline character is seen, and resets /// the code and comment flags in the context ready to process the next line. /// </summary> /// <param name="counts">The line count metrics for the input text.</param> /// <param name="context">The contextual information required during line counting.</param> private static void RegisterNewLine(LineCounts counts, Context context) { ++counts.Total; if (context.HasCode) { ++counts.Code; context.HasCode = false; } if (context.HasComment) { ++counts.Comment; context.HasComment = false; } }
//#################### PUBLIC METHODS #################### #region public override bool Equals(Object other) { LineCounts rhs = other as LineCounts; return(rhs != null && Total == rhs.Total && Code == rhs.Code && Comment == rhs.Comment); }