Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,31 @@ static void Main()
await VerifyCSharpFix(test, fixTest);
}

[TestMethod]
[Description("Analyzer should not report on generated code")]
public void AttributesOnSameLine_InGeneratedCode_NoDiagnostic()
{
string test = @"using System;
using System.CodeDom.Compiler;

namespace ConsoleApp
{
class AAttribute : Attribute { }
class BAttribute : Attribute { }

[GeneratedCode(""tool"", ""1.0"")]
class Program
{
[A][B]
static void Main()
{
}
}
}";
// Should NOT produce a diagnostic for attributes on same line inside generated code
VerifyCSharpDiagnostic(test);
}

private static DiagnosticResult GetExpectedDiagnosticResult(int line, int col)
{
return new DiagnosticResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,27 @@ public class FavorEnumeratorDirectoryCallsTests : CodeFixVerifier
[TestMethod]
public void UsageOfDirectoryGetFiles_ProducesInfoMessage()
{
string source = @"using System;
using System.Diagnostics;
using System.IO;
string source = """
using System;
using System.Diagnostics;
using System.IO;

namespace ConsoleApp5
{
class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory);
namespace ConsoleApp5
{
class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory);

foreach (string file in files)
{
Console.WriteLine($""File found: ${file}"");
}
}
}
}";
foreach (string file in files)
{
Console.WriteLine($"File found: ${file}");
}
}
}
}
""";
VerifyCSharpDiagnostic(source,
new DiagnosticResult
{
Expand All @@ -46,26 +48,28 @@ static void Main(string[] args)
[TestMethod]
public void DeclarationOfOtherDirectoryGetFiles_ProducesNothing()
{
string source = @"using System;
using System.Diagnostics;
using System.IO;
string source = """
using System;
using System.Diagnostics;
using System.IO;

namespace ConsoleApp5
{
public static class Directory {
public static string[] GetFiles(string path) => Array.Empty<string>();
}
namespace ConsoleApp5
{
public static class Directory {
public static string[] GetFiles(string path) => Array.Empty<string>();
}


class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory);
class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory);

}
}
}";
}
}
}
""";
VerifyCSharpDiagnostic(source);
}

Expand All @@ -79,25 +83,27 @@ protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer()
[TestMethod]
public void UsageOfDirectoryGetDirectories_ProducesInfoMessage()
{
string source = @"using System;
using System.Diagnostics;
using System.IO;
string source = """
using System;
using System.Diagnostics;
using System.IO;

namespace ConsoleApp5
{
class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetDirectories(AppDomain.CurrentDomain.BaseDirectory);
namespace ConsoleApp5
{
class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetDirectories(AppDomain.CurrentDomain.BaseDirectory);

foreach (string file in files)
{
Console.WriteLine($""File found: ${file}"");
}
}
}
}";
foreach (string file in files)
{
Console.WriteLine($"File found: ${file}");
}
}
}
}
""";
VerifyCSharpDiagnostic(source,
new DiagnosticResult
{
Expand All @@ -114,52 +120,173 @@ static void Main(string[] args)
[TestMethod]
public void DeclarationOfOtherDirectoryGetDirectories_ProducesNothing()
{
string source = @"using System;
using System.Diagnostics;
using System.IO;
string source = """
using System;
using System.Diagnostics;
using System.IO;

namespace ConsoleApp5
{
public static class Directory {
public static string[] GetDirectories(string path) => Array.Empty<string>();
}
namespace ConsoleApp5
{
public static class Directory {
public static string[] GetDirectories(string path) => Array.Empty<string>();
}


class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetDirectories(AppDomain.CurrentDomain.BaseDirectory);
class Program
{
static void Main(string[] args)
{
string[] files = Directory.GetDirectories(AppDomain.CurrentDomain.BaseDirectory);

}
}
}";
}
}
}
""";
VerifyCSharpDiagnostic(source);
}

[TestMethod]
[Description("Issue 53")]
public void Diagnostic_HandlesMemberAccess()
{
string source = @"
using System;
string source = """

namespace Namespace
{
class Program
{
static void Main(string[] args)
using System;

namespace Namespace
{
class Program
{
static void Main(string[] args)
{
int selection;
if (!int.TryParse(Console.ReadLine(), out selection))
{
selection = 0;
}
}
}
}
""";
VerifyCSharpDiagnostic(source);
}

[TestMethod]
[Description("Cast<IdentifierNameSyntax>() throws InvalidCastException on generic method calls")]
public void GenericMethodCallOnDirectory_DoesNotThrow()
{
int selection;
if (!int.TryParse(Console.ReadLine(), out selection))
{
selection = 0;
}
// memberAccess.ChildNodes().Cast<IdentifierNameSyntax>() will throw
// if any child node is not IdentifierNameSyntax (e.g. GenericNameSyntax).
// This test uses a generic method call on a class named Directory.
string source = """

using System;
using System.Collections.Generic;

namespace ConsoleApp
{
public static class Directory
{
public static List<T> GetItems<T>() => new List<T>();
}

class Program
{
static void Main(string[] args)
{
var items = Directory.GetItems<string>();
}
}
}
""";
VerifyCSharpDiagnostic(source);
}
}
}
";

[TestMethod]
[Description("Analyzer should not report when symbol is unresolved (compile error)")]
public void UnresolvableDirectoryType_NoDiagnostic()
{
// When symbol.Symbol is null it means the code has a compile error,
// not that it's System.IO.Directory. Should not produce a false positive.
string source = """

namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var files = Directory.GetFiles(".");
}
}
}
""";
// No 'using System.IO' so Directory is unresolvable — should NOT produce diagnostic
VerifyCSharpDiagnostic(source);
}

[TestMethod]
[Description("Detect fully-qualified System.IO.Directory.GetFiles()")]
public void FullyQualifiedDirectoryGetFiles_ProducesInfoMessage()
{
string source = """

using System;

namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
string[] files = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory);
}
}
}
""";
VerifyCSharpDiagnostic(source,
new DiagnosticResult
{
Id = "INTL0301",
Severity = DiagnosticSeverity.Info,
Message = "Favor using the method `EnumerateFiles` over the `GetFiles` method",
Locations =
[
new DiagnosticResultLocation("Test0.cs", 10, 30)
]
});
}

[TestMethod]
[Description("Detect fully-qualified System.IO.Directory.GetDirectories()")]
public void FullyQualifiedDirectoryGetDirectories_ProducesInfoMessage()
{
string source = """

using System;

namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
string[] dirs = System.IO.Directory.GetDirectories(AppDomain.CurrentDomain.BaseDirectory);
}
}
}
""";
VerifyCSharpDiagnostic(source,
new DiagnosticResult
{
Id = "INTL0302",
Severity = DiagnosticSeverity.Info,
Message = "Favor using the method `EnumerateDirectories` over the `GetDirectories` method",
Locations =
[
new DiagnosticResultLocation("Test0.cs", 10, 29)
]
});
}
}
}
Loading
Loading