Skip to content

Instantly share code, notes, and snippets.

@davidwhitney
Created March 30, 2015 13:15
Show Gist options
  • Save davidwhitney/9bdaea45a1ac2f71ee12 to your computer and use it in GitHub Desktop.
Save davidwhitney/9bdaea45a1ac2f71ee12 to your computer and use it in GitHub Desktop.
DEATH TO ALL FALSE COMMENTS
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NUnit.Framework;
namespace rostest
{
[TestFixture]
public class Class1
{
private CommentHoover _hoover;
[SetUp]
public void Setup()
{
_hoover = new CommentHoover();
}
[Test]
public void Clean_GivenSingleNarrativeComment_KeepsComment()
{
var code = "// comment";
var output = _hoover.Clean(code);
Assert.That(output, Is.EqualTo(code));
}
[Test]
public void Clean_GivenSingleLineOfCode_ReturnsSame()
{
var code = "Console.WriteLine(\"hi\");";
var output = _hoover.Clean(code);
Assert.That(output, Is.EqualTo(code));
}
[TestCase("// Console.WriteLine(\" hi \");")]
[TestCase("// Debug.WriteLine(\" hi \");")]
//[TestCase("// Some.Api(\" hi \");")]
public void Clean_GivenSingleCommentOfCodeWithQuotedWord_RemovesComment(string code)
{
var output = _hoover.Clean(code);
Assert.That(output, Is.Empty);
}
[Test]
public void Clean_GivenCommentAndCodeLine_ReturnsJustCodeLine()
{
var code = "Console.WriteLine(\"hi\");" + Environment.NewLine +
"//Console.WriteLine(\"hi\");";
var output = _hoover.Clean(code);
Assert.That(output, Is.EqualTo("Console.WriteLine(\"hi\");"));
}
[Test]
public void Clean_GivenCodeWithNarrativeComment_ReturnsBothLines()
{
var code = "// Performs a console writeline" + Environment.NewLine +
"Console.WriteLine(\"hi\");";
var output = _hoover.Clean(code);
Assert.That(output, Is.EqualTo(code));
}
[Test]
public void Clean_GivenCodeWithCommentBlock_CleansBlock()
{
var code = "/* Console.WriteLine(\"hi\");" + Environment.NewLine +
"Console.WriteLine(\"hi\");" + Environment.NewLine +
"*/" + Environment.NewLine +
"Console.WriteLine(\"yay\");";
var output = _hoover.Clean(code);
Assert.That(output, Is.EqualTo("Console.WriteLine(\"yay\");"));
}
[Test]
public void Clean_GivenCodeWithXDoc_KeepsComment()
{
var code = "/// <summary>a</summary>" + Environment.NewLine +
"public static void Main() { }";
var output = _hoover.Clean(code);
Assert.That(output, Is.EqualTo(code));
}
}
public class CommentHoover
{
private static readonly string[] Words;
static CommentHoover()
{
Words = File.ReadAllLines("words.txt").Select(x=>x.ToLower()).ToArray();
}
public string Clean(string code)
{
var removals = new List<string>();
List<string> captureBuffer = null;
var lines = code.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
foreach (var line in lines)
{
var trimmed = line.Trim();
if (StartCapture(trimmed))
{
captureBuffer = new List<string>();
}
if (captureBuffer != null)
{
if (!CommentIsEnglish(line)
&& !CommentIsXDoc(line))
{
captureBuffer.Add(line);
}
}
if (EndCapture(trimmed))
{
if (captureBuffer.Any())
{
removals.Add(string.Join(Environment.NewLine, captureBuffer));
}
captureBuffer = null;
}
}
return removals.Aggregate(code, (current, removal) => current.Replace(removal, ""))
.Trim();
}
private bool CommentIsXDoc(string line)
{
return line.StartsWith("///");
}
private static bool StartCapture(string trimmed)
{
return trimmed.StartsWith("/*") || trimmed.StartsWith("//");
}
private static bool EndCapture(string trimmed)
{
return trimmed.StartsWith("//") || trimmed.EndsWith("*/");
}
private static bool CommentIsEnglish(string line)
{
var commentWords = line.ToLower().Split(' ');
return commentWords.Any(word => Words.Contains(word))
&& !line.Contains("WriteLine");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment