Skip to content

Commit

Permalink
WI00405814: Analyzer to warn against manually specified path separato…
Browse files Browse the repository at this point in the history
…rs. (#146)

* Add basic scaffolding
* Add initial tests
* Fix tests, add negative tests for string constants
* Initial implementation work
* Fix up some '// TODO' false-positives
* simplify
* code fix for string literal arguments
* Add code fix support for interpolated strings
* Simplify, and set the stage for recursion
* Add worlds most naive AddExpression fixer
* binary expression hard mode
* allow paths that are heavily platform-specific
* minor optimization (I think)
* Add test case for Path.[Alt]DirectorySeparatorChar just in case
* Fix bug in interpolated string code-fix
* Rename test suite
* Add tests for array initialization
* Rename test suite
* Add tests for explicit array init
* Add support for array initialization syntax
* Handle older target frameworks and older lang versions
* Remove unnecesary project config
* simplify
  • Loading branch information
yaakov-h authored May 20, 2021
1 parent 474bd3a commit c0daf0c
Show file tree
Hide file tree
Showing 24 changed files with 1,099 additions and 0 deletions.
1 change: 1 addition & 0 deletions WTG.Analyzers.Test/AnalyzerAndCodeFixTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace WTG.Analyzers.Test
[TestFixture(TypeArgs = new[] { typeof(DeconstructionAnalyzer), typeof(DeconstructionCodeFixProvider) })]
[TestFixture(TypeArgs = new[] { typeof(DiscardThrowAnalyzer), typeof(DiscardThrowCodeFixProvider) })]
[TestFixture(TypeArgs = new[] { typeof(EmitAnalyzer), typeof(EmitCodeFixProvider) })]
[TestFixture(TypeArgs = new[] { typeof(FileSystemPathsAnalyzer), typeof(FileSystemPathsCodeFixProvider) })]
[TestFixture(TypeArgs = new[] { typeof(FlagsAnalyzer), typeof(FlagsCodeFixProvider) })]
[TestFixture(TypeArgs = new[] { typeof(LinqAnalyzer), typeof(LinqCodeFixProvider) })]
[TestFixture(TypeArgs = new[] { typeof(NullComparisonAnalyzer), typeof(NullComparisonCodeFixProvider) })]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.IO;

class Foo
{
const string WindowsPath = "My Path";
const string LinuxPath = "mypath";

public static void Method()
{
DoThingWithFile(Path.Combine("parent", WindowsPath));
DoThingWithFile(Path.Combine("parent", LinuxPath));
DoThingWithFile(Path.Combine(WindowsPath, "child"));
DoThingWithFile(Path.Combine(LinuxPath, "child"));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.IO;

class Foo
{
const string ChildPath = "MyCoolDir";

public static void Method()
{
DoThingWithFile(Path.Combine("C:\\Blah", "My Cool Dir"));
DoThingWithFile(Path.Combine("/usr/bin", "vim"));
DoThingWithFile(Path.Combine("/", "opt", "homebrew"));
DoThingWithFile(Path.Combine(@"\\?\C:\Blah", "My Cool Dir"));
DoThingWithFile(Path.Combine(@"\\?\UNC\server\C$\Blah", "My Cool Dir"));
DoThingWithFile(Path.Combine(@"\\server\C$\Blah", "My Cool Dir"));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.IO;

class Foo
{
public static void Method(int a)
{
DoThingWithFile(Path.Combine("parent", $"child{a}"));
DoThingWithFile(Path.Combine("parent", @"abcd"));
DoThingWithFile(Path.Combine("parent", $@"abc{a}"));
DoThingWithFile(Path.Combine("parent", "child" + a.ToString("X")));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.IO;

class Foo
{
public static void Method()
{
DoThingWithFile(Path.Combine("parent", "foo\\bar"));
DoThingWithFile(Path.Combine("parent", "foo/bar"));
}

static void DoThingWithFile(string file)
{
}
}

namespace System.IO
{
public static class Path
{
public static string Combine(string path1, string path2) { throw null; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<diagnostics id="WTG2008" message="Do not specify path separators in string literals that represent filesystem paths." severity="Warning">
<languageVersion>3.0</languageVersion>
</diagnostics>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.IO;

class Foo
{
public static void Method()
{
DoThingWithFile(Path.Combine("parent", "foo\\bar"));
DoThingWithFile(Path.Combine("parent", "foo/bar"));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<diagnostics id="WTG2008" message="Do not specify path separators in string literals that represent filesystem paths." severity="Warning">
<diagnostic>
<location>Test0.cs: (10,42-62)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (11,42-62)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (12,32-52)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (13,32-52)</location>
</diagnostic>
</diagnostics>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.IO;

class Foo
{
const string GrandchildSubpathWin = "child\\grandchild";
const string GrandchildSubpathLin = "child/grandchild";

public static void Method()
{
DoThingWithFile(Path.Combine("parent", GrandchildSubpathWin));
DoThingWithFile(Path.Combine("parent", GrandchildSubpathLin));
DoThingWithFile(Path.Combine(GrandchildSubpathWin, "great-grandchild"));
DoThingWithFile(Path.Combine(GrandchildSubpathLin, "great-grandchild"));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.IO;

class Foo
{
public static void Method()
{
DoThingWithFile(Path.Combine("parent" + Path.DirectorySeparatorChar + "child", "grandchild"));
DoThingWithFile(Path.Combine("parent" + Path.AltDirectorySeparatorChar + "child", "grandchild"));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<diagnostics id="WTG2008" message="Do not specify path separators in string literals that represent filesystem paths." severity="Warning">
<diagnostic>
<location>Test0.cs: (10,57-76)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (11,57-76)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (12,57-89)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (13,57-89)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (14,57-89)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (15,57-91)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (16,57-91)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (17,57-82)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (18,57-82)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (19,57-101)</location>
</diagnostic>
</diagnostics>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.IO;

class Foo
{
const string Child = "grandchild";
const string GrandchildFolderName = "grandchild";

public static void Method()
{
DoThingWithFile(Path.Combine(new string[] { "parent", "child", "grandchild" }));
DoThingWithFile(Path.Combine(new string[] { "parent", "child", "grandchild" }));
DoThingWithFile(Path.Combine(new string[] { "parent", "child", GrandchildFolderName }));
DoThingWithFile(Path.Combine(new string[] { "parent", "child", GrandchildFolderName }));
DoThingWithFile(Path.Combine(new string[] { "parent", "child", GrandchildFolderName }));
DoThingWithFile(Path.Combine(new string[] { "parent", Child, GrandchildFolderName }));
DoThingWithFile(Path.Combine(new string[] { "parent", Child, GrandchildFolderName }));
DoThingWithFile(Path.Combine(new string[] { "parent", "child", "grandchild" + 123 }));
DoThingWithFile(Path.Combine(new string[] { "parent", 123 + "child", "grandchild" }));
DoThingWithFile(Path.Combine(new string[] { "parent", "child", $"prefixed{GrandchildFolderName}.001" }));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.IO;

class Foo
{
const string Child = "grandchild";
const string GrandchildFolderName = "grandchild";

public static void Method()
{
DoThingWithFile(Path.Combine(new string[] { "parent", "child\\grandchild" }));
DoThingWithFile(Path.Combine(new string[] { "parent", @"child\grandchild" }));
DoThingWithFile(Path.Combine(new string[] { "parent", $"child\\{GrandchildFolderName}" }));
DoThingWithFile(Path.Combine(new string[] { "parent", "child\\" + GrandchildFolderName }));
DoThingWithFile(Path.Combine(new string[] { "parent", @"child\" + GrandchildFolderName }));
DoThingWithFile(Path.Combine(new string[] { "parent", $"{Child}\\{GrandchildFolderName}" }));
DoThingWithFile(Path.Combine(new string[] { "parent", $@"{Child}\{GrandchildFolderName}" }));
DoThingWithFile(Path.Combine(new string[] { "parent", @"child\grandchild" + 123 }));
DoThingWithFile(Path.Combine(new string[] { "parent", 123 + @"child\grandchild" }));
DoThingWithFile(Path.Combine(new string[] { "parent", $"child\\prefixed{GrandchildFolderName}.001" }));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.IO;

class Foo
{
public static void Method()
{
DoThingWithFile(Path.Combine("parent", "child", "grandchild"));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<diagnostics id="WTG2008" message="Do not specify path separators in string literals that represent filesystem paths." severity="Warning">
<diagnostic>
<location>Test0.cs: (10,50-69)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (11,50-69)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (12,50-82)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (13,50-82)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (14,50-82)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (15,50-84)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (16,50-84)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (17,50-75)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (18,50-75)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (19,50-94)</location>
</diagnostic>
</diagnostics>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.IO;

class Foo
{
const string Child = "grandchild";
const string GrandchildFolderName = "grandchild";

public static void Method()
{
DoThingWithFile(Path.Combine(new[] { "parent", "child", "grandchild" }));
DoThingWithFile(Path.Combine(new[] { "parent", "child", "grandchild" }));
DoThingWithFile(Path.Combine(new[] { "parent", "child", GrandchildFolderName }));
DoThingWithFile(Path.Combine(new[] { "parent", "child", GrandchildFolderName }));
DoThingWithFile(Path.Combine(new[] { "parent", "child", GrandchildFolderName }));
DoThingWithFile(Path.Combine(new[] { "parent", Child, GrandchildFolderName }));
DoThingWithFile(Path.Combine(new[] { "parent", Child, GrandchildFolderName }));
DoThingWithFile(Path.Combine(new[] { "parent", "child", "grandchild" + 123 }));
DoThingWithFile(Path.Combine(new[] { "parent", 123 + "child", "grandchild" }));
DoThingWithFile(Path.Combine(new[] { "parent", "child", $"prefixed{GrandchildFolderName}.001" }));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.IO;

class Foo
{
const string Child = "grandchild";
const string GrandchildFolderName = "grandchild";

public static void Method()
{
DoThingWithFile(Path.Combine(new[] { "parent", "child\\grandchild" }));
DoThingWithFile(Path.Combine(new[] { "parent", @"child\grandchild" }));
DoThingWithFile(Path.Combine(new[] { "parent", $"child\\{GrandchildFolderName}" }));
DoThingWithFile(Path.Combine(new[] { "parent", "child\\" + GrandchildFolderName }));
DoThingWithFile(Path.Combine(new[] { "parent", @"child\" + GrandchildFolderName }));
DoThingWithFile(Path.Combine(new[] { "parent", $"{Child}\\{GrandchildFolderName}" }));
DoThingWithFile(Path.Combine(new[] { "parent", $@"{Child}\{GrandchildFolderName}" }));
DoThingWithFile(Path.Combine(new[] { "parent", @"child\grandchild" + 123 }));
DoThingWithFile(Path.Combine(new[] { "parent", 123 + @"child\grandchild" }));
DoThingWithFile(Path.Combine(new[] { "parent", $"child\\prefixed{GrandchildFolderName}.001" }));
}

static void DoThingWithFile(string file)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<diagnostics id="WTG2008" message="Do not specify path separators in string literals that represent filesystem paths." severity="Warning">
<diagnostic>
<location>Test0.cs: (10,42-61)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (11,42-61)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (12,42-74)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (13,42-74)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (14,42-74)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (15,42-76)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (16,42-76)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (17,42-67)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (18,42-67)</location>
</diagnostic>
<diagnostic>
<location>Test0.cs: (19,42-86)</location>
</diagnostic>
</diagnostics>
Loading

0 comments on commit c0daf0c

Please sign in to comment.