From 00287ad50e3f7ce1e32893e668969584821b0bf7 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 30 Oct 2020 16:41:30 -0700 Subject: [PATCH 01/41] think i have it blocking winmds --- Authoring/AuthoringSample/Program.cs | 26 +++++++++ Authoring/WinRT.SourceGenerator/Generator.cs | 57 ++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/Authoring/AuthoringSample/Program.cs b/Authoring/AuthoringSample/Program.cs index de46e0aac..40677d1b0 100644 --- a/Authoring/AuthoringSample/Program.cs +++ b/Authoring/AuthoringSample/Program.cs @@ -6,6 +6,32 @@ namespace AuthoringSample { + public sealed class ErroneousClass : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } + public enum BasicEnum { First = -1, diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index 0b43d751c..a43db9fc0 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -1,12 +1,16 @@ using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System; using System.Diagnostics; using System.IO; +using System.Linq; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; using System.Text; +using System.Xml; namespace Generator { @@ -133,6 +137,45 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } + private static DiagnosticDescriptor AsyncRule = new DiagnosticDescriptor("WinRTDiagnostic", + "WinRT doesn't support implementing Async interfaces", + "Runtime components can't implement Async interfaces, use AsyncInfo class methods instead (see: WME Error 1084)", + "Usage", + DiagnosticSeverity.Error, + true, + "Longer description about not implementing async interfaces."); + + private void CatchWinRTDiagnostics(GeneratorExecutionContext context) + { + INamedTypeSymbol asyncInterfaceType = context.Compilation.GetTypeByMetadataName("Windows.Foundation.IAsyncAction"); + + foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) + { + var model = context.Compilation.GetSemanticModel(tree); + var classes = tree.GetRoot().DescendantNodes().OfType(); + foreach (var cl in classes) + { + var classSymbol = model.GetDeclaredSymbol(cl); + if (classSymbol.AllInterfaces.Contains(asyncInterfaceType)) + { + context.ReportDiagnostic(Diagnostic.Create(AsyncRule, cl.GetLocation())); + } + } + } + } + + /* Checks the compilation's diagnostics, logging all that are seen. Return false iff there are no diagnostics */ + private bool LookForDiagnostics(GeneratorExecutionContext context) + { + var diagnostics = context.Compilation.GetDiagnostics(); + if (diagnostics.Any()) + { + foreach (Diagnostic d in diagnostics) { Logger.Log("!!! Oops! Found diagnostic: " + d + " !!!"); } + return true; + } + return false; + } + public void Execute(GeneratorExecutionContext context) { if (!IsCsWinRTComponent(context)) @@ -142,6 +185,17 @@ public void Execute(GeneratorExecutionContext context) Logger.Initialize(context); + CatchWinRTDiagnostics(context); + var diagnostics = context.Compilation.GetDiagnostics(); + + Logger.Log("hello Joshua"); + + if (diagnostics.Any()) + { + foreach (Diagnostic d in diagnostics) { Logger.Log("!!! Oops! Found diagnostic: " + d + " !!!"); } + return; + } + try { string assembly = GetAssemblyName(context); @@ -152,11 +206,14 @@ public void Execute(GeneratorExecutionContext context) assembly, version, metadataBuilder); + foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { + Logger.Log("!!!! shouldnt get here !!!!"); writer.Model = context.Compilation.GetSemanticModel(tree); writer.Visit(tree.GetRoot()); } + Logger.Log("!!!! Definitely shouldn't get here !!!!"); writer.FinalizeGeneration(); string winmdFile = GetWinmdOutputFile(context); From 6f2bfbf62919fb1e2210bb423d6fd021ae3a44ec Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 2 Nov 2020 12:04:48 -0800 Subject: [PATCH 02/41] working diagnostic test app, blocking winmd generator via return as getdiagnostics dont show mine --- Authoring/AuthoringSample/Program.cs | 25 ---------- .../TestDiagnostics/Directory.Build.props | 9 ++++ .../TestDiagnostics/Directory.Build.targets | 9 ++++ Authoring/TestDiagnostics/Scenarios.cs | 31 ++++++++++++ .../TestDiagnostics/TestDiagnostics.csproj | 28 +++++++++++ Authoring/WinRT.SourceGenerator/Generator.cs | 49 ++++++++++--------- cswinrt.sln | 22 +++++++++ 7 files changed, 124 insertions(+), 49 deletions(-) create mode 100644 Authoring/TestDiagnostics/Directory.Build.props create mode 100644 Authoring/TestDiagnostics/Directory.Build.targets create mode 100644 Authoring/TestDiagnostics/Scenarios.cs create mode 100644 Authoring/TestDiagnostics/TestDiagnostics.csproj diff --git a/Authoring/AuthoringSample/Program.cs b/Authoring/AuthoringSample/Program.cs index 40677d1b0..aaa5af755 100644 --- a/Authoring/AuthoringSample/Program.cs +++ b/Authoring/AuthoringSample/Program.cs @@ -6,31 +6,6 @@ namespace AuthoringSample { - public sealed class ErroneousClass : IAsyncAction - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - } public enum BasicEnum { diff --git a/Authoring/TestDiagnostics/Directory.Build.props b/Authoring/TestDiagnostics/Directory.Build.props new file mode 100644 index 000000000..4cf186e3d --- /dev/null +++ b/Authoring/TestDiagnostics/Directory.Build.props @@ -0,0 +1,9 @@ + + + + true + + + + + diff --git a/Authoring/TestDiagnostics/Directory.Build.targets b/Authoring/TestDiagnostics/Directory.Build.targets new file mode 100644 index 000000000..53a2d80be --- /dev/null +++ b/Authoring/TestDiagnostics/Directory.Build.targets @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs new file mode 100644 index 000000000..85b3075c3 --- /dev/null +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -0,0 +1,31 @@ +using System; +using Windows.Foundation; + +namespace TestDiagnostics +{ + public class Scenarios : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +} diff --git a/Authoring/TestDiagnostics/TestDiagnostics.csproj b/Authoring/TestDiagnostics/TestDiagnostics.csproj new file mode 100644 index 000000000..14a7b7e8f --- /dev/null +++ b/Authoring/TestDiagnostics/TestDiagnostics.csproj @@ -0,0 +1,28 @@ + + + + net5.0 + x64;x86 + preview + 1.0.0.0 + true + true + true + $([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)', '$(IntermediateOutputPath)', 'Generated Files')) + + + + + + + + + + + + + + + + + diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index a43db9fc0..57ed9d376 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System; +using System.ComponentModel.Design; using System.Diagnostics; using System.IO; using System.Linq; @@ -137,7 +138,7 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } - private static DiagnosticDescriptor AsyncRule = new DiagnosticDescriptor("WinRTDiagnostic", + private static DiagnosticDescriptor AsyncRule = new DiagnosticDescriptor("WME1084", "WinRT doesn't support implementing Async interfaces", "Runtime components can't implement Async interfaces, use AsyncInfo class methods instead (see: WME Error 1084)", "Usage", @@ -145,8 +146,9 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) true, "Longer description about not implementing async interfaces."); - private void CatchWinRTDiagnostics(GeneratorExecutionContext context) - { + private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) + { + bool found = false; INamedTypeSymbol asyncInterfaceType = context.Compilation.GetTypeByMetadataName("Windows.Foundation.IAsyncAction"); foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) @@ -159,21 +161,12 @@ private void CatchWinRTDiagnostics(GeneratorExecutionContext context) if (classSymbol.AllInterfaces.Contains(asyncInterfaceType)) { context.ReportDiagnostic(Diagnostic.Create(AsyncRule, cl.GetLocation())); + found = true; } } } - } - /* Checks the compilation's diagnostics, logging all that are seen. Return false iff there are no diagnostics */ - private bool LookForDiagnostics(GeneratorExecutionContext context) - { - var diagnostics = context.Compilation.GetDiagnostics(); - if (diagnostics.Any()) - { - foreach (Diagnostic d in diagnostics) { Logger.Log("!!! Oops! Found diagnostic: " + d + " !!!"); } - return true; - } - return false; + return found; } public void Execute(GeneratorExecutionContext context) @@ -185,17 +178,20 @@ public void Execute(GeneratorExecutionContext context) Logger.Initialize(context); - CatchWinRTDiagnostics(context); - var diagnostics = context.Compilation.GetDiagnostics(); - - Logger.Log("hello Joshua"); - - if (diagnostics.Any()) + if (CatchWinRTDiagnostics(context)) { - foreach (Diagnostic d in diagnostics) { Logger.Log("!!! Oops! Found diagnostic: " + d + " !!!"); } + Logger.Log("Exiting early runtime component errors found"); + Logger.Close(); return; } + /* + foreach (Diagnostic d in context.Compilation.GetMethodBodyDiagnostics()) { Logger.Log("MethodBody diagnostic: " + d.ToString()); } + foreach (Diagnostic d in context.Compilation.GetParseDiagnostics()) { Logger.Log("Parse diagnostic: " + d.ToString()); } + foreach (Diagnostic d in context.Compilation.GetDiagnostics()) { Logger.Log("Plain ol diagnostic: " + d.ToString()); } + foreach (Diagnostic d in context.Compilation.GetDeclarationDiagnostics()) { Logger.Log("Declaration diagnostic: " + d.ToString()); } + */ + try { string assembly = GetAssemblyName(context); @@ -209,11 +205,16 @@ public void Execute(GeneratorExecutionContext context) foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { - Logger.Log("!!!! shouldnt get here !!!!"); - writer.Model = context.Compilation.GetSemanticModel(tree); + var model = context.Compilation.GetSemanticModel(tree); + /* + foreach (Diagnostic d in model.GetSyntaxDiagnostics()) { Logger.Log("[later] MethodBody diagnostic: " + d.ToString()); } + foreach (Diagnostic d in model.GetMethodBodyDiagnostics()) { Logger.Log("[later] MethodBody diagnostic: " + d.ToString()); } + foreach (Diagnostic d in model.GetDiagnostics()) { Logger.Log("[later] Plain ol diagnostic: " + d.ToString()); } + foreach (Diagnostic d in model.GetDeclarationDiagnostics()) { Logger.Log("[later] Declaration diagnostic: " + d.ToString()); } + */ + writer.Model = model; writer.Visit(tree.GetRoot()); } - Logger.Log("!!!! Definitely shouldn't get here !!!!"); writer.FinalizeGeneration(); string winmdFile = GetWinmdOutputFile(context); diff --git a/cswinrt.sln b/cswinrt.sln index 8ab9b72f6..03b7a2cbe 100644 --- a/cswinrt.sln +++ b/cswinrt.sln @@ -80,6 +80,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AuthoringSample", "Authorin EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringConsumptionTest", "Authoring\AuthoringConsumptionTest\AuthoringConsumptionTest.vcxproj", "{0212A7C5-8D3F-443C-9EBC-1F28091FDF88}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestDiagnostics", "Authoring\TestDiagnostics\TestDiagnostics.csproj", "{9D94052B-137A-40EE-957C-8B9E355FA15C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -390,6 +392,26 @@ Global {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x64.Build.0 = Release|x64 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x86.ActiveCfg = Release|Win32 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x86.Build.0 = Release|Win32 + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|ARM.ActiveCfg = Debug|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|ARM.Build.0 = Debug|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|ARM64.Build.0 = Debug|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|x64.ActiveCfg = Debug|x64 + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|x64.Build.0 = Debug|x64 + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|x86.ActiveCfg = Debug|x86 + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|x86.Build.0 = Debug|x86 + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|Any CPU.Build.0 = Release|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|ARM.ActiveCfg = Release|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|ARM.Build.0 = Release|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|ARM64.ActiveCfg = Release|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|ARM64.Build.0 = Release|Any CPU + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|x64.ActiveCfg = Release|x64 + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|x64.Build.0 = Release|x64 + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|x86.ActiveCfg = Release|x86 + {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 0e6538e10b5572bd67931eace6f74473dfaf7b78 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 2 Nov 2020 19:49:08 -0800 Subject: [PATCH 03/41] trying the generic interfacen ow --- Authoring/TestDiagnostics/Scenarios.cs | 63 ++++++++++---------- Authoring/WinRT.SourceGenerator/Generator.cs | 27 +++++++-- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 85b3075c3..40377dc6f 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -1,31 +1,32 @@ -using System; -using Windows.Foundation; - -namespace TestDiagnostics -{ - public class Scenarios : IAsyncAction - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - } -} +using System; +using Windows.Foundation; + +namespace TestDiagnostics +{ + public class Scenario : IAsyncActionWithProgress + { + public AsyncActionProgressHandler Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public AsyncActionWithProgressCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +} diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index 57ed9d376..12e5b907e 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -148,20 +148,35 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) { + Logger.Log("Joshua Joshua Joshua"); bool found = false; INamedTypeSymbol asyncInterfaceType = context.Compilation.GetTypeByMetadataName("Windows.Foundation.IAsyncAction"); + string[] DontImplementTheseInterfaces = { "Windows.Foundation.IAsyncAction", + "Windows.Foundation.IAsyncActionWithProgress", + "Windows.Foundation.IAsyncOperation", + "Windows.Foundation.IAsyncOperationWithProgress" }; foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { var model = context.Compilation.GetSemanticModel(tree); var classes = tree.GetRoot().DescendantNodes().OfType(); - foreach (var cl in classes) + foreach (ClassDeclarationSyntax classDeclaration in classes) { - var classSymbol = model.GetDeclaredSymbol(cl); - if (classSymbol.AllInterfaces.Contains(asyncInterfaceType)) - { - context.ReportDiagnostic(Diagnostic.Create(AsyncRule, cl.GetLocation())); - found = true; + var classSymbol = model.GetDeclaredSymbol(classDeclaration); + foreach (string interfaceName in DontImplementTheseInterfaces) + { + INamedTypeSymbol interfaceTypeSymbol = context.Compilation.GetTypeByMetadataName(interfaceName); + Logger.Log("interfacename: " + interfaceTypeSymbol.ToString()); + foreach (var thing in classSymbol.AllInterfaces) + { + Logger.Log("!!! thing is" + thing.ToString()); + } + Logger.Log("did we see it?"); + if (classSymbol.AllInterfaces.Contains(interfaceTypeSymbol)) + { + context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation())); + found |= true; + } } } } From b95eb82bc6a5b0ce10badf01bf633ae409cc2592 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 3 Nov 2020 17:14:50 -0800 Subject: [PATCH 04/41] updating starter log message --- Authoring/WinRT.SourceGenerator/Generator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index 12e5b907e..e7f2f771f 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -148,7 +148,7 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) { - Logger.Log("Joshua Joshua Joshua"); + Logger.Log("Starting CatchWinRTDiagnostics"); bool found = false; INamedTypeSymbol asyncInterfaceType = context.Compilation.GetTypeByMetadataName("Windows.Foundation.IAsyncAction"); string[] DontImplementTheseInterfaces = { "Windows.Foundation.IAsyncAction", From e09ba9d1ba2bbb2eece19a5a2af348578ab60bc4 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Wed, 4 Nov 2020 15:12:28 -0800 Subject: [PATCH 05/41] raising diagnostics for all async interfaces --- Authoring/TestDiagnostics/Scenarios.cs | 111 ++++++++++++++++++- Authoring/WinRT.SourceGenerator/Generator.cs | 90 ++++++++------- 2 files changed, 157 insertions(+), 44 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 40377dc6f..06ea31680 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -1,12 +1,13 @@ using System; using Windows.Foundation; +using Windows.Web.Syndication; namespace TestDiagnostics { - public class Scenario : IAsyncActionWithProgress + + public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress { - public AsyncActionProgressHandler Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public AsyncActionWithProgressCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public Exception ErrorCode => throw new NotImplementedException(); @@ -14,6 +15,15 @@ public class Scenario : IAsyncActionWithProgress public AsyncStatus Status => throw new NotImplementedException(); + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + public void Cancel() { throw new NotImplementedException(); @@ -28,5 +38,100 @@ public void GetResults() { throw new NotImplementedException(); } + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } + + public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } } + + public sealed class OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperationWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } + + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } } diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index e7f2f771f..b2aeac96d 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -138,49 +138,71 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } + /* TODO: update the message to know which interface was implemented. + * update format string and passing arguments when raising this rule */ private static DiagnosticDescriptor AsyncRule = new DiagnosticDescriptor("WME1084", "WinRT doesn't support implementing Async interfaces", "Runtime components can't implement Async interfaces, use AsyncInfo class methods instead (see: WME Error 1084)", "Usage", - DiagnosticSeverity.Error, + /* Warnings dont fail command line build; winmd generation is prevented regardless of severity. + Make this error when making final touches on this deliverable. */ + DiagnosticSeverity.Warning, true, "Longer description about not implementing async interfaces."); + static private string[] ProhibitedAsyncInterfaces = { + "Windows.Foundation.IAsyncAction", + "Windows.Foundation.IAsyncActionWithProgress`1", + "Windows.Foundation.IAsyncOperation`1", + "Windows.Foundation.IAsyncOperationWithProgress`2" + }; + + /* SameAsyncInterface uses the proper ISymbol equality check on the OriginalDefinition of the given symbols */ + private bool SameAsyncInterface(INamedTypeSymbol interfaceA, INamedTypeSymbol interfaceB) + { + /* Using OriginalDefinition b/c the generic field of the metadata type has the template name, e.g. `TProgress` + * and the actual interface will have a concrete type, e.g. `int` */ + return SymbolEqualityComparer.Default.Equals(interfaceA.OriginalDefinition, interfaceB.OriginalDefinition); + } + + /* ClassImplementsAsyncInterface returns true if the class represented by the symbol + implements any of the interfaces defined in ProhibitedAsyncInterfaces */ + private bool ClassImplementsAsyncInterface(GeneratorExecutionContext context, INamedTypeSymbol classSymbol, ClassDeclarationSyntax classDeclaration) + { + foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) + { + INamedTypeSymbol asyncInterface = context.Compilation.GetTypeByMetadataName(prohibitedInterface); + foreach (var interfaceImplemented in classSymbol.AllInterfaces) + { + if (SameAsyncInterface(interfaceImplemented, asyncInterface)) + { + context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation())); + return true; + /* by exiting early, we only report diagnostic for first prohibited interface we see. + If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. + could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported + */ + } + } + } + return false; + } + private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) { - Logger.Log("Starting CatchWinRTDiagnostics"); - bool found = false; - INamedTypeSymbol asyncInterfaceType = context.Compilation.GetTypeByMetadataName("Windows.Foundation.IAsyncAction"); - string[] DontImplementTheseInterfaces = { "Windows.Foundation.IAsyncAction", - "Windows.Foundation.IAsyncActionWithProgress", - "Windows.Foundation.IAsyncOperation", - "Windows.Foundation.IAsyncOperationWithProgress" }; - + bool found = false; // used by caller to exit early, i.e. don't generate a .winmd + foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { var model = context.Compilation.GetSemanticModel(tree); var classes = tree.GetRoot().DescendantNodes().OfType(); + foreach (ClassDeclarationSyntax classDeclaration in classes) { var classSymbol = model.GetDeclaredSymbol(classDeclaration); - foreach (string interfaceName in DontImplementTheseInterfaces) - { - INamedTypeSymbol interfaceTypeSymbol = context.Compilation.GetTypeByMetadataName(interfaceName); - Logger.Log("interfacename: " + interfaceTypeSymbol.ToString()); - foreach (var thing in classSymbol.AllInterfaces) - { - Logger.Log("!!! thing is" + thing.ToString()); - } - Logger.Log("did we see it?"); - if (classSymbol.AllInterfaces.Contains(interfaceTypeSymbol)) - { - context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation())); - found |= true; - } - } + found |= ClassImplementsAsyncInterface(context, classSymbol, classDeclaration); } } - return found; } @@ -195,18 +217,11 @@ public void Execute(GeneratorExecutionContext context) if (CatchWinRTDiagnostics(context)) { - Logger.Log("Exiting early runtime component errors found"); + Logger.Log("Exiting early -- errors in authored runtime component found."); Logger.Close(); return; } - /* - foreach (Diagnostic d in context.Compilation.GetMethodBodyDiagnostics()) { Logger.Log("MethodBody diagnostic: " + d.ToString()); } - foreach (Diagnostic d in context.Compilation.GetParseDiagnostics()) { Logger.Log("Parse diagnostic: " + d.ToString()); } - foreach (Diagnostic d in context.Compilation.GetDiagnostics()) { Logger.Log("Plain ol diagnostic: " + d.ToString()); } - foreach (Diagnostic d in context.Compilation.GetDeclarationDiagnostics()) { Logger.Log("Declaration diagnostic: " + d.ToString()); } - */ - try { string assembly = GetAssemblyName(context); @@ -220,14 +235,7 @@ public void Execute(GeneratorExecutionContext context) foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { - var model = context.Compilation.GetSemanticModel(tree); - /* - foreach (Diagnostic d in model.GetSyntaxDiagnostics()) { Logger.Log("[later] MethodBody diagnostic: " + d.ToString()); } - foreach (Diagnostic d in model.GetMethodBodyDiagnostics()) { Logger.Log("[later] MethodBody diagnostic: " + d.ToString()); } - foreach (Diagnostic d in model.GetDiagnostics()) { Logger.Log("[later] Plain ol diagnostic: " + d.ToString()); } - foreach (Diagnostic d in model.GetDeclarationDiagnostics()) { Logger.Log("[later] Declaration diagnostic: " + d.ToString()); } - */ - writer.Model = model; + writer.Model = context.Compilation.GetSemanticModel(tree); writer.Visit(tree.GetRoot()); } writer.FinalizeGeneration(); From 52d66bdfee06ff3a49b3850194d29b372c7e255f Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Wed, 4 Nov 2020 16:36:59 -0800 Subject: [PATCH 06/41] add diagnostic for multiple constructors of same arity --- Authoring/TestDiagnostics/Scenarios.cs | 22 ++++++++ Authoring/WinRT.SourceGenerator/Generator.cs | 53 +++++++++++++++++--- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 06ea31680..0feadb1f6 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -4,7 +4,28 @@ namespace TestDiagnostics { + public sealed class SameArityConstructors + { + private int num; + private string word; + + public SameArityConstructors(int i) + { + num = i; + word = "dog"; + } + + public SameArityConstructors(string s) + { + num = 38; + word = s; + } + + // Can test that multiple constructors are allowed (has been verified already, too) + // as long as they have different arities by making one take none or 2 arguments + } + /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress { public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -134,4 +155,5 @@ int IAsyncOperation.GetResults() throw new NotImplementedException(); } } + */ } diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index b2aeac96d..8fc5e7b1e 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -3,7 +3,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System; -using System.ComponentModel.Design; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -11,7 +11,6 @@ using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; using System.Text; -using System.Xml; namespace Generator { @@ -150,6 +149,15 @@ Make this error when making final touches on this deliverable. */ true, "Longer description about not implementing async interfaces."); + /* TODO, similar to above */ + private static DiagnosticDescriptor ClassConstructorRule = new DiagnosticDescriptor("WME1099", + "WinRT doesn't support a class having multiple constructors with the same arity", + "WinRT doesn't support a class having multiple constructors with the same arity", + "Usage", + DiagnosticSeverity.Warning, + true, + "longer description..."); + static private string[] ProhibitedAsyncInterfaces = { "Windows.Foundation.IAsyncAction", "Windows.Foundation.IAsyncActionWithProgress`1", @@ -172,25 +180,50 @@ private bool ClassImplementsAsyncInterface(GeneratorExecutionContext context, IN foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) { INamedTypeSymbol asyncInterface = context.Compilation.GetTypeByMetadataName(prohibitedInterface); - foreach (var interfaceImplemented in classSymbol.AllInterfaces) + foreach (INamedTypeSymbol interfaceImplemented in classSymbol.AllInterfaces) { if (SameAsyncInterface(interfaceImplemented, asyncInterface)) { context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation())); return true; /* by exiting early, we only report diagnostic for first prohibited interface we see. - If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. - could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported - */ + If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. + could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported */ } } } return false; } + /* HasMultipleConstructorsOfSameArity keeps track of the arity of all constructors seen, + * and reports the diagnostic (and exits) as soon as a duplicate is seen. */ + private bool HasMultipleConstructorsOfSameArity(GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + IEnumerable constructors = classDeclaration.ChildNodes().OfType(); + + /* more performant data structure? or use a Set, in order to not have to call Contains()? */ + IList aritiesSeenSoFar = new List(); + + foreach (ConstructorDeclarationSyntax constructor in constructors) + { + int arity = constructor.ParameterList.Parameters.Count; + + if (aritiesSeenSoFar.Contains(arity)) + { + context.ReportDiagnostic(Diagnostic.Create(ClassConstructorRule, constructor.GetLocation())); + return true; + } + else + { + aritiesSeenSoFar.Add(arity); + } + } + return false; + } + private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) { - bool found = false; // used by caller to exit early, i.e. don't generate a .winmd + bool found = false; foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { @@ -199,6 +232,10 @@ private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) foreach (ClassDeclarationSyntax classDeclaration in classes) { + /* look for multiple constructors of the same arity */ + found |= HasMultipleConstructorsOfSameArity(context, classDeclaration); + + /* look for async interfaces */ var classSymbol = model.GetDeclaredSymbol(classDeclaration); found |= ClassImplementsAsyncInterface(context, classSymbol, classDeclaration); } @@ -217,7 +254,7 @@ public void Execute(GeneratorExecutionContext context) if (CatchWinRTDiagnostics(context)) { - Logger.Log("Exiting early -- errors in authored runtime component found."); + Logger.Log("Exiting early -- found errors in authored runtime component."); Logger.Close(); return; } From b71cb021b9eaa51cbc8dd85eef0dcfad0d568156 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Wed, 4 Nov 2020 16:56:58 -0800 Subject: [PATCH 07/41] refactor rules used when reporting diagnostics --- Authoring/WinRT.SourceGenerator/Generator.cs | 47 +++++++++++--------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index 8fc5e7b1e..f7bda1ca4 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -137,26 +137,33 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } - /* TODO: update the message to know which interface was implemented. - * update format string and passing arguments when raising this rule */ - private static DiagnosticDescriptor AsyncRule = new DiagnosticDescriptor("WME1084", - "WinRT doesn't support implementing Async interfaces", - "Runtime components can't implement Async interfaces, use AsyncInfo class methods instead (see: WME Error 1084)", - "Usage", + private static string diagnosticsLink = "https://docs.microsoft.com/en-us/previous-versions/hh977010(v=vs.110)"; + + /* TODO: update the format message to know which interface was implemented. + * should take in the interface name and the class name that is implementing the interface */ + private static DiagnosticDescriptor AsyncRule = MakeRule( + "WME1084", + "Async Interfaces Rule", + "Runtime component class {0} cannot implement async interface {1}; use AsyncInfo class methods instead of async interfaces"); + + private static DiagnosticDescriptor ClassConstructorRule = MakeRule( + "WME1099", + "Class Constructor Rule", + "Runtime component class {0} cannot have multiple constructors of the same arity {1}"); + + private static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) + { + return new DiagnosticDescriptor( + id: id, + title: title, + messageFormat: messageFormat, + category: "Usage", /* Warnings dont fail command line build; winmd generation is prevented regardless of severity. - Make this error when making final touches on this deliverable. */ - DiagnosticSeverity.Warning, - true, - "Longer description about not implementing async interfaces."); - - /* TODO, similar to above */ - private static DiagnosticDescriptor ClassConstructorRule = new DiagnosticDescriptor("WME1099", - "WinRT doesn't support a class having multiple constructors with the same arity", - "WinRT doesn't support a class having multiple constructors with the same arity", - "Usage", - DiagnosticSeverity.Warning, - true, - "longer description..."); + * Make this error when making final touches on this deliverable. */ + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: diagnosticsLink); + } static private string[] ProhibitedAsyncInterfaces = { "Windows.Foundation.IAsyncAction", @@ -184,7 +191,7 @@ private bool ClassImplementsAsyncInterface(GeneratorExecutionContext context, IN { if (SameAsyncInterface(interfaceImplemented, asyncInterface)) { - context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation())); + context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation())); // believe this is where the arguments to the Rule's format message get passed... return true; /* by exiting early, we only report diagnostic for first prohibited interface we see. If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. From 69995d1cf5ada266f85c20d29479f05f95d8d9ec Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Thu, 5 Nov 2020 07:33:27 -0800 Subject: [PATCH 08/41] printing details in diagnostic rule such as erroneous class name --- Authoring/TestDiagnostics/Scenarios.cs | 5 +++-- Authoring/WinRT.SourceGenerator/Generator.cs | 8 +++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 0feadb1f6..a8af1f1c2 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -25,7 +25,7 @@ public SameArityConstructors(string s) // as long as they have different arities by making one take none or 2 arguments } - /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? + /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? */ public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress { public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -75,7 +75,7 @@ void IAsyncActionWithProgress.GetResults() throw new NotImplementedException(); } } - + public class ActionWithProgress : IAsyncActionWithProgress { AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -103,6 +103,7 @@ void IAsyncActionWithProgress.GetResults() } } + /* public sealed class OpWithProgress : IAsyncOperationWithProgress { AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index f7bda1ca4..fd6f6b81c 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -139,8 +139,6 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) private static string diagnosticsLink = "https://docs.microsoft.com/en-us/previous-versions/hh977010(v=vs.110)"; - /* TODO: update the format message to know which interface was implemented. - * should take in the interface name and the class name that is implementing the interface */ private static DiagnosticDescriptor AsyncRule = MakeRule( "WME1084", "Async Interfaces Rule", @@ -191,9 +189,9 @@ private bool ClassImplementsAsyncInterface(GeneratorExecutionContext context, IN { if (SameAsyncInterface(interfaceImplemented, asyncInterface)) { - context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation())); // believe this is where the arguments to the Rule's format message get passed... + context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation(), classDeclaration.Identifier, interfaceImplemented)); return true; - /* by exiting early, we only report diagnostic for first prohibited interface we see. + /* By exiting early, we only report diagnostic for first prohibited interface we see. If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported */ } @@ -217,7 +215,7 @@ private bool HasMultipleConstructorsOfSameArity(GeneratorExecutionContext contex if (aritiesSeenSoFar.Contains(arity)) { - context.ReportDiagnostic(Diagnostic.Create(ClassConstructorRule, constructor.GetLocation())); + context.ReportDiagnostic(Diagnostic.Create(ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity)); return true; } else From e6d6a36ff6a910d58dc109a339fef5a3fa615e74 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Thu, 5 Nov 2020 10:26:43 -0800 Subject: [PATCH 09/41] diagnostic for method parameter literally named value --- Authoring/TestDiagnostics/Scenarios.cs | 37 ++++++++++++++++- Authoring/WinRT.SourceGenerator/Generator.cs | 42 +++++++++++++++++--- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index a8af1f1c2..53f2fd724 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -4,6 +4,39 @@ namespace TestDiagnostics { + + /* structures... + * can only contain fields + * all fields must be public + * fields cannot be used elsewhere + * valid fields are enumerations, structures, primitive types + * UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself + */ + + public struct UsefulName + { + const int ci = 5; + } + + /* need clarification on the `returnValue` name for property accessors */ + public sealed class ParameterNamedValue + { + public int Identity(int value) + { + return value; + } + + public int specialNumber + { + get + { + int returnValue = 38; + return returnValue; + } + } + } + + /* public sealed class SameArityConstructors { private int num; @@ -24,8 +57,9 @@ public SameArityConstructors(string s) // Can test that multiple constructors are allowed (has been verified already, too) // as long as they have different arities by making one take none or 2 arguments } + */ - /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? */ + /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress { public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -102,6 +136,7 @@ void IAsyncActionWithProgress.GetResults() throw new NotImplementedException(); } } + */ /* public sealed class OpWithProgress : IAsyncOperationWithProgress diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index fd6f6b81c..e5358de27 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -149,6 +149,13 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) "Class Constructor Rule", "Runtime component class {0} cannot have multiple constructors of the same arity {1}"); + private static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( + "WME1092", + "Parameter Named Value Rule", + ("The method {0} has a parameter named {1} which is the same as the default return value name. " + + "Consider using another name for the parameter or use the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute " + + "to explicitly specify the name of the return value.")); + private static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) { return new DiagnosticDescriptor( @@ -180,7 +187,7 @@ private bool SameAsyncInterface(INamedTypeSymbol interfaceA, INamedTypeSymbol in /* ClassImplementsAsyncInterface returns true if the class represented by the symbol implements any of the interfaces defined in ProhibitedAsyncInterfaces */ - private bool ClassImplementsAsyncInterface(GeneratorExecutionContext context, INamedTypeSymbol classSymbol, ClassDeclarationSyntax classDeclaration) + private bool ImplementsAsyncInterface(GeneratorExecutionContext context, INamedTypeSymbol classSymbol, ClassDeclarationSyntax classDeclaration) { foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) { @@ -226,6 +233,25 @@ private bool HasMultipleConstructorsOfSameArity(GeneratorExecutionContext contex return false; } + /* HasParameterNamedValue */ + private bool HasParameterNamedValue(GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + IEnumerable methods = classDeclaration.ChildNodes().OfType(); + + foreach (MethodDeclarationSyntax method in methods) + { + foreach (ParameterSyntax parameter in method.ParameterList.Parameters) + { + if (parameter.Identifier.Value.Equals("value")) + { + context.ReportDiagnostic(Diagnostic.Create(ParameterNamedValueRule, parameter.GetLocation(), method.Identifier, parameter.Identifier)); + return true; + } + } + } + return false; + } + private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) { bool found = false; @@ -235,14 +261,20 @@ private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) var model = context.Compilation.GetSemanticModel(tree); var classes = tree.GetRoot().DescendantNodes().OfType(); + /* look for... */ foreach (ClassDeclarationSyntax classDeclaration in classes) - { - /* look for multiple constructors of the same arity */ + { + /* parameters named value*/ + /* TODO: make sure property accessors do not have a parameter named returnValue*/ + found |= HasParameterNamedValue(context, classDeclaration); + + + /* multiple constructors of the same arity */ found |= HasMultipleConstructorsOfSameArity(context, classDeclaration); - /* look for async interfaces */ + /* implementing async interfaces */ var classSymbol = model.GetDeclaredSymbol(classDeclaration); - found |= ClassImplementsAsyncInterface(context, classSymbol, classDeclaration); + found |= ImplementsAsyncInterface(context, classSymbol, classDeclaration); } } return found; From 0d0f1c3a63ad400842ac461b7235b4ef8cc4ebfb Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Thu, 12 Nov 2020 07:41:12 -0800 Subject: [PATCH 10/41] fix return value name --- Authoring/TestDiagnostics/Scenarios.cs | 24 +++++++++++--------- Authoring/WinRT.SourceGenerator/Generator.cs | 8 +++---- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 53f2fd724..1fcfdfcfd 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -13,28 +13,30 @@ namespace TestDiagnostics * UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself */ - public struct UsefulName + public struct ExampleStruct { const int ci = 5; + int x; } - /* need clarification on the `returnValue` name for property accessors */ - public sealed class ParameterNamedValue + public struct StructInAStruct { - public int Identity(int value) + ExampleStruct strct; + public int phi { - return value; + get { return 5; } } + } - public int specialNumber + /* + public sealed class ParameterNamedDunderRetVal + { + public int Identity(int __retval) { - get - { - int returnValue = 38; - return returnValue; - } + return __retval; } } + */ /* public sealed class SameArityConstructors diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index e5358de27..b51a47e9e 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -111,7 +111,7 @@ private void GenerateSources(GeneratorExecutionContext context) context.AddSource(Path.GetFileNameWithoutExtension(file), SourceText.From(File.ReadAllText(file), Encoding.UTF8)); } - Directory.Delete(outputDir, true); + // Directory.Delete(outputDir, true); } private string GetWinmdOutputFile(GeneratorExecutionContext context) @@ -234,7 +234,7 @@ private bool HasMultipleConstructorsOfSameArity(GeneratorExecutionContext contex } /* HasParameterNamedValue */ - private bool HasParameterNamedValue(GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + private bool HasReturnValueNameConflict(GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { IEnumerable methods = classDeclaration.ChildNodes().OfType(); @@ -242,7 +242,7 @@ private bool HasParameterNamedValue(GeneratorExecutionContext context, ClassDecl { foreach (ParameterSyntax parameter in method.ParameterList.Parameters) { - if (parameter.Identifier.Value.Equals("value")) + if (parameter.Identifier.Value.Equals("__retval")) { context.ReportDiagnostic(Diagnostic.Create(ParameterNamedValueRule, parameter.GetLocation(), method.Identifier, parameter.Identifier)); return true; @@ -266,7 +266,7 @@ private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) { /* parameters named value*/ /* TODO: make sure property accessors do not have a parameter named returnValue*/ - found |= HasParameterNamedValue(context, classDeclaration); + found |= HasReturnValueNameConflict(context, classDeclaration); /* multiple constructors of the same arity */ From ff313a607b7161eb353dc3fb32508005dc7b8386 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 13 Nov 2020 12:04:14 -0800 Subject: [PATCH 11/41] starting struct scenario tests --- Authoring/TestDiagnostics/Scenarios.cs | 52 +++++++++++++++++++------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 1fcfdfcfd..758211ab4 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -1,33 +1,57 @@ -using System; +using ABI.System.Numerics; +using System; using Windows.Foundation; +using Windows.Foundation.Numerics; using Windows.Web.Syndication; namespace TestDiagnostics { - /* structures... - * can only contain fields - * all fields must be public - * fields cannot be used elsewhere - * valid fields are enumerations, structures, primitive types + /* "only structures can contain fields" what does this mean? + * ? we have samples of classes with fields that are fine... + * + * structures can only contain "valid" fields + * ! all fields must be public + * "valid" fields are enumerations, structures, primitive types * UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself */ - public struct ExampleStruct + public struct Posn /* Invalid? because property? */ + { + int z; + public int x { get; } + public int y { get; } + } + + /* + public struct StructWithPrivateField_Invalid { const int ci = 5; - int x; + private int x; } - public struct StructInAStruct + public struct StructWithAllValidFields { - ExampleStruct strct; - public int phi - { - get { return 5; } - } + bool b; + } + public struct StructWithObjectField_Invalid // is this really invalid? + { + + } + + public struct StructWithByteField_Invalid // is this really invalid? + { + + } + + public struct StructWithWinRTStructField + { + public Matrix3x2 matrix; + } + */ + /* public sealed class ParameterNamedDunderRetVal { From 61ca90a0899f74a398dd149f85cedaf771945ff7 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 16 Nov 2020 12:44:56 -0800 Subject: [PATCH 12/41] adding structure fields diagnostic - temp --- Authoring/TestDiagnostics/Scenarios.cs | 55 +++++- Authoring/WinRT.SourceGenerator/Generator.cs | 172 ++++++++++++++++++- 2 files changed, 213 insertions(+), 14 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 758211ab4..3f2f621cd 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -1,5 +1,6 @@ using ABI.System.Numerics; using System; +using System.Runtime.ExceptionServices; using Windows.Foundation; using Windows.Foundation.Numerics; using Windows.Web.Syndication; @@ -14,43 +15,79 @@ namespace TestDiagnostics * ! all fields must be public * "valid" fields are enumerations, structures, primitive types * UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself + * are bytes okay? */ + + public enum BasicEnum + { + First = 0, + Second = 1 + } + + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + } + + public struct StructWithClass_Invalid + { + public SillyClass classField; + } - public struct Posn /* Invalid? because property? */ + public struct Posn_Invalid { - int z; + BasicEnum enumField; + public int x { get; } public int y { get; } } - /* public struct StructWithPrivateField_Invalid { const int ci = 5; private int x; } + /* public struct StructWithAllValidFields { - bool b; - + bool boolean; + char character; + decimal dec; + double dbl; + float flt; + int i; + uint nat; + long lng; + ulong ulng; + short sh; + ushort us; + string str; } + */ public struct StructWithObjectField_Invalid // is this really invalid? - { + { + object obj; } + public struct StructWithDynamicField_Invalid // is this really invalid? + { + dynamic dyn; + } public struct StructWithByteField_Invalid // is this really invalid? - { - + { + byte b; } public struct StructWithWinRTStructField { public Matrix3x2 matrix; } - */ /* public sealed class ParameterNamedDunderRetVal diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index b51a47e9e..0ba4a0698 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -156,6 +156,23 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) + "Consider using another name for the parameter or use the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute " + "to explicitly specify the name of the return value.")); + private static DiagnosticDescriptor StructHasPropertyRule = MakeRule( + "WME1060(a)", + "Property in a Struct", + "The structure {0} has a property {1}. In Windows Runtime, structures can only contain public fields of basic types, enums and structures."); + + private static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( + "WME1060(b)", + "Private field in struct", + ("Structure {0} has private field. All fields must be public for Windows Runtime structures.")); + + private static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( + "WME1060", + "Invalid field in struct", + ("Structure {0} has field {1} of type {2}. {2} is not a valid Windows Runtime field type. Each field " + + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.") ); + + private static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) { return new DiagnosticDescriptor( @@ -252,6 +269,75 @@ private bool HasReturnValueNameConflict(GeneratorExecutionContext context, Class return false; } + private bool StructHasProperty(GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) + { + var propertyDeclarations = structDeclaration.DescendantNodes().OfType(); + if (propertyDeclarations.Any()) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasPropertyRule, structDeclaration.GetLocation(), structDeclaration.Identifier, propertyDeclarations.First().Identifier)); + return true; + } + return false; + } + + private bool StructHasInvalidFields(GeneratorExecutionContext context, FieldDeclarationSyntax field, StructDeclarationSyntax structDeclaration, List classNames) + { + bool found = false; + + if (field.GetFirstToken().ToString().Equals("private")) // hmm + { + context.ReportDiagnostic(Diagnostic.Create(StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); + found |= true; + } + foreach (var variable in field.DescendantNodes().OfType()) + { + var type = variable.Type; + var typeStr = type.ToString(); + + List invalidTypes = new List { "object", "byte", "dynamic" }; + invalidTypes.AddRange(classNames); + + /* + if (invalidTypes.Contains(typeStr)) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, + variable.GetLocation(), + structDeclaration.Identifier, + field.ToString(), + typeStr)); + } + */ + + if (type.IsKind(SyntaxKind.PredefinedType)) + { + if (typeStr.Equals("object") || typeStr.Equals("byte")) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, + variable.GetLocation(), + structDeclaration.Identifier, + field.ToString(), + typeStr)); + found |= true; + } + } + + if (type.IsKind(SyntaxKind.IdentifierName)) + { + // Assuming the only other IdentifierNames would be enums or structures ... + if (typeStr.Equals("dynamic") || classNames.Contains(type.GetFirstToken().ToString())) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, + variable.GetLocation(), + structDeclaration.Identifier, + field.ToString(), // would be better if it just had the field name + typeStr)); + found |= true; + } + } + } + return found; + } + private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) { bool found = false; @@ -259,15 +345,22 @@ private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { var model = context.Compilation.GetSemanticModel(tree); - var classes = tree.GetRoot().DescendantNodes().OfType(); + var nodes = tree.GetRoot().DescendantNodes(); + + var classes = nodes.OfType(); + var enums = nodes.OfType(); + var structs = nodes.OfType(); + + List classNames = new List(); + List enumNames = new List(); /* look for... */ foreach (ClassDeclarationSyntax classDeclaration in classes) - { - /* parameters named value*/ - /* TODO: make sure property accessors do not have a parameter named returnValue*/ - found |= HasReturnValueNameConflict(context, classDeclaration); + { + classNames.Add(classDeclaration.Identifier.ToString()); + /* parameters named __retval*/ + found |= HasReturnValueNameConflict(context, classDeclaration); /* multiple constructors of the same arity */ found |= HasMultipleConstructorsOfSameArity(context, classDeclaration); @@ -276,6 +369,75 @@ private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) var classSymbol = model.GetDeclaredSymbol(classDeclaration); found |= ImplementsAsyncInterface(context, classSymbol, classDeclaration); } + + // don't need this loop if the only other variable identifier possible is for a class or struct + foreach (EnumDeclarationSyntax enumDeclaration in enums) + { + enumNames.Add(enumDeclaration.Identifier); + } + + foreach (StructDeclarationSyntax structDeclaration in structs) + { + found |= StructHasProperty(context, structDeclaration); + /*var propertyDeclarations = structDeclaration.DescendantNodes().OfType(); + if (propertyDeclarations.Any()) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasPropertyRule, structDeclaration.GetLocation(), structDeclaration.Identifier, propertyDeclarations.First().Identifier)); + found |= true; + }*/ + + + + var fields = structDeclaration.DescendantNodes().OfType(); + foreach (var field in fields) + { + + found |= StructHasInvalidFields(context, field, structDeclaration, classNames); + + // check if field is private + /* + if (field.GetFirstToken().ToString().Equals("private")) // hmm + { + context.ReportDiagnostic(Diagnostic.Create(StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); + found |= true; + } + + foreach (var variable in field.DescendantNodes().OfType()) + { + var type = variable.Type; + var typeStr = type.ToString(); + + if (type.IsKind(SyntaxKind.PredefinedType)) + { + if (typeStr.Equals("object") || typeStr.Equals("byte")) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, + variable.GetLocation(), + structDeclaration.Identifier, + field.ToString(), + typeStr)); + found |= true; + } + } + + if (type.IsKind(SyntaxKind.IdentifierName)) + { + // Assuming the only other IdentifierNames would be enums or structures ... + if (classNames.Contains(type.GetFirstToken().ToString())) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, + variable.GetLocation(), + structDeclaration.Identifier, + field.ToString(), // would be better if it just had the field name + typeStr)); + found |= true; + } + } + } + */ + } + } + } return found; } From 9550bf2d805a922dbd5bd4c9de647fc104c6ed4e Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 16 Nov 2020 12:47:21 -0800 Subject: [PATCH 13/41] adding struct field diagnostic 90percent --- Authoring/WinRT.SourceGenerator/Generator.cs | 94 +------------------- 1 file changed, 3 insertions(+), 91 deletions(-) diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index 0ba4a0698..10912b982 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -269,7 +269,7 @@ private bool HasReturnValueNameConflict(GeneratorExecutionContext context, Class return false; } - private bool StructHasProperty(GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) + private bool StructHasPropertyField(GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) { var propertyDeclarations = structDeclaration.DescendantNodes().OfType(); if (propertyDeclarations.Any()) @@ -297,7 +297,6 @@ private bool StructHasInvalidFields(GeneratorExecutionContext context, FieldDecl List invalidTypes = new List { "object", "byte", "dynamic" }; invalidTypes.AddRange(classNames); - /* if (invalidTypes.Contains(typeStr)) { context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, @@ -306,34 +305,6 @@ private bool StructHasInvalidFields(GeneratorExecutionContext context, FieldDecl field.ToString(), typeStr)); } - */ - - if (type.IsKind(SyntaxKind.PredefinedType)) - { - if (typeStr.Equals("object") || typeStr.Equals("byte")) - { - context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, - variable.GetLocation(), - structDeclaration.Identifier, - field.ToString(), - typeStr)); - found |= true; - } - } - - if (type.IsKind(SyntaxKind.IdentifierName)) - { - // Assuming the only other IdentifierNames would be enums or structures ... - if (typeStr.Equals("dynamic") || classNames.Contains(type.GetFirstToken().ToString())) - { - context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, - variable.GetLocation(), - structDeclaration.Identifier, - field.ToString(), // would be better if it just had the field name - typeStr)); - found |= true; - } - } } return found; } @@ -348,11 +319,10 @@ private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) var nodes = tree.GetRoot().DescendantNodes(); var classes = nodes.OfType(); - var enums = nodes.OfType(); var structs = nodes.OfType(); + // Used in checking structure fields List classNames = new List(); - List enumNames = new List(); /* look for... */ foreach (ClassDeclarationSyntax classDeclaration in classes) @@ -370,74 +340,16 @@ private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) found |= ImplementsAsyncInterface(context, classSymbol, classDeclaration); } - // don't need this loop if the only other variable identifier possible is for a class or struct - foreach (EnumDeclarationSyntax enumDeclaration in enums) - { - enumNames.Add(enumDeclaration.Identifier); - } - foreach (StructDeclarationSyntax structDeclaration in structs) { - found |= StructHasProperty(context, structDeclaration); - /*var propertyDeclarations = structDeclaration.DescendantNodes().OfType(); - if (propertyDeclarations.Any()) - { - context.ReportDiagnostic(Diagnostic.Create(StructHasPropertyRule, structDeclaration.GetLocation(), structDeclaration.Identifier, propertyDeclarations.First().Identifier)); - found |= true; - }*/ - - + found |= StructHasPropertyField(context, structDeclaration); var fields = structDeclaration.DescendantNodes().OfType(); foreach (var field in fields) { - found |= StructHasInvalidFields(context, field, structDeclaration, classNames); - - // check if field is private - /* - if (field.GetFirstToken().ToString().Equals("private")) // hmm - { - context.ReportDiagnostic(Diagnostic.Create(StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); - found |= true; - } - - foreach (var variable in field.DescendantNodes().OfType()) - { - var type = variable.Type; - var typeStr = type.ToString(); - - if (type.IsKind(SyntaxKind.PredefinedType)) - { - if (typeStr.Equals("object") || typeStr.Equals("byte")) - { - context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, - variable.GetLocation(), - structDeclaration.Identifier, - field.ToString(), - typeStr)); - found |= true; - } - } - - if (type.IsKind(SyntaxKind.IdentifierName)) - { - // Assuming the only other IdentifierNames would be enums or structures ... - if (classNames.Contains(type.GetFirstToken().ToString())) - { - context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, - variable.GetLocation(), - structDeclaration.Identifier, - field.ToString(), // would be better if it just had the field name - typeStr)); - found |= true; - } - } - } - */ } } - } return found; } From 2e4f0c068ac111ff7ddd7daed3656e3fcb4c0edb Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 20 Nov 2020 10:24:06 -0800 Subject: [PATCH 14/41] restructure diagnostics into separate file, context passed by ref so reported diagnostics dont get forgotten --- Authoring/TestDiagnostics/Scenarios.cs | 46 ++-- .../WinRT.SourceGenerator/DiagnosticRules.cs | 192 ++++++++++++++++ Authoring/WinRT.SourceGenerator/Generator.cs | 205 ++---------------- 3 files changed, 230 insertions(+), 213 deletions(-) create mode 100644 Authoring/WinRT.SourceGenerator/DiagnosticRules.cs diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 3f2f621cd..de24fa2bf 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -7,22 +7,8 @@ namespace TestDiagnostics { - - /* "only structures can contain fields" what does this mean? - * ? we have samples of classes with fields that are fine... - * - * structures can only contain "valid" fields - * ! all fields must be public - * "valid" fields are enumerations, structures, primitive types - * UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself - * are bytes okay? - */ - public enum BasicEnum - { - First = 0, - Second = 1 - } + public sealed class SillyClass { @@ -32,11 +18,18 @@ public double Identity(double d) } } + /* */ public struct StructWithClass_Invalid { public SillyClass classField; } + public enum BasicEnum + { + First = 0, + Second = 1 + } + public struct Posn_Invalid { BasicEnum enumField; @@ -50,8 +43,9 @@ public struct StructWithPrivateField_Invalid const int ci = 5; private int x; } + /* */ - /* + /**/ public struct StructWithAllValidFields { bool boolean; @@ -67,8 +61,9 @@ public struct StructWithAllValidFields ushort us; string str; } - */ + /**/ + /**/ public struct StructWithObjectField_Invalid // is this really invalid? { object obj; @@ -88,8 +83,9 @@ public struct StructWithWinRTStructField { public Matrix3x2 matrix; } + /**/ - /* + /**/ public sealed class ParameterNamedDunderRetVal { public int Identity(int __retval) @@ -97,9 +93,9 @@ public int Identity(int __retval) return __retval; } } - */ + /**/ - /* + /**/ public sealed class SameArityConstructors { private int num; @@ -120,9 +116,9 @@ public SameArityConstructors(string s) // Can test that multiple constructors are allowed (has been verified already, too) // as long as they have different arities by making one take none or 2 arguments } - */ + /**/ - /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? + /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? */ public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress { public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -199,9 +195,9 @@ void IAsyncActionWithProgress.GetResults() throw new NotImplementedException(); } } - */ + /**/ - /* + /**/ public sealed class OpWithProgress : IAsyncOperationWithProgress { AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -254,5 +250,5 @@ int IAsyncOperation.GetResults() throw new NotImplementedException(); } } - */ + /**/ } diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs new file mode 100644 index 000000000..640403084 --- /dev/null +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -0,0 +1,192 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Collections.Generic; +using System.Linq; + +namespace Generator +{ + public class WinRTRules + { + /* MakeRule is a helper function that does most of the boilerplate information needed for Diagnostics + param id : string, a short identifier for the diagnostic + param title : string, a few words generally describing the diagnostic + param messageFormat : string, describes the diagnostic -- formatted with {0}, ... -- + such that data can be passed in for the code the diagnostic is reported for */ + static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) + { + return new DiagnosticDescriptor( + id: id, + title: title, + messageFormat: messageFormat, + category: "Usage", + /* Warnings dont fail command line build; winmd generation is prevented regardless of severity. + * Make this error when making final touches on this deliverable. */ + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: "https://docs.microsoft.com/en-us/previous-versions/hh977010(v=vs.110)"); + } + + static DiagnosticDescriptor AsyncRule = MakeRule( + "WME1084", + "Async Interfaces Rule", + "Runtime component class {0} cannot implement async interface {1}; use AsyncInfo class methods instead of async interfaces"); + + static DiagnosticDescriptor ClassConstructorRule = MakeRule( + "WME1099", + "Class Constructor Rule", + "Runtime component class {0} cannot have multiple constructors of the same arity {1}"); + + static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( + "WME1092", + "Parameter Named Value Rule", + ("The method {0} has a parameter named {1} which is the same as the default return value name. " + + "Consider using another name for the parameter or use the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute " + + "to explicitly specify the name of the return value.")); + + static DiagnosticDescriptor StructHasPropertyRule = MakeRule( + "WME1060(a)", + "Property in a Struct", + "The structure {0} has a property {1}. In Windows Runtime, structures can only contain public fields of basic types, enums and structures."); + + static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( + "WME1060(b)", + "Private field in struct", + "Structure {0} has private field. All fields must be public for Windows Runtime structures."); + + static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( + "WME1060", + "Invalid field in struct", + ("Structure {0} has field {1} of type {2}. {2} is not a valid Windows Runtime field type. Each field " + + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.")); + + + /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ + static string[] ProhibitedAsyncInterfaces = { + "Windows.Foundation.IAsyncAction", + "Windows.Foundation.IAsyncActionWithProgress`1", + "Windows.Foundation.IAsyncOperation`1", + "Windows.Foundation.IAsyncOperationWithProgress`2" + }; + + /* SameAsyncInterface uses the proper ISymbol equality check on the OriginalDefinition of the given symbols */ + private bool SameAsyncInterface(INamedTypeSymbol interfaceA, INamedTypeSymbol interfaceB) + { + /* Using OriginalDefinition b/c the generic field of the metadata type has the template name, e.g. `TProgress` + * and the actual interface will have a concrete type, e.g. `int` */ + return SymbolEqualityComparer.Default.Equals(interfaceA.OriginalDefinition, interfaceB.OriginalDefinition); + } + + /* ImplementsAsyncInterface + returns true if the class represented by the symbol implements any of the interfaces defined in ProhibitedAsyncInterfaces */ + public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INamedTypeSymbol classSymbol, ClassDeclarationSyntax classDeclaration) + { + foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) + { + INamedTypeSymbol asyncInterface = context.Compilation.GetTypeByMetadataName(prohibitedInterface); + foreach (INamedTypeSymbol interfaceImplemented in classSymbol.AllInterfaces) + { + if (SameAsyncInterface(interfaceImplemented, asyncInterface)) + { + context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation(), classDeclaration.Identifier, interfaceImplemented)); + return true; + /* By exiting early, we only report diagnostic for first prohibited interface we see. + If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. + could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported */ + } + } + } + return false; + } + + /* HasMultipleConstructorsOfSameArity + keeps track of the arity of all constructors, and reports the diagnostic (and exits) as soon as a two constructors of the same arity are seen. */ + public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + IEnumerable constructors = classDeclaration.ChildNodes().OfType(); + + /* more performant data structure? or use a Set, in order to not have to call Contains()? */ + IList aritiesSeenSoFar = new List(); + + foreach (ConstructorDeclarationSyntax constructor in constructors) + { + int arity = constructor.ParameterList.Parameters.Count; + + if (aritiesSeenSoFar.Contains(arity)) + { + context.ReportDiagnostic(Diagnostic.Create(ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity)); + return true; + } + else + { + aritiesSeenSoFar.Add(arity); + } + } + return false; + } + + /* HasParameterNamedValue + the generated code for components uses the name "__retval" for the output variable, + we report diagnostic if a user uses this same identifier as a parameter to a method */ + public bool HasReturnValueNameConflict(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + IEnumerable methods = classDeclaration.ChildNodes().OfType(); + + foreach (MethodDeclarationSyntax method in methods) + { + foreach (ParameterSyntax parameter in method.ParameterList.Parameters) + { + if (parameter.Identifier.Value.Equals("__retval")) + { + context.ReportDiagnostic(Diagnostic.Create(ParameterNamedValueRule, parameter.GetLocation(), method.Identifier, parameter.Identifier)); + return true; + } + } + } + return false; + } + + /* StructHasPropertyField + structs cannot have properties in the Windows Runtime */ + public bool StructHasPropertyField(ref GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) + { + var propertyDeclarations = structDeclaration.DescendantNodes().OfType(); + if (propertyDeclarations.Any()) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasPropertyRule, structDeclaration.GetLocation(), structDeclaration.Identifier, propertyDeclarations.First().Identifier)); + return true; + } + return false; + } + + /* StructHasInvalidFields + structs can only contain fields of primitive types, enums, and other structs */ + public bool StructHasInvalidFields(ref GeneratorExecutionContext context, FieldDeclarationSyntax field, StructDeclarationSyntax structDeclaration, List classNames) + { + bool found = false; + + if (field.GetFirstToken().ToString().Equals("private")) // hmm + { + context.ReportDiagnostic(Diagnostic.Create(StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); + found |= true; + } + foreach (var variable in field.DescendantNodes().OfType()) + { + var type = variable.Type; + var typeStr = type.ToString(); + + List invalidTypes = new List { "object", "byte", "dynamic" }; + invalidTypes.AddRange(classNames); + + if (invalidTypes.Contains(typeStr)) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, + variable.GetLocation(), + structDeclaration.Identifier, + field.ToString(), + typeStr)); + } + } + return found; + } + } +} diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index 10912b982..ab4456efe 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -119,8 +119,8 @@ private string GetWinmdOutputFile(GeneratorExecutionContext context) return Path.Combine(GetGeneratedFilesDir(context), GetAssemblyName(context) + ".winmd"); } - private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) - { + private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) + { Logger.Log("Writing " + outputFile); var managedPeBuilder = new ManagedPEBuilder( new PEHeaderBuilder( @@ -137,217 +137,46 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } - private static string diagnosticsLink = "https://docs.microsoft.com/en-us/previous-versions/hh977010(v=vs.110)"; - - private static DiagnosticDescriptor AsyncRule = MakeRule( - "WME1084", - "Async Interfaces Rule", - "Runtime component class {0} cannot implement async interface {1}; use AsyncInfo class methods instead of async interfaces"); - - private static DiagnosticDescriptor ClassConstructorRule = MakeRule( - "WME1099", - "Class Constructor Rule", - "Runtime component class {0} cannot have multiple constructors of the same arity {1}"); - - private static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( - "WME1092", - "Parameter Named Value Rule", - ("The method {0} has a parameter named {1} which is the same as the default return value name. " - + "Consider using another name for the parameter or use the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute " - + "to explicitly specify the name of the return value.")); - - private static DiagnosticDescriptor StructHasPropertyRule = MakeRule( - "WME1060(a)", - "Property in a Struct", - "The structure {0} has a property {1}. In Windows Runtime, structures can only contain public fields of basic types, enums and structures."); - - private static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( - "WME1060(b)", - "Private field in struct", - ("Structure {0} has private field. All fields must be public for Windows Runtime structures.")); - - private static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( - "WME1060", - "Invalid field in struct", - ("Structure {0} has field {1} of type {2}. {2} is not a valid Windows Runtime field type. Each field " + - "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.") ); - - - private static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) - { - return new DiagnosticDescriptor( - id: id, - title: title, - messageFormat: messageFormat, - category: "Usage", - /* Warnings dont fail command line build; winmd generation is prevented regardless of severity. - * Make this error when making final touches on this deliverable. */ - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - helpLinkUri: diagnosticsLink); - } - - static private string[] ProhibitedAsyncInterfaces = { - "Windows.Foundation.IAsyncAction", - "Windows.Foundation.IAsyncActionWithProgress`1", - "Windows.Foundation.IAsyncOperation`1", - "Windows.Foundation.IAsyncOperationWithProgress`2" - }; - - /* SameAsyncInterface uses the proper ISymbol equality check on the OriginalDefinition of the given symbols */ - private bool SameAsyncInterface(INamedTypeSymbol interfaceA, INamedTypeSymbol interfaceB) - { - /* Using OriginalDefinition b/c the generic field of the metadata type has the template name, e.g. `TProgress` - * and the actual interface will have a concrete type, e.g. `int` */ - return SymbolEqualityComparer.Default.Equals(interfaceA.OriginalDefinition, interfaceB.OriginalDefinition); - } - - /* ClassImplementsAsyncInterface returns true if the class represented by the symbol - implements any of the interfaces defined in ProhibitedAsyncInterfaces */ - private bool ImplementsAsyncInterface(GeneratorExecutionContext context, INamedTypeSymbol classSymbol, ClassDeclarationSyntax classDeclaration) - { - foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) - { - INamedTypeSymbol asyncInterface = context.Compilation.GetTypeByMetadataName(prohibitedInterface); - foreach (INamedTypeSymbol interfaceImplemented in classSymbol.AllInterfaces) - { - if (SameAsyncInterface(interfaceImplemented, asyncInterface)) - { - context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation(), classDeclaration.Identifier, interfaceImplemented)); - return true; - /* By exiting early, we only report diagnostic for first prohibited interface we see. - If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. - could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported */ - } - } - } - return false; - } - - /* HasMultipleConstructorsOfSameArity keeps track of the arity of all constructors seen, - * and reports the diagnostic (and exits) as soon as a duplicate is seen. */ - private bool HasMultipleConstructorsOfSameArity(GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - IEnumerable constructors = classDeclaration.ChildNodes().OfType(); - - /* more performant data structure? or use a Set, in order to not have to call Contains()? */ - IList aritiesSeenSoFar = new List(); - - foreach (ConstructorDeclarationSyntax constructor in constructors) - { - int arity = constructor.ParameterList.Parameters.Count; - - if (aritiesSeenSoFar.Contains(arity)) - { - context.ReportDiagnostic(Diagnostic.Create(ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity)); - return true; - } - else - { - aritiesSeenSoFar.Add(arity); - } - } - return false; - } - - /* HasParameterNamedValue */ - private bool HasReturnValueNameConflict(GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - IEnumerable methods = classDeclaration.ChildNodes().OfType(); - - foreach (MethodDeclarationSyntax method in methods) - { - foreach (ParameterSyntax parameter in method.ParameterList.Parameters) - { - if (parameter.Identifier.Value.Equals("__retval")) - { - context.ReportDiagnostic(Diagnostic.Create(ParameterNamedValueRule, parameter.GetLocation(), method.Identifier, parameter.Identifier)); - return true; - } - } - } - return false; - } - - private bool StructHasPropertyField(GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) + private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) { - var propertyDeclarations = structDeclaration.DescendantNodes().OfType(); - if (propertyDeclarations.Any()) - { - context.ReportDiagnostic(Diagnostic.Create(StructHasPropertyRule, structDeclaration.GetLocation(), structDeclaration.Identifier, propertyDeclarations.First().Identifier)); - return true; - } - return false; - } - - private bool StructHasInvalidFields(GeneratorExecutionContext context, FieldDeclarationSyntax field, StructDeclarationSyntax structDeclaration, List classNames) - { bool found = false; - - if (field.GetFirstToken().ToString().Equals("private")) // hmm - { - context.ReportDiagnostic(Diagnostic.Create(StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); - found |= true; - } - foreach (var variable in field.DescendantNodes().OfType()) + WinRTRules winrtRules = new WinRTRules(); + foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { - var type = variable.Type; - var typeStr = type.ToString(); - - List invalidTypes = new List { "object", "byte", "dynamic" }; - invalidTypes.AddRange(classNames); - - if (invalidTypes.Contains(typeStr)) - { - context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, - variable.GetLocation(), - structDeclaration.Identifier, - field.ToString(), - typeStr)); - } - } - return found; - } - - private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) - { - bool found = false; - - foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) - { - var model = context.Compilation.GetSemanticModel(tree); + var model = context.Compilation.GetSemanticModel(tree); var nodes = tree.GetRoot().DescendantNodes(); - - var classes = nodes.OfType(); + + var classes = nodes.OfType(); var structs = nodes.OfType(); // Used in checking structure fields List classNames = new List(); - /* look for... */ + /* Check all classes */ foreach (ClassDeclarationSyntax classDeclaration in classes) - { + { classNames.Add(classDeclaration.Identifier.ToString()); /* parameters named __retval*/ - found |= HasReturnValueNameConflict(context, classDeclaration); + found |= winrtRules.HasReturnValueNameConflict(ref context, classDeclaration); /* multiple constructors of the same arity */ - found |= HasMultipleConstructorsOfSameArity(context, classDeclaration); + found |= winrtRules.HasMultipleConstructorsOfSameArity(ref context, classDeclaration); /* implementing async interfaces */ var classSymbol = model.GetDeclaredSymbol(classDeclaration); - found |= ImplementsAsyncInterface(context, classSymbol, classDeclaration); + found |= winrtRules.ImplementsAsyncInterface(ref context, classSymbol, classDeclaration); } + /* Check all structs */ foreach (StructDeclarationSyntax structDeclaration in structs) { - found |= StructHasPropertyField(context, structDeclaration); + found |= winrtRules.StructHasPropertyField(ref context, structDeclaration); var fields = structDeclaration.DescendantNodes().OfType(); foreach (var field in fields) { - found |= StructHasInvalidFields(context, field, structDeclaration, classNames); + found |= winrtRules.StructHasInvalidFields(ref context, field, structDeclaration, classNames); } } } @@ -363,7 +192,7 @@ public void Execute(GeneratorExecutionContext context) Logger.Initialize(context); - if (CatchWinRTDiagnostics(context)) + if (CatchWinRTDiagnostics(ref context)) { Logger.Log("Exiting early -- found errors in authored runtime component."); Logger.Close(); From 723a560e23bb2f70be8fdbf30a0ce84ee18a4507 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 20 Nov 2020 14:52:11 -0800 Subject: [PATCH 15/41] full diagnostics for struct fields --- Authoring/TestDiagnostics/Scenarios.cs | 71 ++++++++++++---- .../WinRT.SourceGenerator/DiagnosticRules.cs | 82 ++++++++++++++----- Authoring/WinRT.SourceGenerator/Generator.cs | 10 ++- 3 files changed, 125 insertions(+), 38 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index de24fa2bf..8b618fae1 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -1,4 +1,5 @@ using ABI.System.Numerics; +using ABI.Windows.ApplicationModel.Contacts; using System; using System.Runtime.ExceptionServices; using Windows.Foundation; @@ -24,6 +25,44 @@ public struct StructWithClass_Invalid public SillyClass classField; } + public struct StructWithDelegate_Invalid + { + public delegate int ADelegate(int x); + } + + public struct StructWithEvent_Invalid + { + public event EventHandler EventField; + } + + public struct StructWithConstructor_Invalid + { + int X; + StructWithConstructor_Invalid(int x) + { + X = x; + } + } + + public struct StructWithIndexer_Invalid + { + int[] arr; + int this[int i] => arr[i]; + } + + public struct StructWithMethods_Invalid + { + int foo(int x) + { + return x; + } + } + public struct StructWithConst_Invalid // really invalid ? + { + const int five = 5; + } + + /* public enum BasicEnum { First = 0, @@ -37,15 +76,17 @@ public struct Posn_Invalid public int x { get; } public int y { get; } } + */ + /* public struct StructWithPrivateField_Invalid { const int ci = 5; private int x; } - /* */ + */ - /**/ + /* public struct StructWithAllValidFields { bool boolean; @@ -61,9 +102,9 @@ public struct StructWithAllValidFields ushort us; string str; } - /**/ + */ - /**/ + /* public struct StructWithObjectField_Invalid // is this really invalid? { object obj; @@ -83,9 +124,9 @@ public struct StructWithWinRTStructField { public Matrix3x2 matrix; } - /**/ + */ - /**/ + /* public sealed class ParameterNamedDunderRetVal { public int Identity(int __retval) @@ -93,9 +134,9 @@ public int Identity(int __retval) return __retval; } } - /**/ + */ - /**/ + /* public sealed class SameArityConstructors { private int num; @@ -116,9 +157,9 @@ public SameArityConstructors(string s) // Can test that multiple constructors are allowed (has been verified already, too) // as long as they have different arities by making one take none or 2 arguments } - /**/ + */ - /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? */ + /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress { public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -168,7 +209,9 @@ void IAsyncActionWithProgress.GetResults() throw new NotImplementedException(); } } - + */ + + /* public class ActionWithProgress : IAsyncActionWithProgress { AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -195,9 +238,9 @@ void IAsyncActionWithProgress.GetResults() throw new NotImplementedException(); } } - /**/ + */ - /**/ + /* public sealed class OpWithProgress : IAsyncOperationWithProgress { AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -250,5 +293,5 @@ int IAsyncOperation.GetResults() throw new NotImplementedException(); } } - /**/ + */ } diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index 640403084..e1547aa14 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -1,12 +1,16 @@ using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Collections; using System.Collections.Generic; using System.Linq; namespace Generator { public class WinRTRules - { + { + #region RuleDescriptors + /* MakeRule is a helper function that does most of the boilerplate information needed for Diagnostics param id : string, a short identifier for the diagnostic param title : string, a few words generally describing the diagnostic @@ -43,11 +47,6 @@ static DiagnosticDescriptor MakeRule(string id, string title, string messageForm + "Consider using another name for the parameter or use the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute " + "to explicitly specify the name of the return value.")); - static DiagnosticDescriptor StructHasPropertyRule = MakeRule( - "WME1060(a)", - "Property in a Struct", - "The structure {0} has a property {1}. In Windows Runtime, structures can only contain public fields of basic types, enums and structures."); - static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( "WME1060(b)", "Private field in struct", @@ -56,9 +55,16 @@ static DiagnosticDescriptor MakeRule(string id, string title, string messageForm static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( "WME1060", "Invalid field in struct", - ("Structure {0} has field {1} of type {2}. {2} is not a valid Windows Runtime field type. Each field " + ("Structure {0} has field '{1}' of type {2}; {2} is not a valid Windows Runtime field type. Each field " + + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.")); + + static DiagnosticDescriptor StructHasInvalidFieldRule2 = MakeRule( + "WME1060", + "Invalid field in struct", + ("Structure {0} has a field of type {1}; {1} is not a valid Windows Runtime field type. Each field " + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.")); + #endregion /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ static string[] ProhibitedAsyncInterfaces = { @@ -77,7 +83,7 @@ private bool SameAsyncInterface(INamedTypeSymbol interfaceA, INamedTypeSymbol in } /* ImplementsAsyncInterface - returns true if the class represented by the symbol implements any of the interfaces defined in ProhibitedAsyncInterfaces */ + * returns true if the class represented by the symbol implements any of the interfaces defined in ProhibitedAsyncInterfaces */ public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INamedTypeSymbol classSymbol, ClassDeclarationSyntax classDeclaration) { foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) @@ -99,7 +105,7 @@ public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INam } /* HasMultipleConstructorsOfSameArity - keeps track of the arity of all constructors, and reports the diagnostic (and exits) as soon as a two constructors of the same arity are seen. */ + * keeps track of the arity of all constructors, and reports the diagnostic (and exits) as soon as a two constructors of the same arity are seen. */ public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { IEnumerable constructors = classDeclaration.ChildNodes().OfType(); @@ -125,8 +131,8 @@ public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext con } /* HasParameterNamedValue - the generated code for components uses the name "__retval" for the output variable, - we report diagnostic if a user uses this same identifier as a parameter to a method */ + * the generated code for components uses the name "__retval" for the output variable, + * we report diagnostic if a user uses this same identifier as a parameter to a method */ public bool HasReturnValueNameConflict(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { IEnumerable methods = classDeclaration.ChildNodes().OfType(); @@ -145,34 +151,65 @@ public bool HasReturnValueNameConflict(ref GeneratorExecutionContext context, Cl return false; } - /* StructHasPropertyField - structs cannot have properties in the Windows Runtime */ - public bool StructHasPropertyField(ref GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) - { - var propertyDeclarations = structDeclaration.DescendantNodes().OfType(); - if (propertyDeclarations.Any()) + /* SimplifySyntaxTypeString + * returns the more common term for the given kind of syntax; used when creating a diagnostic for an invalid field in a struct */ + private string SimplifySyntaxTypeString(string syntaxType) + { + switch (syntaxType) { - context.ReportDiagnostic(Diagnostic.Create(StructHasPropertyRule, structDeclaration.GetLocation(), structDeclaration.Identifier, propertyDeclarations.First().Identifier)); + case "EventFieldDeclarationSyntax": + return "event"; + case "ConstructorDeclarationSyntax": + return "constructor"; + case "DelegateDeclarationSyntax": + return "delegate"; + case "IndexerDeclarationSyntax": + return "indexer"; + case "MethodDeclarationSyntax": + return "method"; + case "OperatorDeclarationSyntax": + return "operator"; + case "PropertyDeclarationSyntax": + return "property"; + default: + return "unknown syntax type: " + syntaxType; + } + } + + /* StructHasFieldOfType + * returns true iff there is a declaration of a field with the given type argument + * e.g., if a struct has a property, and T is PropertyDeclarationSyntax, we report a diagnostic and return true */ + public bool StructHasFieldOfType(ref GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) + { + if (structDeclaration.DescendantNodes().OfType().Any()) + { + context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule2, + structDeclaration.GetLocation(), + structDeclaration.Identifier, + SimplifySyntaxTypeString(typeof(T).Name))); return true; } return false; } + /* StructHasInvalidFields - structs can only contain fields of primitive types, enums, and other structs */ - public bool StructHasInvalidFields(ref GeneratorExecutionContext context, FieldDeclarationSyntax field, StructDeclarationSyntax structDeclaration, List classNames) + * returns true if there is a field declared private, + * or (inclusive) declared with a type that is a class or one of object, byte or dynamic */ + public bool StructHasFieldOfInvalidType(ref GeneratorExecutionContext context, FieldDeclarationSyntax field, StructDeclarationSyntax structDeclaration, List classNames) { bool found = false; + /* No private fields allowed in Windows Runtime components */ if (field.GetFirstToken().ToString().Equals("private")) // hmm { context.ReportDiagnostic(Diagnostic.Create(StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); found |= true; } + foreach (var variable in field.DescendantNodes().OfType()) { - var type = variable.Type; - var typeStr = type.ToString(); + var typeStr = variable.Type.ToString(); List invalidTypes = new List { "object", "byte", "dynamic" }; invalidTypes.AddRange(classNames); @@ -184,6 +221,7 @@ public bool StructHasInvalidFields(ref GeneratorExecutionContext context, FieldD structDeclaration.Identifier, field.ToString(), typeStr)); + found |= true; } } return found; diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index ab4456efe..5b0a1d30b 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -171,12 +171,18 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) /* Check all structs */ foreach (StructDeclarationSyntax structDeclaration in structs) { - found |= winrtRules.StructHasPropertyField(ref context, structDeclaration); + found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); + found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); + found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); + found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); + found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); + found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); + found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); var fields = structDeclaration.DescendantNodes().OfType(); foreach (var field in fields) { - found |= winrtRules.StructHasInvalidFields(ref context, field, structDeclaration, classNames); + found |= winrtRules.StructHasFieldOfInvalidType(ref context, field, structDeclaration, classNames); } } } From 0ea88857abdfe43e58ffa5be8cb6cd798a15065e Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 20 Nov 2020 17:27:24 -0800 Subject: [PATCH 16/41] adding operator overload diagnostic and method overload, the latter needs a bit of fine tuning --- Authoring/TestDiagnostics/Scenarios.cs | 183 +++++++++++++++++- .../WinRT.SourceGenerator/DiagnosticRules.cs | 112 ++++++++++- Authoring/WinRT.SourceGenerator/Generator.cs | 5 +- 3 files changed, 292 insertions(+), 8 deletions(-) diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 8b618fae1..2558484c3 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -8,9 +8,188 @@ namespace TestDiagnostics { - + + // valid method overload tests + public sealed class TwoOverloads_DiffParamCount_OneAttribute_OneInList_Valid + { + + // pretty sure diagnostic will get thrown for this right now BUT it shouldn't + + // the fix could be to append the method name (as a string) with its arity (as a string) and add that as the key to the map + // so the map isnt exactly the method name, but methodnameN where N is the arity of the methodname at that time + // think this fix would mean no logic has to change on the "have we seen this methodname before and did it have the attribute" + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n, int m) { return n; } + } + + public sealed class TwoOverloads_OneAttribute_OneInList_Valid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_OneAttribute_OneIrrelevatAttribute_Valid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_OneAttribute_TwoLists_Valid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + + public sealed class ThreeOverloads_OneAttribute_Valid + { + + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + public bool OverloadExample(bool b) { return b; } + } + + public sealed class ThreeOverloads_OneAttribute_2_Valid + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } + + public sealed class TwoOverloads_OneAttribute_3_Valid + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + // invalid method overload tests + public sealed class TwoOverloads_NoAttribute_Invalid + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_OneInList_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_NoAttribute_OneIrrevAttr_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_BothInList_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_TwoLists_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_BothInSeparateList_Invalid + { + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_Invalid + { + + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class ThreeOverloads_TwoAttributes_Invalid + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } + + + // end overload method tests + + public sealed class ClassThatOverloadsOperator + { + public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) // the rule needs update, it says "operator" instead of "+" + { + return thing; + } + } + + /* public sealed class SillyClass { public double Identity(double d) @@ -19,7 +198,6 @@ public double Identity(double d) } } - /* */ public struct StructWithClass_Invalid { public SillyClass classField; @@ -61,6 +239,7 @@ public struct StructWithConst_Invalid // really invalid ? { const int five = 5; } + */ /* public enum BasicEnum diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index e1547aa14..fe405cf68 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -64,6 +64,23 @@ static DiagnosticDescriptor MakeRule(string id, string title, string messageForm ("Structure {0} has a field of type {1}; {1} is not a valid Windows Runtime field type. Each field " + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.")); + static DiagnosticDescriptor OperatorOverloadedRule = MakeRule( + "WME1087", + "Operator overload exposed", + "{0} is an operator overload. Managed types cannot expose operator overloads in the Windows Runtime"); + + static DiagnosticDescriptor MethodOverload_MultipleDefaultAttribute = MakeRule( + "WME1059", + "Only one overload should be designated default", // todo better msg + //"Multiple {0}-parameter overloads of '{1}.{2}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + "Multiple {0}-parameter overloads of '{1}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + + static DiagnosticDescriptor MethodOverload_NeedDefaultAttribute = MakeRule( + "WME1085", + "Multiple overloads seen, one needs a default", // todo better msg + //"The {0}-parameter overloads of {1}.{2} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + "The {0}-parameter overloads of {1} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + #endregion /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ @@ -130,23 +147,96 @@ public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext con return false; } + /* HasParameterNamedValue * the generated code for components uses the name "__retval" for the output variable, * we report diagnostic if a user uses this same identifier as a parameter to a method */ - public bool HasReturnValueNameConflict(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + public bool HasParameterNamedValue(ref GeneratorExecutionContext context, MethodDeclarationSyntax method) + { + foreach (ParameterSyntax parameter in method.ParameterList.Parameters) + { + if (parameter.Identifier.Value.Equals("__retval")) + { + context.ReportDiagnostic(Diagnostic.Create(ParameterNamedValueRule, parameter.GetLocation(), method.Identifier, parameter.Identifier)); + return true; + } + } + return false; + } + + public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { + bool found = false; IEnumerable methods = classDeclaration.ChildNodes().OfType(); + // the boolean indicates that the method name (the key) has been marked as the DefaultOverload (via an attribute) + Dictionary myMap = new Dictionary(); + foreach (MethodDeclarationSyntax method in methods) { - foreach (ParameterSyntax parameter in method.ParameterList.Parameters) + string methodName = method.Identifier.Text; + + bool seenMethodBefore = myMap.TryGetValue(methodName, out bool methodHasAttrAlready); + + bool hasDefaultOverloadAttribute = false; + + // look at all the attributes on this method and see if any of them is the DefaultOverload attribute + foreach (var attrList in method.AttributeLists) + { + foreach (var attr in attrList.Attributes) + { + if (attr.Name.ToString().Equals("Windows.Foundation.Metadata.DefaultOverload")) // maybe name is just DefaultOverload? + { + hasDefaultOverloadAttribute = true; + break; + } + } + } + + // what do we do if it is in there but not with the attribute ? + // what do we do if above AND we see the attribute now + // what do we do if above AND we DONT see the attribute now + + // ... + + // later if we have seen it before... + // and if it doesnt have it now and it didnt have it before, raise the "add attribute error" + // if it doesnt have it now and it did before, thats fine, + // note: dont change its mapping! + + // if it has it now and it didn't before, thats fine (make sure to mark it as having it) + // if it has it now and it did before, raise "multiple attributes error" + + // Do we have an overload ? + if (seenMethodBefore) { - if (parameter.Identifier.Value.Equals("__retval")) + if (hasDefaultOverloadAttribute && !methodHasAttrAlready) { - context.ReportDiagnostic(Diagnostic.Create(ParameterNamedValueRule, parameter.GetLocation(), method.Identifier, parameter.Identifier)); - return true; + // we've seen it, but it didnt have the attribute, so mark that it has it now + myMap[methodName] = true; } + else if (hasDefaultOverloadAttribute && methodHasAttrAlready) + { + // raise the "dont have multiple default overloads attributed" diagnostic + context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), method.Arity, method.Identifier)); + found |= true; + } + else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) + { + // raise the "multiple overloads, one needs the attribute!" + context.ReportDiagnostic(Diagnostic.Create(MethodOverload_NeedDefaultAttribute, method.GetLocation(), method.Arity, method.Identifier)); + found |= true; + } + } + else + { + // if the method hasn't been seen before, this will make a new pair and mark it + myMap[methodName] = hasDefaultOverloadAttribute; // this is where we store it with value false } + + + /* make sure no parameter has the name "__retval" */ + found |= HasParameterNamedValue(ref context, method); } return false; } @@ -226,5 +316,17 @@ public bool StructHasFieldOfInvalidType(ref GeneratorExecutionContext context, F } return found; } + + public bool OverloadsOperator(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + var operatorDeclarations = classDeclaration.DescendantNodes().OfType(); + if (operatorDeclarations.Any()) + { + var overloadedOperator = operatorDeclarations.First(); + context.ReportDiagnostic(Diagnostic.Create(OperatorOverloadedRule, overloadedOperator.GetLocation(), overloadedOperator.OperatorKeyword.Text)); + return true; + } + return false; + } } } diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index 5b0a1d30b..a107b9fe0 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -157,8 +157,11 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) { classNames.Add(classDeclaration.Identifier.ToString()); + /* exposes an operator overload */ + found |= winrtRules.OverloadsOperator(ref context, classDeclaration); + /* parameters named __retval*/ - found |= winrtRules.HasReturnValueNameConflict(ref context, classDeclaration); + found |= winrtRules.HasErrorsInMethods(ref context, classDeclaration); /* multiple constructors of the same arity */ found |= winrtRules.HasMultipleConstructorsOfSameArity(ref context, classDeclaration); From 4c3708441781b1f9d93722227f2071ffb5636394 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 20 Nov 2020 22:51:32 -0800 Subject: [PATCH 17/41] tinkering still --- .../TestDiagnostics/Directory.Build.targets | 2 +- Authoring/TestDiagnostics/Scenarios.cs | 5 +- .../TestDiagnostics/TestDiagnostics.csproj | 2 +- .../WinRT.SourceGenerator/DiagnosticRules.cs | 206 +++++++++++++----- Authoring/WinRT.SourceGenerator/Generator.cs | 2 +- 5 files changed, 161 insertions(+), 56 deletions(-) diff --git a/Authoring/TestDiagnostics/Directory.Build.targets b/Authoring/TestDiagnostics/Directory.Build.targets index 53a2d80be..cee38e58e 100644 --- a/Authoring/TestDiagnostics/Directory.Build.targets +++ b/Authoring/TestDiagnostics/Directory.Build.targets @@ -3,7 +3,7 @@ - + diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 2558484c3..17929cd87 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -10,7 +10,7 @@ namespace TestDiagnostics { // valid method overload tests - public sealed class TwoOverloads_DiffParamCount_OneAttribute_OneInList_Valid + public sealed class TwoOverloads_DiffParamCount_Valid { // pretty sure diagnostic will get thrown for this right now BUT it shouldn't @@ -85,6 +85,7 @@ public sealed class TwoOverloads_OneAttribute_3_Valid // invalid method overload tests public sealed class TwoOverloads_NoAttribute_Invalid { + // hmm public string OverloadExample(string s) { return s; } public int OverloadExample(int n) { return n; } @@ -103,7 +104,7 @@ public sealed class TwoOverloads_TwoAttribute_OneInList_Invalid public sealed class TwoOverloads_NoAttribute_OneIrrevAttr_Invalid { - + // hmm [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] public string OverloadExample(string s) { return s; } diff --git a/Authoring/TestDiagnostics/TestDiagnostics.csproj b/Authoring/TestDiagnostics/TestDiagnostics.csproj index 14a7b7e8f..7376cb5f6 100644 --- a/Authoring/TestDiagnostics/TestDiagnostics.csproj +++ b/Authoring/TestDiagnostics/TestDiagnostics.csproj @@ -19,9 +19,9 @@ - + diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index fe405cf68..f3aa674eb 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -73,13 +73,13 @@ static DiagnosticDescriptor MakeRule(string id, string title, string messageForm "WME1059", "Only one overload should be designated default", // todo better msg //"Multiple {0}-parameter overloads of '{1}.{2}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); - "Multiple {0}-parameter overloads of '{1}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + "In class {2}: Multiple {0}-parameter overloads of '{1}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); static DiagnosticDescriptor MethodOverload_NeedDefaultAttribute = MakeRule( "WME1085", "Multiple overloads seen, one needs a default", // todo better msg //"The {0}-parameter overloads of {1}.{2} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); - "The {0}-parameter overloads of {1} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + "In class {2}: The {0}-parameter overloads of {1} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); #endregion @@ -164,80 +164,184 @@ public bool HasParameterNamedValue(ref GeneratorExecutionContext context, Method return false; } + + // what do we do if it is in there but not with the attribute ? + // what do we do if above AND we see the attribute now + // what do we do if above AND we DONT see the attribute now + + // ... + + // later if we have seen it before... + // and if it doesnt have it now and it didnt have it before, raise the "add attribute error" + // if it doesnt have it now and it did before, thats fine, + // note: dont change its mapping! + + // if it has it now and it didn't before, thats fine (make sure to mark it as having it) + // if it has it now and it did before, raise "multiple attributes error" + + /// MethodHasAttribute looks at all possible attributes on a given method declaration + /// returns true iff any are (string) equal to the given attribute name + private bool MethodHasAttribute(string attrName, MethodDeclarationSyntax method) + { + foreach (var attrList in method.AttributeLists) + { + foreach (var attr in attrList.Attributes) + { + if (attr.Name.ToString().Equals(attrName)) + { + return true; + } + } + } + return false; + } + + private bool CheckOverloadAttributes_v2(MethodDeclarationSyntax method, ref Dictionary myMap, ClassDeclarationSyntax classDeclaration, ref GeneratorExecutionContext context) + { + bool found = false; + + return found; + } + + private bool CheckOverloadAttributes(MethodDeclarationSyntax method, ref Dictionary myMap, ClassDeclarationSyntax classDeclaration, ref GeneratorExecutionContext context) + { + bool found = false; + int methodArity = method.ParameterList.Parameters.Count; + string methodNameWithArity = method.Identifier.Text + methodArity.ToString(); + + // look at all the attributes on this method and see if any of them is the DefaultOverload attribute + bool hasDefaultOverloadAttribute = MethodHasAttribute("Windows.Foundation.Metadata.DefaultOverload", method); + + bool seenMethodBefore = myMap.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); + // Do we have an overload ? + if (seenMethodBefore) + { + if (hasDefaultOverloadAttribute && !methodHasAttrAlready) + { + // we've seen it, but it didnt have the attribute, so mark that it has it now + myMap[methodNameWithArity] = true; + } + else if (hasDefaultOverloadAttribute && methodHasAttrAlready) + { + // raise the "dont have multiple default overloads attributed" diagnostic + context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), + methodArity, method.Identifier, classDeclaration.Identifier)); + found |= true; + } + else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) + { + // raise the "multiple overloads, one needs the attribute!" + context.ReportDiagnostic(Diagnostic.Create(MethodOverload_NeedDefaultAttribute, method.GetLocation(), + methodArity, method.Identifier, classDeclaration.Identifier)); + found |= true; + } + } + else + { + // if the method hasn't been seen before, this will make a new pair and mark it + myMap[methodNameWithArity] = hasDefaultOverloadAttribute; // this is where we store it with value false + } + + return found; + } + public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { bool found = false; IEnumerable methods = classDeclaration.ChildNodes().OfType(); - // the boolean indicates that the method name (the key) has been marked as the DefaultOverload (via an attribute) - Dictionary myMap = new Dictionary(); + // int indicates how many declarations of this method have been decorated as DefaultOverload + Dictionary singularMethods = new Dictionary(); + Dictionary overloadedMethods = new Dictionary(); foreach (MethodDeclarationSyntax method in methods) { - string methodName = method.Identifier.Text; + int methodArity = method.ParameterList.Parameters.Count; + string methodNameWithArity = method.Identifier.Text + methodArity.ToString(); - bool seenMethodBefore = myMap.TryGetValue(methodName, out bool methodHasAttrAlready); + // look at all the attributes on this method and see if any of them is the DefaultOverload attribute + bool hasDefaultOverloadAttribute = MethodHasAttribute("Windows.Foundation.Metadata.DefaultOverload", method); - bool hasDefaultOverloadAttribute = false; + // + bool seenOverloadBefore = overloadedMethods.TryGetValue(methodNameWithArity, out int timesAttributed); + bool seenSingularBefore = singularMethods.TryGetValue(methodNameWithArity, out int zeroOrOne); - // look at all the attributes on this method and see if any of them is the DefaultOverload attribute - foreach (var attrList in method.AttributeLists) + if (seenSingularBefore) { - foreach (var attr in attrList.Attributes) + singularMethods.Remove(methodNameWithArity); + if (hasDefaultOverloadAttribute && zeroOrOne == 1) + { + context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), + methodArity, method.Identifier, classDeclaration.Identifier)); + found |= true; + + // invariant, if its in singular its not in overloaded + overloadedMethods[methodNameWithArity] = 2; + } + else { - if (attr.Name.ToString().Equals("Windows.Foundation.Metadata.DefaultOverload")) // maybe name is just DefaultOverload? + overloadedMethods[methodNameWithArity] = hasDefaultOverloadAttribute ? 1 : 0; + } + } + else if (seenOverloadBefore) + { + if (hasDefaultOverloadAttribute) + { + if (timesAttributed > 0) { - hasDefaultOverloadAttribute = true; - break; + context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), + methodArity, method.Identifier, classDeclaration.Identifier)); + found |= true; } - } + ++overloadedMethods[methodNameWithArity]; + } + } + else + { + singularMethods.Add(methodNameWithArity, hasDefaultOverloadAttribute ? 1 : 0); } - // what do we do if it is in there but not with the attribute ? - // what do we do if above AND we see the attribute now - // what do we do if above AND we DONT see the attribute now - // ... + /* + // if we know this is an overload + // and at least one of the (previously seen) overloads has the attribute already + // and the current declaration also has the attribute... + // report "cant declare multiple as default" + if (seenOverloadBefore && timesAttributed > 0 && hasDefaultOverloadAttribute) // might be more efficient to move the actual call to MethodHasAttribute here ... + { + context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), + methodArity, method.Identifier, classDeclaration.Identifier)); + found |= true; + } + else if (seenOverloadBefore && timesAttributed > 0) + { + // just make sure we don't see it in singularMethods again + singularMethods.Remove(methodNameWithArity); + } - // later if we have seen it before... - // and if it doesnt have it now and it didnt have it before, raise the "add attribute error" - // if it doesnt have it now and it did before, thats fine, - // note: dont change its mapping! - // if it has it now and it didn't before, thats fine (make sure to mark it as having it) - // if it has it now and it did before, raise "multiple attributes error" - - // Do we have an overload ? - if (seenMethodBefore) + if (!seenOverloadBefore) { - if (hasDefaultOverloadAttribute && !methodHasAttrAlready) - { - // we've seen it, but it didnt have the attribute, so mark that it has it now - myMap[methodName] = true; - } - else if (hasDefaultOverloadAttribute && methodHasAttrAlready) - { - // raise the "dont have multiple default overloads attributed" diagnostic - context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), method.Arity, method.Identifier)); - found |= true; - } - else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) - { - // raise the "multiple overloads, one needs the attribute!" - context.ReportDiagnostic(Diagnostic.Create(MethodOverload_NeedDefaultAttribute, method.GetLocation(), method.Arity, method.Identifier)); - found |= true; - } - } - else - { - // if the method hasn't been seen before, this will make a new pair and mark it - myMap[methodName] = hasDefaultOverloadAttribute; // this is where we store it with value false + singularMethods[methodNameWithArity] = hasDefaultOverloadAttribute ? 1 : 0; } + */ + + // bool seenMethodBefore = overloadedMethods.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); + // found |= CheckOverloadAttributes(method, ref myMap, classDeclaration, ref context); /* make sure no parameter has the name "__retval" */ found |= HasParameterNamedValue(ref context, method); } + foreach (var thing in overloadedMethods) + { + if (thing.Value == 0) + { + context.ReportDiagnostic(Diagnostic.Create(MethodOverload_NeedDefaultAttribute, classDeclaration.GetLocation(), + thing.Key, thing.Key, classDeclaration.Identifier)); + found |= true; + } + } return false; } @@ -267,8 +371,8 @@ private string SimplifySyntaxTypeString(string syntaxType) } /* StructHasFieldOfType - * returns true iff there is a declaration of a field with the given type argument - * e.g., if a struct has a property, and T is PropertyDeclarationSyntax, we report a diagnostic and return true */ + * returns true iff there is a field of the given type in the given struct + * e.g., if T is PropertyDeclarationSyntax, then if a struct has a property, we report a diagnostic and return true */ public bool StructHasFieldOfType(ref GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) { if (structDeclaration.DescendantNodes().OfType().Any()) diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index a107b9fe0..a3fbec5df 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -149,7 +149,7 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) var classes = nodes.OfType(); var structs = nodes.OfType(); - // Used in checking structure fields + // Used in the checking of structure fields List classNames = new List(); /* Check all classes */ From 043073448c63b7db0f24654d4beb96f225147b52 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 23 Nov 2020 11:51:24 -0800 Subject: [PATCH 18/41] finished work on checking overloaded methods --- .../WinRT.SourceGenerator/DiagnosticRules.cs | 154 +++++------------- 1 file changed, 38 insertions(+), 116 deletions(-) diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index f3aa674eb..51f38db55 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -164,21 +164,6 @@ public bool HasParameterNamedValue(ref GeneratorExecutionContext context, Method return false; } - - // what do we do if it is in there but not with the attribute ? - // what do we do if above AND we see the attribute now - // what do we do if above AND we DONT see the attribute now - - // ... - - // later if we have seen it before... - // and if it doesnt have it now and it didnt have it before, raise the "add attribute error" - // if it doesnt have it now and it did before, thats fine, - // note: dont change its mapping! - - // if it has it now and it didn't before, thats fine (make sure to mark it as having it) - // if it has it now and it did before, raise "multiple attributes error" - /// MethodHasAttribute looks at all possible attributes on a given method declaration /// returns true iff any are (string) equal to the given attribute name private bool MethodHasAttribute(string attrName, MethodDeclarationSyntax method) @@ -196,14 +181,20 @@ private bool MethodHasAttribute(string attrName, MethodDeclarationSyntax method) return false; } - private bool CheckOverloadAttributes_v2(MethodDeclarationSyntax method, ref Dictionary myMap, ClassDeclarationSyntax classDeclaration, ref GeneratorExecutionContext context) - { - bool found = false; - - return found; - } - - private bool CheckOverloadAttributes(MethodDeclarationSyntax method, ref Dictionary myMap, ClassDeclarationSyntax classDeclaration, ref GeneratorExecutionContext context) + /// + /// Returns true if multiple overloads of a method are found where more than one has been designated as the default overload + /// + /// The method to check attributes for + /// Keeps track of the method (via name + arity) and whether it was declared with the DefaultOverload attribute + /// Keeps track of the methods that are overloads but don't have the DefaultOverload attribute (yet) + /// The class the method lives in -- used for creating the diagnostic + /// The SourceGenerator context the code lives in + /// + private bool CheckOverloadAttributes(MethodDeclarationSyntax method, + ref Dictionary methodHasAttributeMap, + ref Dictionary overloadsWithoutAttributeMap, + ClassDeclarationSyntax classDeclaration, + ref GeneratorExecutionContext context) { bool found = false; int methodArity = method.ParameterList.Parameters.Count; @@ -212,34 +203,35 @@ private bool CheckOverloadAttributes(MethodDeclarationSyntax method, ref Diction // look at all the attributes on this method and see if any of them is the DefaultOverload attribute bool hasDefaultOverloadAttribute = MethodHasAttribute("Windows.Foundation.Metadata.DefaultOverload", method); - bool seenMethodBefore = myMap.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); + bool seenMethodBefore = methodHasAttributeMap.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); + // Do we have an overload ? if (seenMethodBefore) { if (hasDefaultOverloadAttribute && !methodHasAttrAlready) { // we've seen it, but it didnt have the attribute, so mark that it has it now - myMap[methodNameWithArity] = true; + methodHasAttributeMap[methodNameWithArity] = true; + overloadsWithoutAttributeMap.Remove(methodNameWithArity); } else if (hasDefaultOverloadAttribute && methodHasAttrAlready) { - // raise the "dont have multiple default overloads attributed" diagnostic + // raise the "can't have multiple default attributes" diagnostic context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classDeclaration.Identifier)); found |= true; } else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) { - // raise the "multiple overloads, one needs the attribute!" - context.ReportDiagnostic(Diagnostic.Create(MethodOverload_NeedDefaultAttribute, method.GetLocation(), - methodArity, method.Identifier, classDeclaration.Identifier)); - found |= true; + // we could see this method later with the attribute, so hold onto the diagnostic for it until we know it doesn't have the attribute + Diagnostic diagnostic = Diagnostic.Create(MethodOverload_NeedDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classDeclaration.Identifier); + overloadsWithoutAttributeMap[methodNameWithArity] = diagnostic; } } else { - // if the method hasn't been seen before, this will make a new pair and mark it - myMap[methodNameWithArity] = hasDefaultOverloadAttribute; // this is where we store it with value false + // first time we're seeing the method, add a pair in the map for its name and whether it has the attribute + methodHasAttributeMap[methodNameWithArity] = hasDefaultOverloadAttribute; } return found; @@ -250,99 +242,29 @@ public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDecla bool found = false; IEnumerable methods = classDeclaration.ChildNodes().OfType(); - // int indicates how many declarations of this method have been decorated as DefaultOverload - Dictionary singularMethods = new Dictionary(); - Dictionary overloadedMethods = new Dictionary(); + Dictionary methodsHasAttributeMap = new Dictionary(); + + /* we can't throw the diagnostic as soon as we see a second overload without an attribute, + * as there could be a third overload with the default attribute + * we use this map to keep track of these cases, and after we have checked all methods, + * we check the elements of the map to raise diagnostics for those that didn't get attributed */ + Dictionary overloadsWithoutAttributeMap = new Dictionary(); foreach (MethodDeclarationSyntax method in methods) { - int methodArity = method.ParameterList.Parameters.Count; - string methodNameWithArity = method.Identifier.Text + methodArity.ToString(); - - // look at all the attributes on this method and see if any of them is the DefaultOverload attribute - bool hasDefaultOverloadAttribute = MethodHasAttribute("Windows.Foundation.Metadata.DefaultOverload", method); - - // - bool seenOverloadBefore = overloadedMethods.TryGetValue(methodNameWithArity, out int timesAttributed); - bool seenSingularBefore = singularMethods.TryGetValue(methodNameWithArity, out int zeroOrOne); - - if (seenSingularBefore) - { - singularMethods.Remove(methodNameWithArity); - if (hasDefaultOverloadAttribute && zeroOrOne == 1) - { - context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), - methodArity, method.Identifier, classDeclaration.Identifier)); - found |= true; - - // invariant, if its in singular its not in overloaded - overloadedMethods[methodNameWithArity] = 2; - } - else - { - overloadedMethods[methodNameWithArity] = hasDefaultOverloadAttribute ? 1 : 0; - } - } - else if (seenOverloadBefore) - { - if (hasDefaultOverloadAttribute) - { - if (timesAttributed > 0) - { - context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), - methodArity, method.Identifier, classDeclaration.Identifier)); - found |= true; - } - ++overloadedMethods[methodNameWithArity]; - } - } - else - { - singularMethods.Add(methodNameWithArity, hasDefaultOverloadAttribute ? 1 : 0); - } - - - /* - // if we know this is an overload - // and at least one of the (previously seen) overloads has the attribute already - // and the current declaration also has the attribute... - // report "cant declare multiple as default" - if (seenOverloadBefore && timesAttributed > 0 && hasDefaultOverloadAttribute) // might be more efficient to move the actual call to MethodHasAttribute here ... - { - context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), - methodArity, method.Identifier, classDeclaration.Identifier)); - found |= true; - } - else if (seenOverloadBefore && timesAttributed > 0) - { - // just make sure we don't see it in singularMethods again - singularMethods.Remove(methodNameWithArity); - } - - - if (!seenOverloadBefore) - { - singularMethods[methodNameWithArity] = hasDefaultOverloadAttribute ? 1 : 0; - } - */ - - // bool seenMethodBefore = overloadedMethods.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); - - // found |= CheckOverloadAttributes(method, ref myMap, classDeclaration, ref context); + /* Gather information on overloaded methods; make sure there is only one marked DefaultOverload */ + found |= CheckOverloadAttributes(method, ref methodsHasAttributeMap, ref overloadsWithoutAttributeMap, classDeclaration, ref context); /* make sure no parameter has the name "__retval" */ found |= HasParameterNamedValue(ref context, method); } - foreach (var thing in overloadedMethods) + + foreach (var thing in overloadsWithoutAttributeMap) { - if (thing.Value == 0) - { - context.ReportDiagnostic(Diagnostic.Create(MethodOverload_NeedDefaultAttribute, classDeclaration.GetLocation(), - thing.Key, thing.Key, classDeclaration.Identifier)); - found |= true; - } + context.ReportDiagnostic(thing.Value); + found |= true; } - return false; + return found; } /* SimplifySyntaxTypeString From 0bf786a188e1ea47516998efd5c132e75b56e930 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 23 Nov 2020 17:13:41 -0800 Subject: [PATCH 19/41] moving to multiple test files --- .../TestDiagnostics/AsyncInterfaceTests.cs | 138 ++++++ .../JaggedArraySignatureTests.cs | 66 +++ .../TestDiagnostics/MethodOverloadTests.cs | 178 +++++++ .../MultidimensionalArraySignatureTests.cs | 108 +++++ .../NonZeroLowerBoundArraySignatureTests.cs | 153 +++++++ Authoring/TestDiagnostics/Scenarios.cs | 433 +----------------- .../StructField_StructInNamespaceTests.cs | 128 ++++++ .../StructField_StructTopLevel.cs | 111 +++++ .../WinRT.SourceGenerator/DiagnosticRules.cs | 3 +- 9 files changed, 888 insertions(+), 430 deletions(-) create mode 100644 Authoring/TestDiagnostics/AsyncInterfaceTests.cs create mode 100644 Authoring/TestDiagnostics/JaggedArraySignatureTests.cs create mode 100644 Authoring/TestDiagnostics/MethodOverloadTests.cs create mode 100644 Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs create mode 100644 Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs create mode 100644 Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs create mode 100644 Authoring/TestDiagnostics/StructField_StructTopLevel.cs diff --git a/Authoring/TestDiagnostics/AsyncInterfaceTests.cs b/Authoring/TestDiagnostics/AsyncInterfaceTests.cs new file mode 100644 index 000000000..a302ac8bf --- /dev/null +++ b/Authoring/TestDiagnostics/AsyncInterfaceTests.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestDiagnostics +{ + public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } + + public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } + + public sealed class OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperationWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } + + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } +} diff --git a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs new file mode 100644 index 000000000..19cbb6f81 --- /dev/null +++ b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestDiagnostics +{ + /* ** jagged array ** */ + + // public property in class + public sealed class JaggedArraySignature_2D_PublicProperty_Invalid + { + public int[][] Arr { get; set; } + } + + public sealed class JaggedArraySignature_3D_PublicProperty_Invalid + { + public int[][] Arr { get; set; } + } + + // positive test - private property in class + + public sealed class JaggedArraySignature_2D_PrivateProperty_Valid + { + private int[][] Arr { get; set; } + } + + public sealed class JaggedArraySignature_3D_PrivateProperty_Valid + { + private int[][] Arr { get; set; } + } + + internal sealed class JaggedArraySignature_2D_PublicProperty_PrivateClass_Valid + { + public int[][] Arr { get; set; } + } + + internal sealed class JaggedArraySignature_3D_PublicProperty_PrivateClass_Valid + { + public int[][] Arr { get; set; } + } + + // positive test - private property in class + + internal sealed class JaggedArraySignature_2D_PrivateProperty_PrivateClass_Valid + { + private int[][] Arr { get; set; } + } + + internal sealed class JaggedArraySignature_3D_PrivateProperty_PrivateClass_Valid + { + private int[][] Arr { get; set; } + } + + // public methods + + // positive test - private method + + // field in struct -- think this will get covered already, but we'll see + + // declared (public) in interface + + // positive test - private in interface + +} diff --git a/Authoring/TestDiagnostics/MethodOverloadTests.cs b/Authoring/TestDiagnostics/MethodOverloadTests.cs new file mode 100644 index 000000000..647baf3ee --- /dev/null +++ b/Authoring/TestDiagnostics/MethodOverloadTests.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestDiagnostics +{ + // valid method overload tests + public sealed class TwoOverloads_DiffParamCount_Valid + { + + // pretty sure diagnostic will get thrown for this right now BUT it shouldn't + + // the fix could be to append the method name (as a string) with its arity (as a string) and add that as the key to the map + // so the map isnt exactly the method name, but methodnameN where N is the arity of the methodname at that time + // think this fix would mean no logic has to change on the "have we seen this methodname before and did it have the attribute" + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n, int m) { return n; } + } + + public sealed class TwoOverloads_OneAttribute_OneInList_Valid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_OneAttribute_OneIrrelevatAttribute_Valid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_OneAttribute_TwoLists_Valid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + + public sealed class ThreeOverloads_OneAttribute_Valid + { + + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + public bool OverloadExample(bool b) { return b; } + } + + public sealed class ThreeOverloads_OneAttribute_2_Valid + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } + + public sealed class TwoOverloads_OneAttribute_3_Valid + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + // invalid method overload tests + public sealed class TwoOverloads_NoAttribute_Invalid + { + // hmm + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_OneInList_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_NoAttribute_OneIrrevAttr_Invalid + { + // hmm + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_BothInList_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_TwoLists_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_BothInSeparateList_Invalid + { + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class TwoOverloads_TwoAttribute_Invalid + { + + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } + + public sealed class ThreeOverloads_TwoAttributes_Invalid + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } +} diff --git a/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs b/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs new file mode 100644 index 000000000..bb46f8441 --- /dev/null +++ b/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestDiagnostics +{ + /* ** multidimensional array ** */ + + // public property in class + public sealed class MultidimensionalArraySignature_2D_Invalid + { + public int[,] Arr { get; set; } + } + + public sealed class MultidimensionalArraySignature_3D_Invalid + { + public int[,,] Arr { get; set; } + } + + // positive test - private property in class + public sealed class MultidimensionalArraySignature_2D_PrivateProperty_Valid + { + private int[,] Arr { get; set; } + } + + // we don't care about private or internal classes or methods + + public sealed class MultidimensionalArraySignature_3D_PrivateProperty_Valid + { + private int[,,] Arr { get; set; } + } + + internal class MultidimensionalArraySignature_2D_PrivateClass_Valid + { + public int[,] Arr { get; set; } + } + + internal sealed class MultidimensionalArraySignature_3D_PrivateClass_Valid + { + public int[,,] Arr { get; set; } + } + + // positive test - private property in class + internal sealed class MultidimensionalArraySignature_2D_PrivateProperty_PrivateClass_Valid + { + private int[,] Arr { get; set; } + } + + // we don't care about private or internal classes or methods + + internal sealed class MultidimensionalArraySignature_3D_PrivateProperty_PrivateClass_Valid + { + private int[,,] Arr { get; set; } + } + + // public methods + // return type + // parameters, 1 and 2 and 3 + public sealed class D2PublicPublic + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + + } + + /* + private sealed class D2PrivatePublic + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + + } + */ + + public sealed class D3PublicPublic + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + + } + public void Foo(int[,] arr); + public void Foo2(int[,,] arr); + // return type and parameters + + // positive test - private method + + // field in struct -- think this will get covered already, but we'll see + + // declared (public) in interface + + // positive test - private in interface + + +} diff --git a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs new file mode 100644 index 000000000..5f5394b48 --- /dev/null +++ b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestDiagnostics +{ + + /* ** non-zero lowerbound array ** */ + + // public property in class + public sealed class NonZeroLowerBound_PublicProperty1_Invalid + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } + + public sealed class NonZeroLowerBound_PublicProperty2_Invalid + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } + + public sealed class NonZeroLowerBound_PublicProperty1_Valid + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + + public sealed class NonZeroLowerBound_PublicProperty2_Valid + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + + // positive test - private property in class + public sealed class NonZeroLowerBound_PrivateProperty1_Valid + { + private int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } + + public sealed class NonZeroLowerBound_PrivateProperty2_Valid + { + private System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } + + public sealed class NonZeroLowerBound_PrivateProperty3_Valid + { + private int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + + public sealed class NonZeroLowerBound_PrivateProperty4_Valid + { + private System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + + internal sealed class NonZeroLowerBound_PublicProperty1_PrivateClass_Valid + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } + + internal sealed class NonZeroLowerBound_PublicProperty2_PrivateClass_Valid + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } + + internal sealed class NonZeroLowerBound_PublicProperty1_PrivateClass2_Valid + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + + internal sealed class NonZeroLowerBound_PublicProperty2_PrivateClass3_Valid + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + + // positive test - private property in class + internal sealed class NonZeroLowerBound_PrivateProperty1_PrivateClass_Valid + { + private int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } + + internal sealed class NonZeroLowerBound_PrivateProperty2_PrivateClass_Valid + { + private System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } + + internal sealed class NonZeroLowerBound_PrivateProperty3_PrivateClass_Valid + { + private int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + + internal sealed class NonZeroLowerBound_PrivateProperty4_PrivateClass_Valid + { + private System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + + // public methods + + // positive test - private method + + // field in struct -- think this will get covered already, but we'll see + + // declared (public) in interface + + // positive test - private in interface + +} diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 17929cd87..0dc3e724b 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -4,309 +4,24 @@ using System.Runtime.ExceptionServices; using Windows.Foundation; using Windows.Foundation.Numerics; +using Windows.Security.Cryptography.Core; using Windows.Web.Syndication; namespace TestDiagnostics { + + // ---------------------------------------------------------------------------- - // valid method overload tests - public sealed class TwoOverloads_DiffParamCount_Valid - { - - // pretty sure diagnostic will get thrown for this right now BUT it shouldn't - - // the fix could be to append the method name (as a string) with its arity (as a string) and add that as the key to the map - // so the map isnt exactly the method name, but methodnameN where N is the arity of the methodname at that time - // think this fix would mean no logic has to change on the "have we seen this methodname before and did it have the attribute" - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n, int m) { return n; } - } - - public sealed class TwoOverloads_OneAttribute_OneInList_Valid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_OneAttribute_OneIrrelevatAttribute_Valid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_OneAttribute_TwoLists_Valid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - - public sealed class ThreeOverloads_OneAttribute_Valid - { - - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - - public bool OverloadExample(bool b) { return b; } - } - - public sealed class ThreeOverloads_OneAttribute_2_Valid - { - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public bool OverloadExample(bool b) { return b; } - } - - public sealed class TwoOverloads_OneAttribute_3_Valid - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - // invalid method overload tests - public sealed class TwoOverloads_NoAttribute_Invalid - { - // hmm - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_OneInList_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_NoAttribute_OneIrrevAttr_Invalid - { - // hmm - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_BothInList_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_TwoLists_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_BothInSeparateList_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_Invalid - { - - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class ThreeOverloads_TwoAttributes_Invalid - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public bool OverloadExample(bool b) { return b; } - } - - - // end overload method tests - + // todo: fix the error message on operator -- says "operator" instead of "+" public sealed class ClassThatOverloadsOperator { - public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) // the rule needs update, it says "operator" instead of "+" + public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) { return thing; } } - /* - public sealed class SillyClass - { - public double Identity(double d) - { - return d; - } - } - - public struct StructWithClass_Invalid - { - public SillyClass classField; - } - - public struct StructWithDelegate_Invalid - { - public delegate int ADelegate(int x); - } - - public struct StructWithEvent_Invalid - { - public event EventHandler EventField; - } - - public struct StructWithConstructor_Invalid - { - int X; - StructWithConstructor_Invalid(int x) - { - X = x; - } - } - - public struct StructWithIndexer_Invalid - { - int[] arr; - int this[int i] => arr[i]; - } - - public struct StructWithMethods_Invalid - { - int foo(int x) - { - return x; - } - } - public struct StructWithConst_Invalid // really invalid ? - { - const int five = 5; - } - */ - /* - public enum BasicEnum - { - First = 0, - Second = 1 - } - - public struct Posn_Invalid - { - BasicEnum enumField; - - public int x { get; } - public int y { get; } - } - */ - - /* - public struct StructWithPrivateField_Invalid - { - const int ci = 5; - private int x; - } - */ - - /* - public struct StructWithAllValidFields - { - bool boolean; - char character; - decimal dec; - double dbl; - float flt; - int i; - uint nat; - long lng; - ulong ulng; - short sh; - ushort us; - string str; - } - */ - - /* - public struct StructWithObjectField_Invalid // is this really invalid? - { - object obj; - - } - public struct StructWithDynamicField_Invalid // is this really invalid? - { - dynamic dyn; - } - - public struct StructWithByteField_Invalid // is this really invalid? - { - byte b; - } - - public struct StructWithWinRTStructField - { - public Matrix3x2 matrix; - } - */ - - /* public sealed class ParameterNamedDunderRetVal { public int Identity(int __retval) @@ -314,9 +29,7 @@ public int Identity(int __retval) return __retval; } } - */ - /* public sealed class SameArityConstructors { private int num; @@ -337,141 +50,5 @@ public SameArityConstructors(string s) // Can test that multiple constructors are allowed (has been verified already, too) // as long as they have different arities by making one take none or 2 arguments } - */ - - /* Would be nice to not have to comment out scenarios... perhaps a file for each case to test? - public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } - */ - - /* - public class ActionWithProgress : IAsyncActionWithProgress - { - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } - */ - - /* - public sealed class OpWithProgress : IAsyncOperationWithProgress - { - AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperationWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } - public sealed class Op : IAsyncOperation - { - AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperation.GetResults() - { - throw new NotImplementedException(); - } - } - */ } diff --git a/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs b/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs new file mode 100644 index 000000000..385bf9d00 --- /dev/null +++ b/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestDiagnostics +{ + + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + } + + public struct StructWithClass_Invalid + { + public SillyClass classField; + } + + public struct StructWithDelegate_Invalid + { + public delegate int ADelegate(int x); + } + + public struct StructWithEvent_Invalid + { + public event EventHandler EventField; + } + + public struct StructWithConstructor_Invalid + { + int X; + StructWithConstructor_Invalid(int x) + { + X = x; + } + } + + public struct StructWithIndexer_Invalid + { + int[] arr; + int this[int i] => arr[i]; + } + + public struct StructWithMethods_Invalid + { + int foo(int x) + { + return x; + } + } + public struct StructWithConst_Invalid // really invalid ? + { + const int five = 5; + } + */ + + /* + public enum BasicEnum + { + First = 0, + Second = 1 + } + + public struct Posn_Invalid + { + BasicEnum enumField; + + public int x { get; } + public int y { get; } + } + */ + + /* + public struct StructWithPrivateField_Invalid + { + const int ci = 5; + private int x; + } + */ + + /* + public struct StructWithAllValidFields + { + bool boolean; + char character; + decimal dec; + double dbl; + float flt; + int i; + uint nat; + long lng; + ulong ulng; + short sh; + ushort us; + string str; + } + */ + + /* + public struct StructWithObjectField_Invalid // is this really invalid? + { + object obj; + + } + public struct StructWithDynamicField_Invalid // is this really invalid? + { + dynamic dyn; + } + + public struct StructWithByteField_Invalid // is this really invalid? + { + byte b; + } + + public struct StructWithWinRTStructField + { + public Matrix3x2 matrix; + } + */ + + class StructField_StructInClassTests + { + } +} diff --git a/Authoring/TestDiagnostics/StructField_StructTopLevel.cs b/Authoring/TestDiagnostics/StructField_StructTopLevel.cs new file mode 100644 index 000000000..085da4f5f --- /dev/null +++ b/Authoring/TestDiagnostics/StructField_StructTopLevel.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +public sealed class SillyClass +{ + public double Identity(double d) + { + return d; + } +} + +public struct StructWithClass_Invalid +{ + public SillyClass classField; +} + +public struct StructWithDelegate_Invalid +{ + public delegate int ADelegate(int x); +} + +public struct StructWithEvent_Invalid +{ + public event EventHandler EventField; +} + +public struct StructWithConstructor_Invalid +{ + int X; + StructWithConstructor_Invalid(int x) + { + X = x; + } +} + +public struct StructWithIndexer_Invalid +{ + int[] arr; + int this[int i] => arr[i]; +} + +public struct StructWithMethods_Invalid +{ + int foo(int x) + { + return x; + } +} +public struct StructWithConst_Invalid // really invalid ? +{ + const int five = 5; +} + +public enum BasicEnum +{ + First = 0, + Second = 1 +} + +public struct Posn_Invalid +{ + BasicEnum enumField; + public int x { get; } + public int y { get; } +} + +public struct StructWithPrivateField_Invalid +{ + const int ci = 5; + private int x; +} + +public struct StructWithAllValidFields +{ + bool boolean; + char character; + decimal dec; + double dbl; + float flt; + int i; + uint nat; + long lng; + ulong ulng; + short sh; + ushort us; + string str; +} + +public struct StructWithObjectField_Invalid // is this really invalid? +{ + object obj; + +} +public struct StructWithDynamicField_Invalid // is this really invalid? +{ + dynamic dyn; +} + +public struct StructWithByteField_Invalid // is this really invalid? +{ + byte b; +} + +public struct StructWithWinRTStructField +{ + public Matrix3x2 matrix; +} + diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index 51f38db55..6408b2089 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -147,7 +147,6 @@ public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext con return false; } - /* HasParameterNamedValue * the generated code for components uses the name "__retval" for the output variable, * we report diagnostic if a user uses this same identifier as a parameter to a method */ @@ -294,7 +293,7 @@ private string SimplifySyntaxTypeString(string syntaxType) /* StructHasFieldOfType * returns true iff there is a field of the given type in the given struct - * e.g., if T is PropertyDeclarationSyntax, then if a struct has a property, we report a diagnostic and return true */ + * e.g., if T is PropertyDeclarationSyntax, then if the struct has a property, we report a diagnostic and return true */ public bool StructHasFieldOfType(ref GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) { if (structDeclaration.DescendantNodes().OfType().Any()) From 4f337f85d911f31999657b3ccd827a678300bcad Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 24 Nov 2020 14:35:11 -0800 Subject: [PATCH 20/41] adding more array signature tests, fixing up other tests --- .../TestDiagnostics/AsyncInterfaceTests.cs | 15 +- .../JaggedArraySignatureTests.cs | 173 +++++++++++++++--- .../MultidimensionalArraySignatureTests.cs | 143 +++++++++++---- .../NonZeroLowerBoundArraySignatureTests.cs | 96 +++------- .../StructField_StructInNamespaceTests.cs | 16 +- .../StructField_StructTopLevel.cs | 111 ----------- 6 files changed, 276 insertions(+), 278 deletions(-) delete mode 100644 Authoring/TestDiagnostics/StructField_StructTopLevel.cs diff --git a/Authoring/TestDiagnostics/AsyncInterfaceTests.cs b/Authoring/TestDiagnostics/AsyncInterfaceTests.cs index a302ac8bf..5880c6339 100644 --- a/Authoring/TestDiagnostics/AsyncInterfaceTests.cs +++ b/Authoring/TestDiagnostics/AsyncInterfaceTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Windows.Foundation; namespace TestDiagnostics { @@ -40,20 +41,6 @@ public void GetResults() throw new NotImplementedException(); } - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } } public class ActionWithProgress : IAsyncActionWithProgress diff --git a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs index 19cbb6f81..431564621 100644 --- a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs @@ -9,58 +9,175 @@ namespace TestDiagnostics /* ** jagged array ** */ // public property in class - public sealed class JaggedArraySignature_2D_PublicProperty_Invalid + public sealed class JaggedArray_Properties_Invalid { - public int[][] Arr { get; set; } + private int[][] Arr { get; set; } + public int[][] ArrP { get; set; } + public int[][][] Arr3 { get; set; } + private int[][][] Arr3P { get; set; } } - public sealed class JaggedArraySignature_3D_PublicProperty_Invalid + internal sealed class JaggedArray_Properties_Valid { - public int[][] Arr { get; set; } + private int[][] Arr { get; set; } + public int[][] ArrP { get; set; } + public int[][][] Arr3 { get; set; } + private int[][][] Arr3P { get; set; } } - // positive test - private property in class - public sealed class JaggedArraySignature_2D_PrivateProperty_Valid + // tests return type and paramteter cases for 2-dimensional arrays + // we expect diagnostics to be raised since the methods are public + public sealed class J2PublicPublic_Invalid { - private int[][] Arr { get; set; } + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } } - public sealed class JaggedArraySignature_3D_PrivateProperty_Valid + internal sealed class J2InternalPublic_Valid { - private int[][] Arr { get; set; } + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } + } - internal sealed class JaggedArraySignature_2D_PublicProperty_PrivateClass_Valid + // tests return type and paramteter cases for 3-dimensional arrays + // we expect diagnostics to be raised since the methods are public + public sealed class J3PublicPublic_Invalid { - public int[][] Arr { get; set; } + public int[][][] J3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } - internal sealed class JaggedArraySignature_3D_PublicProperty_PrivateClass_Valid + internal sealed class J3InternalPublic_Valid { - public int[][] Arr { get; set; } - } + public int[][][] J3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - // positive test - private property in class + } - internal sealed class JaggedArraySignature_2D_PrivateProperty_PrivateClass_Valid + // tests return type and paramteter cases for 3-dimensional arrays + // we expect normal compilation since the methods are private + public sealed class J3PublicPrivate_Invalid { - private int[][] Arr { get; set; } - } + private int[][][] D3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + private int[][][] D3_ReturnAndInput1(int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - internal sealed class JaggedArraySignature_3D_PrivateProperty_PrivateClass_Valid + } + + public interface J2MemberOfInterface_Invalid { - private int[][] Arr { get; set; } + public int[][] J2_ReturnOnly(); + public int[][] J2_ReturnAndInput1(int[,] arr); + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); } - // public methods - - // positive test - private method - - // field in struct -- think this will get covered already, but we'll see - - // declared (public) in interface + public interface J2MemberOfInterface_Valid + { + private int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + private int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + private int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + private bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + private bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + private int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - // positive test - private in interface + } + public interface J3MemberOfInterface_Invalid + { + public int[][][] J3_ReturnOnly(); + public int[][][] J3_ReturnAndInput1(int[][][] arr); + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + + public interface J3MemberOfInterface_Valid + { + private int[][][] J3_ReturnOnly() { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + private int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + private int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + private int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + private bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + private bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } } + diff --git a/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs b/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs index bb46f8441..1f202ffae 100644 --- a/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs @@ -8,56 +8,39 @@ namespace TestDiagnostics { /* ** multidimensional array ** */ - // public property in class + /* + * Properties in Class + */ public sealed class MultidimensionalArraySignature_2D_Invalid { public int[,] Arr { get; set; } + private int[,] PrivArr { get; set; } + } public sealed class MultidimensionalArraySignature_3D_Invalid { public int[,,] Arr { get; set; } + private int[,,] PrivArr { get; set; } } - // positive test - private property in class - public sealed class MultidimensionalArraySignature_2D_PrivateProperty_Valid - { - private int[,] Arr { get; set; } - } - - // we don't care about private or internal classes or methods - - public sealed class MultidimensionalArraySignature_3D_PrivateProperty_Valid - { - private int[,,] Arr { get; set; } - } + // we don't care about private or internal methods or classes internal class MultidimensionalArraySignature_2D_PrivateClass_Valid { public int[,] Arr { get; set; } + private int[,] PrivArr { get; set; } } internal sealed class MultidimensionalArraySignature_3D_PrivateClass_Valid { public int[,,] Arr { get; set; } + private int[,,] PrivArr { get; set; } } - // positive test - private property in class - internal sealed class MultidimensionalArraySignature_2D_PrivateProperty_PrivateClass_Valid - { - private int[,] Arr { get; set; } - } - - // we don't care about private or internal classes or methods - internal sealed class MultidimensionalArraySignature_3D_PrivateProperty_PrivateClass_Valid - { - private int[,,] Arr { get; set; } - } - - // public methods - // return type - // parameters, 1 and 2 and 3 + // tests return type and paramteter cases for 2-dimensional arrays + // we expect diagnostics to be raised since the methods are public public sealed class D2PublicPublic { public int[,] D2_ReturnOnly() { return new int[4, 2]; } @@ -69,8 +52,7 @@ public sealed class D2PublicPublic } - /* - private sealed class D2PrivatePublic + internal sealed class D2InternalPublic { public int[,] D2_ReturnOnly() { return new int[4, 2]; } public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } @@ -80,8 +62,9 @@ private sealed class D2PrivatePublic public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } } - */ + // tests return type and paramteter cases for 3-dimensional arrays + // we expect diagnostics to be raised since the methods are public public sealed class D3PublicPublic { public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } @@ -92,17 +75,103 @@ public sealed class D3PublicPublic public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } } - public void Foo(int[,] arr); - public void Foo2(int[,,] arr); - // return type and parameters - // positive test - private method + internal sealed class D3InternalPublic + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + + } + + // tests return type and paramteter cases for 3-dimensional arrays + // we expect normal compilation since the methods are private + public sealed class D3PublicPrivate + { + private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + private int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + private int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + private bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + + } // field in struct -- think this will get covered already, but we'll see + // yeah you can't even have methods in fields in Windows Runtime + public struct D2FieldInStruct + { + public int[,,] D3Method(bool b) { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } + + /* + * negative test - public methods as members of an interface + */ + + public interface D2MemberOfInterface_N + { + public int[,] D2_ReturnOnly(); + public int[,] D2_ReturnAndInput1(int[,] arr); + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + } - // declared (public) in interface + public interface D2MemberOfInterface_P + { + private int[,] D2_ReturnOnly() { return new int[4, 2]; } + private int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + private int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + private bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + private bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + private int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - // positive test - private in interface + } + public interface D3MemberOfInterface_N + { + public int[,,] D3_ReturnOnly(); + public int[,,] D3_ReturnAndInput1(int[,,] arr); + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + + public interface D3MemberOfInterface_P + { + private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + private int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + private int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + private bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +} // End TestDiagnostics namespace + + +// maybe we need all the interface tests at the top level ? +public interface TopLevel_PrivateD3MemberOfInterface + { + public int[,,] D3_ReturnOnly(); + public int[,,] D3_ReturnAndInput1(int[,,] arr); + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + +public interface TopLevel_D2MemberOfInterface_P +{ + private int[,] D2_ReturnOnly() { return new int[4, 2]; } + private int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + private int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + private bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + private bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + private int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } } diff --git a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs index 5f5394b48..2cdc01579 100644 --- a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs @@ -10,144 +10,92 @@ namespace TestDiagnostics /* ** non-zero lowerbound array ** */ // public property in class - public sealed class NonZeroLowerBound_PublicProperty1_Invalid + public sealed class NonZeroLowerBound_PublicProperty_Invalid { public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } - public sealed class NonZeroLowerBound_PublicProperty2_Invalid - { - public System.Array Arr + public System.Array Arr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } - public sealed class NonZeroLowerBound_PublicProperty1_Valid - { - public int[] Arr + public int[] Arr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } - - public sealed class NonZeroLowerBound_PublicProperty2_Valid - { - public System.Array Arr + public System.Array Arr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } + } - // positive test - private property in class - public sealed class NonZeroLowerBound_PrivateProperty1_Valid + public sealed class NonZeroLowerBound_PrivateProperty_Valid { - private int[] Arr + private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } - - public sealed class NonZeroLowerBound_PrivateProperty2_Valid - { - private System.Array Arr + private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } - - public sealed class NonZeroLowerBound_PrivateProperty3_Valid - { - private int[] Arr + private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } - - public sealed class NonZeroLowerBound_PrivateProperty4_Valid - { - private System.Array Arr + private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } } - internal sealed class NonZeroLowerBound_PublicProperty1_PrivateClass_Valid + internal sealed class NonZeroLowerBound_PrivateClass_Valid { public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } - internal sealed class NonZeroLowerBound_PublicProperty2_PrivateClass_Valid - { - public System.Array Arr + public System.Array Arr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } - internal sealed class NonZeroLowerBound_PublicProperty1_PrivateClass2_Valid - { - public int[] Arr + public int[] Arr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } - - internal sealed class NonZeroLowerBound_PublicProperty2_PrivateClass3_Valid - { - public System.Array Arr + public System.Array Arr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } - // positive test - private property in class - internal sealed class NonZeroLowerBound_PrivateProperty1_PrivateClass_Valid - { - private int[] Arr + private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } - internal sealed class NonZeroLowerBound_PrivateProperty2_PrivateClass_Valid - { - private System.Array Arr + private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } - internal sealed class NonZeroLowerBound_PrivateProperty3_PrivateClass_Valid - { - private int[] Arr + private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } - internal sealed class NonZeroLowerBound_PrivateProperty4_PrivateClass_Valid - { - private System.Array Arr + private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } } - // public methods - - // positive test - private method - - // field in struct -- think this will get covered already, but we'll see - - // declared (public) in interface - - // positive test - private in interface - + public interface InterfaceWithNonZeroLowerBound + { + System.Array Id(System.Array arr); + } } diff --git a/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs b/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs index 385bf9d00..de617cbc5 100644 --- a/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs +++ b/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs @@ -1,4 +1,5 @@ -using System; +using ABI.System.Numerics; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -56,9 +57,7 @@ public struct StructWithConst_Invalid // really invalid ? { const int five = 5; } - */ - /* public enum BasicEnum { First = 0, @@ -72,17 +71,13 @@ public struct Posn_Invalid public int x { get; } public int y { get; } } - */ - /* public struct StructWithPrivateField_Invalid { const int ci = 5; private int x; } - */ - /* public struct StructWithAllValidFields { bool boolean; @@ -98,9 +93,7 @@ public struct StructWithAllValidFields ushort us; string str; } - */ - /* public struct StructWithObjectField_Invalid // is this really invalid? { object obj; @@ -120,9 +113,4 @@ public struct StructWithWinRTStructField { public Matrix3x2 matrix; } - */ - - class StructField_StructInClassTests - { - } } diff --git a/Authoring/TestDiagnostics/StructField_StructTopLevel.cs b/Authoring/TestDiagnostics/StructField_StructTopLevel.cs deleted file mode 100644 index 085da4f5f..000000000 --- a/Authoring/TestDiagnostics/StructField_StructTopLevel.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -public sealed class SillyClass -{ - public double Identity(double d) - { - return d; - } -} - -public struct StructWithClass_Invalid -{ - public SillyClass classField; -} - -public struct StructWithDelegate_Invalid -{ - public delegate int ADelegate(int x); -} - -public struct StructWithEvent_Invalid -{ - public event EventHandler EventField; -} - -public struct StructWithConstructor_Invalid -{ - int X; - StructWithConstructor_Invalid(int x) - { - X = x; - } -} - -public struct StructWithIndexer_Invalid -{ - int[] arr; - int this[int i] => arr[i]; -} - -public struct StructWithMethods_Invalid -{ - int foo(int x) - { - return x; - } -} -public struct StructWithConst_Invalid // really invalid ? -{ - const int five = 5; -} - -public enum BasicEnum -{ - First = 0, - Second = 1 -} - -public struct Posn_Invalid -{ - BasicEnum enumField; - public int x { get; } - public int y { get; } -} - -public struct StructWithPrivateField_Invalid -{ - const int ci = 5; - private int x; -} - -public struct StructWithAllValidFields -{ - bool boolean; - char character; - decimal dec; - double dbl; - float flt; - int i; - uint nat; - long lng; - ulong ulng; - short sh; - ushort us; - string str; -} - -public struct StructWithObjectField_Invalid // is this really invalid? -{ - object obj; - -} -public struct StructWithDynamicField_Invalid // is this really invalid? -{ - dynamic dyn; -} - -public struct StructWithByteField_Invalid // is this really invalid? -{ - byte b; -} - -public struct StructWithWinRTStructField -{ - public Matrix3x2 matrix; -} - From 834d96b78d8d6de2c773133ffb8d181fa34e5051 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Wed, 25 Nov 2020 14:47:23 -0800 Subject: [PATCH 21/41] update tests for array method signature; add diagnostics for return types --- .../JaggedArraySignatureTests.cs | 150 +++++++-------- .../MultidimensionalArraySignatureTests.cs | 180 ++++++++---------- .../NonZeroLowerBoundArraySignatureTests.cs | 113 ++++++++++- .../WinRT.SourceGenerator/DiagnosticRules.cs | 74 +++++++ Authoring/WinRT.SourceGenerator/Generator.cs | 7 +- 5 files changed, 341 insertions(+), 183 deletions(-) diff --git a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs index 431564621..4d1295dd1 100644 --- a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs @@ -7,43 +7,18 @@ namespace TestDiagnostics { /* ** jagged array ** */ - - // public property in class - public sealed class JaggedArray_Properties_Invalid - { - private int[][] Arr { get; set; } - public int[][] ArrP { get; set; } - public int[][][] Arr3 { get; set; } - private int[][][] Arr3P { get; set; } - } - + + /* + * Valid tests + */ internal sealed class JaggedArray_Properties_Valid { private int[][] Arr { get; set; } - public int[][] ArrP { get; set; } - public int[][][] Arr3 { get; set; } + public int[][] ArrP { get; set; } // this got dinged + public int[][][] Arr3 { get; set; } // this got dinged private int[][][] Arr3P { get; set; } } - - // tests return type and paramteter cases for 2-dimensional arrays - // we expect diagnostics to be raised since the methods are public - public sealed class J2PublicPublic_Invalid - { - public int[][] J2_ReturnOnly() - { - int[][] arr = new int[2][]; - arr[0] = new int[1] { 1 }; - arr[1] = new int[1] { 2 }; - return arr; - } - public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - } - internal sealed class J2InternalPublic_Valid { public int[][] J2_ReturnOnly() @@ -58,12 +33,8 @@ public int[][] J2_ReturnOnly() public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - } - - // tests return type and paramteter cases for 3-dimensional arrays - // we expect diagnostics to be raised since the methods are public - public sealed class J3PublicPublic_Invalid + internal sealed class J3InternalPublic_Valid { public int[][][] J3_ReturnOnly() { @@ -80,10 +51,47 @@ public int[][][] J3_ReturnOnly() public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } + public interface JaggedArrayTests_ValidInterface_NoJaggedArray + { + int[] foo(); + bool bar(int[] arr); } - internal sealed class J3InternalPublic_Valid + /* + * Invalid tests + */ + // public property in class + public sealed class JaggedArray_Properties_Invalid + { + private int[][] Arr { get; set; } // this didn't + public int[][] ArrP { get; set; } // this got dinged + public int[][][] Arr3 { get; set; } // this got dinged + private int[][][] Arr3P { get; set; } + } + + // tests return type and paramteter cases for 2-dimensional arrays + // we expect diagnostics to be raised since the methods are public + public sealed class J2PublicPublic_Invalid + { + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } + } + + // tests return type and paramteter cases for 3-dimensional arrays + // we expect diagnostics to be raised since the methods are public + public sealed class J3PublicPublic_Invalid { public int[][][] J3_ReturnOnly() { @@ -100,9 +108,8 @@ public int[][][] J3_ReturnOnly() public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } - + // tests return type and paramteter cases for 3-dimensional arrays // we expect normal compilation since the methods are private public sealed class J3PublicPrivate_Invalid @@ -122,9 +129,8 @@ private int[][][] D3_ReturnOnly() private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } - + public interface J2MemberOfInterface_Invalid { public int[][] J2_ReturnOnly(); @@ -135,49 +141,37 @@ public interface J2MemberOfInterface_Invalid public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); } - public interface J2MemberOfInterface_Valid - { - private int[][] J2_ReturnOnly() - { - int[][] arr = new int[2][]; - arr[0] = new int[1] { 1 }; - arr[1] = new int[1] { 2 }; - return arr; - } - private int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } - private int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } - private bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } - private bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } - private int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - - } - public interface J3MemberOfInterface_Invalid { - public int[][][] J3_ReturnOnly(); - public int[][][] J3_ReturnAndInput1(int[][][] arr); + public int[][][] J3_ReturnOnly(); + public int[][][] J3_ReturnAndInput1(int[][][] arr); public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); } - - public interface J3MemberOfInterface_Valid - { - private int[][][] J3_ReturnOnly() { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; + namespace SubNamespace + { + public interface SubNamespaceInterface_J2Methods_Invalid + { + public int[][] J2_ReturnOnly(); + public int[][] J2_ReturnAndInput1(int[,] arr); + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); } - private int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } - private int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - private int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - private bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - private bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } -} + + public interface SubNamespaceInterface_J3Methods_Invalid + { + public int[][][] J3_ReturnOnly(); + public int[][][] J3_ReturnAndInput1(int[][][] arr); + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + } // end SubNamespace +} diff --git a/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs b/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs index 1f202ffae..38d6ad39e 100644 --- a/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs @@ -6,42 +6,26 @@ namespace TestDiagnostics { - /* ** multidimensional array ** */ - - /* - * Properties in Class + /* + * Valid tests include `internal` classes and `private` properties + * and public methods in `ineternal` classes ? */ - public sealed class MultidimensionalArraySignature_2D_Invalid - { - public int[,] Arr { get; set; } - private int[,] PrivArr { get; set; } - - } - - public sealed class MultidimensionalArraySignature_3D_Invalid - { - public int[,,] Arr { get; set; } - private int[,,] PrivArr { get; set; } - } - - // we don't care about private or internal methods or classes - internal class MultidimensionalArraySignature_2D_PrivateClass_Valid { - public int[,] Arr { get; set; } - private int[,] PrivArr { get; set; } + public int[,] Arr_2d { get; set; } + public int[,,] Arr_3d { get; set; } + private int[,] PrivArr_2d { get; set; } + private int[,,] PrivArr_3d { get; set; } } - internal sealed class MultidimensionalArraySignature_3D_PrivateClass_Valid + public sealed class MultidimensionalArraySignature_3D_Valid { - public int[,,] Arr { get; set; } - private int[,,] PrivArr { get; set; } + private int[,] PrivArr_2d { get; set; } + private int[,,] PrivArr_3d { get; set; } } - - // tests return type and paramteter cases for 2-dimensional arrays - // we expect diagnostics to be raised since the methods are public - public sealed class D2PublicPublic + // methods ?? + internal sealed class D2InternalPublic_Valid { public int[,] D2_ReturnOnly() { return new int[4, 2]; } public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } @@ -52,31 +36,7 @@ public sealed class D2PublicPublic } - internal sealed class D2InternalPublic - { - public int[,] D2_ReturnOnly() { return new int[4, 2]; } - public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - - } - - // tests return type and paramteter cases for 3-dimensional arrays - // we expect diagnostics to be raised since the methods are public - public sealed class D3PublicPublic - { - public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - - } - - internal sealed class D3InternalPublic + internal sealed class D3InternalPublic_Valid { public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } @@ -89,7 +49,7 @@ internal sealed class D3InternalPublic // tests return type and paramteter cases for 3-dimensional arrays // we expect normal compilation since the methods are private - public sealed class D3PublicPrivate + public sealed class MultiDimPublicPrivate_Valid { private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } @@ -100,6 +60,47 @@ public sealed class D3PublicPrivate } + public interface MultiDimArrayTests_ValidInterface_NoMultiDim + { + int[] foo(); + bool bar(int[] arr); + } + + /* + * Invalid tests include public properties in public classes, public interface methods, + */ + public sealed class MultidimensionalArraySignature_2D_Invalid + { + public int[,] Arr_2d { get; set; } + public int[,,] Arr_3d { get; set; } + private int[,] PrivArr_2d { get; set; } /* below should pass through undetected (private property) */ + } + + // tests return type and paramteter cases for 2-dimensional arrays + // we expect diagnostics to be raised since the methods are public + public sealed class D2PublicPublic_Invalid + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + + } + + // do methods count?? I think so... + public sealed class D3PublicPublic_Invalid + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + + } + // field in struct -- think this will get covered already, but we'll see // yeah you can't even have methods in fields in Windows Runtime public struct D2FieldInStruct @@ -107,11 +108,7 @@ public struct D2FieldInStruct public int[,,] D3Method(bool b) { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } } - /* - * negative test - public methods as members of an interface - */ - - public interface D2MemberOfInterface_N + public interface D2MemberOfInterface_Invalid { public int[,] D2_ReturnOnly(); public int[,] D2_ReturnAndInput1(int[,] arr); @@ -121,18 +118,7 @@ public interface D2MemberOfInterface_N public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); } - public interface D2MemberOfInterface_P - { - private int[,] D2_ReturnOnly() { return new int[4, 2]; } - private int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - private int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - private bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - private bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - private int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - - } - - public interface D3MemberOfInterface_N + public interface D3MemberOfInterface_Invalid { public int[,,] D3_ReturnOnly(); public int[,,] D3_ReturnAndInput1(int[,,] arr); @@ -141,37 +127,27 @@ public interface D3MemberOfInterface_N public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); } - - public interface D3MemberOfInterface_P - { - private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - private int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - private int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - private bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } -} // End TestDiagnostics namespace - -// maybe we need all the interface tests at the top level ? -public interface TopLevel_PrivateD3MemberOfInterface + namespace SubNamespace { - public int[,,] D3_ReturnOnly(); - public int[,,] D3_ReturnAndInput1(int[,,] arr); - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + public interface SubNamespacInterface_D2Methods_Invalid + { + public int[,] D2_ReturnOnly(); + public int[,] D2_ReturnAndInput1(int[,] arr); + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + } + + public interface SubNamespaceInterface_D3Methods_Invalid + { + public int[,,] D3_ReturnOnly(); + public int[,,] D3_ReturnAndInput1(int[,,] arr); + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } } - -public interface TopLevel_D2MemberOfInterface_P -{ - private int[,] D2_ReturnOnly() { return new int[4, 2]; } - private int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - private int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - private bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - private bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - private int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - -} +} // End TestDiagnostics namespace diff --git a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs index 2cdc01579..155b4551d 100644 --- a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs @@ -26,6 +26,7 @@ public int[] Arr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + public System.Array Arr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } @@ -94,8 +95,116 @@ private System.Array PrivArr4 } } - public interface InterfaceWithNonZeroLowerBound + public interface InterfaceWithNonZeroLowerBound_Invalid + { + System.Array Id(System.Array arr); + void Method2(System.Array arr); + System.Array Method3(); + } + + internal interface InterfaceWithNonZeroLowerBound_Valid { System.Array Id(System.Array arr); + void Method2(System.Array arr); + System.Array Method3(); } -} + + /* + * Valid tests include `internal` classes and `private` properties + * and public methods in `ineternal` classes ? + */ + internal class NZLBArraySignature_2D_PrivateClass_Valid + { + public System.Array Arr_2d { get; set; } + public System.Array Arr_3d { get; set; } + private System.Array PrivArr_2d { get; set; } + private System.Array PrivArr_3d { get; set; } + } + public sealed class NZLBArraySignature_3D_Valid + { + private System.Array PrivArr_2d { get; set; } + + private Array PrivArr_3d { get; set; } + } + // methods ?? + internal sealed class NZLBInternalPublic_Valid + { + public System.Array NZLB_ReturnOnly() { return new int[4, 2]; } + public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } + public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } + + internal sealed class D3InternalPublic_Valid + { + public System.Array NZLB_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } + public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + } + + // tests return type and paramteter cases for 3-dimensional arrays + // we expect normal compilation since the methods are private + public sealed class NZLBPublicPrivate_Valid + { + private System.Array NZLB_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + private System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } + private System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + private System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + private bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + private bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + } + + public interface NZLB_ValidInterface_NoNZLB + { + int[] foo(); + bool bar(int[] arr); + } + /* + * Invalid tests include public properties in public classes, public interface methods, + */ + public sealed class NZLBArraySignature_2D_Invalid + { + public System.Array Arr_2d { get; set; } + public System.Array Arr_3d { get; set; } + private System.Array PrivArr_2d { get; set; } /* below should pass through undetected (private property) */ + } + // tests return type and paramteter cases for 2-dimensional arrays + // we expect diagnostics to be raised since the methods are public + public sealed class NZLBPublicPublic_Invalid + { + public System.Array NZLB_ReturnOnly() { return new int[4, 2]; } + public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } + public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } + + public interface NZLBMemberOfInterface_Invalid + { + public System.Array NZLB_ReturnOnly(); + public System.Array NZLB_ReturnAndInput1(System.Array arr); + public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr); + public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr); + public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b); + public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b); + } + + namespace SubNamespace + { + public interface SubNamespacInterface_NZLBMethods_Invalid + { + public System.Array D2_ReturnOnly(); + public System.Array D2_ReturnAndInput1(System.Array arr); + public System.Array D2_ReturnAndInput2of2(bool a, System.Array arr); + public System.Array D2_ReturnAndInput2of3(bool a, System.Array arr, bool b); + public bool D2_NotReturnAndInput2of2(bool a, System.Array arr); + public bool D2_NotReturnAndInput2of3(bool a, System.Array arr, bool b); + } + } +} diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index 6408b2089..99d6823dc 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -81,8 +81,65 @@ static DiagnosticDescriptor MakeRule(string id, string title, string messageForm //"The {0}-parameter overloads of {1}.{2} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); "In class {2}: The {0}-parameter overloads of {1} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + static DiagnosticDescriptor ArraySignature_JaggedArrayRule = MakeRule( + "WME10??", + "Array signature found with jagged array, which is not a valid WinRT type", // todo better msg + "In type {0}: the method {1} has signature that contains a jagged array; use a different type like List"); + + static DiagnosticDescriptor ArraySignature_MultiDimensionalArrayRule = MakeRule( + "WME10??", + "Array signature found with multi-dimensional array, which is not a valid WinRT type", // todo better msg + "In type {0}: the method {1} has signature that contains a multi-dimensional array; use a different type like List"); + + static DiagnosticDescriptor ArraySignature_SystemArrayRule = MakeRule( + "WME10??", + "Array signature found with System.Array instance, which is not a valid WinRT type", // todo better msg + "In type {0}: the method {1} has signature that contains a System.Array instance; use a different type like List"); + // "Method {0} has a multi-dimensional array of type {1} in its signature. Arrays in Windows Runtime must be one dimensional" + #endregion + private bool PropertyIsPublic(PropertyDeclarationSyntax p) + { + foreach (var thing in p.Modifiers) + { + if (thing.ValueText.Equals("public")) + { + return true; + } + } + return false; + } + + + public bool CheckArraySignature_ClassProperties(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + bool found = false; + var props = classDeclaration.DescendantNodes().OfType(); + foreach (var p in props.Where(PropertyIsPublic)) + { + var arrTypes = p.DescendantNodes().OfType(); + if (arrTypes.Any()) + { + foreach (var arrType in arrTypes) + { + var rankSpecs = arrType.DescendantNodes().OfType(); + if (rankSpecs.Count() > 1) + { + context.ReportDiagnostic(Diagnostic.Create(ArraySignature_JaggedArrayRule, p.GetLocation(), classDeclaration.Identifier, p.Identifier)); + found |= true; + } + else if (rankSpecs.Count() == 1 && rankSpecs.First().ToString().Contains(",")) + { + context.ReportDiagnostic(Diagnostic.Create(ArraySignature_MultiDimensionalArrayRule, p.GetLocation(), classDeclaration.Identifier, p.Identifier)); + found |= true; + } + } + } + } + return found; + } + /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ static string[] ProhibitedAsyncInterfaces = { "Windows.Foundation.IAsyncAction", @@ -236,6 +293,18 @@ private bool CheckOverloadAttributes(MethodDeclarationSyntax method, return found; } + + private bool IfAnyAndFirstEquals(ref GeneratorExecutionContext context, MethodDeclarationSyntax method, ClassDeclarationSyntax classDeclaration, string typeName) + { + var qualName = method.DescendantNodes().OfType(); + if (qualName.Any() && qualName.First().ToString().Equals(typeName)) + { + context.ReportDiagnostic(Diagnostic.Create(ArraySignature_SystemArrayRule, method.GetLocation(), classDeclaration.Identifier, method.Identifier)); + return true; + } + return false; + } + public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { bool found = false; @@ -256,6 +325,11 @@ public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDecla /* make sure no parameter has the name "__retval" */ found |= HasParameterNamedValue(ref context, method); + + /* see if method return type is System.Array or Array */ + found |= IfAnyAndFirstEquals(ref context, method, classDeclaration, "System.Array"); + found |= IfAnyAndFirstEquals(ref context, method, classDeclaration, "Array"); + // need to check all parameters too } foreach (var thing in overloadsWithoutAttributeMap) diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index a3fbec5df..3bb6c1a08 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -152,11 +152,16 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) // Used in the checking of structure fields List classNames = new List(); + // need an interfaces loop for the array signature rule + /* Check all classes */ foreach (ClassDeclarationSyntax classDeclaration in classes) - { + { classNames.Add(classDeclaration.Identifier.ToString()); + /* exports multidimensional array */ + found |= winrtRules.CheckArraySignature_ClassProperties(ref context, classDeclaration); + /* exposes an operator overload */ found |= winrtRules.OverloadsOperator(ref context, classDeclaration); From 35a7e018e7204c1f0b8655838cc390c36ed2ca15 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Wed, 25 Nov 2020 15:24:14 -0800 Subject: [PATCH 22/41] only looking at public methods, starting on param checking --- .../WinRT.SourceGenerator/DiagnosticRules.cs | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index 99d6823dc..62d4da317 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -111,6 +111,17 @@ private bool PropertyIsPublic(PropertyDeclarationSyntax p) return false; } + private bool MethodIsPublic(MethodDeclarationSyntax m) + { + foreach (var thing in m.Modifiers) + { + if (thing.ValueText.Equals("public")) + { + return true; + } + } + return false; + } public bool CheckArraySignature_ClassProperties(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { @@ -118,6 +129,9 @@ public bool CheckArraySignature_ClassProperties(ref GeneratorExecutionContext co var props = classDeclaration.DescendantNodes().OfType(); foreach (var p in props.Where(PropertyIsPublic)) { + + found |= IfAnyAndFirstEquals_Prop(ref context, p, classDeclaration, "System.Array"); + found |= IfAnyAndFirstEquals_Prop(ref context, p, classDeclaration, "Array"); var arrTypes = p.DescendantNodes().OfType(); if (arrTypes.Any()) { @@ -294,7 +308,7 @@ private bool CheckOverloadAttributes(MethodDeclarationSyntax method, } - private bool IfAnyAndFirstEquals(ref GeneratorExecutionContext context, MethodDeclarationSyntax method, ClassDeclarationSyntax classDeclaration, string typeName) + private bool IfAnyAndFirstEquals_Method(ref GeneratorExecutionContext context, MethodDeclarationSyntax method, ClassDeclarationSyntax classDeclaration, string typeName) { var qualName = method.DescendantNodes().OfType(); if (qualName.Any() && qualName.First().ToString().Equals(typeName)) @@ -304,6 +318,17 @@ private bool IfAnyAndFirstEquals(ref GeneratorExecutionContext context, Metho } return false; } + // would be nice to have some abstraction of the above/below method + private bool IfAnyAndFirstEquals_Prop(ref GeneratorExecutionContext context, PropertyDeclarationSyntax prop, ClassDeclarationSyntax classDeclaration, string typeName) + { + var qualName = prop.DescendantNodes().OfType(); + if (qualName.Any() && qualName.First().ToString().Equals(typeName)) + { + context.ReportDiagnostic(Diagnostic.Create(ArraySignature_SystemArrayRule, prop.GetLocation(), classDeclaration.Identifier, prop.Identifier)); + return true; + } + return false; + } public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { @@ -318,7 +343,7 @@ public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDecla * we check the elements of the map to raise diagnostics for those that didn't get attributed */ Dictionary overloadsWithoutAttributeMap = new Dictionary(); - foreach (MethodDeclarationSyntax method in methods) + foreach (MethodDeclarationSyntax method in methods.Where(MethodIsPublic)) { /* Gather information on overloaded methods; make sure there is only one marked DefaultOverload */ found |= CheckOverloadAttributes(method, ref methodsHasAttributeMap, ref overloadsWithoutAttributeMap, classDeclaration, ref context); @@ -326,9 +351,19 @@ public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDecla /* make sure no parameter has the name "__retval" */ found |= HasParameterNamedValue(ref context, method); + + var paramLists = method.DescendantNodes().OfType(); + if (paramLists.Any()) + { + var paramList = paramLists.First(); + foreach (var thing in paramList.Parameters) + { + // thing.Type.IsKind(ArrayTypeSyntax); + } + } /* see if method return type is System.Array or Array */ - found |= IfAnyAndFirstEquals(ref context, method, classDeclaration, "System.Array"); - found |= IfAnyAndFirstEquals(ref context, method, classDeclaration, "Array"); + found |= IfAnyAndFirstEquals_Method(ref context, method, classDeclaration, "System.Array"); + found |= IfAnyAndFirstEquals_Method(ref context, method, classDeclaration, "Array"); // need to check all parameters too } From 461ec534a004da742b6557c82d40bef0945216ff Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 30 Nov 2020 15:29:44 -0800 Subject: [PATCH 23/41] fix bug in sln file --- cswinrt.sln | 1 + 1 file changed, 1 insertion(+) diff --git a/cswinrt.sln b/cswinrt.sln index f618d531a..aa405b974 100644 --- a/cswinrt.sln +++ b/cswinrt.sln @@ -81,6 +81,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringConsumptionTest", "Authoring\AuthoringConsumptionTest\AuthoringConsumptionTest.vcxproj", "{0212A7C5-8D3F-443C-9EBC-1F28091FDF88}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestDiagnostics", "Authoring\TestDiagnostics\TestDiagnostics.csproj", "{9D94052B-137A-40EE-957C-8B9E355FA15C}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_component_base", "TestWinRT\test_component_base\test_component_base.vcxproj", "{13333A6F-6A4A-48CD-865C-0F65135EB018}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_component_derived", "TestWinRT\test_component_derived\test_component_derived.vcxproj", "{0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}" From 115b28b21f2cbf8edd0552b97d582bce21abda6d Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 30 Nov 2020 15:30:35 -0800 Subject: [PATCH 24/41] checking array types in signatures --- .../JaggedArraySignatureTests.cs | 4 +- .../NonZeroLowerBoundArraySignatureTests.cs | 16 +- Authoring/TestDiagnostics/Scenarios.cs | 1 - .../WinRT.SourceGenerator/DiagnosticRules.cs | 214 ++++++++++++------ Authoring/WinRT.SourceGenerator/Generator.cs | 34 ++- 5 files changed, 181 insertions(+), 88 deletions(-) diff --git a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs index 4d1295dd1..2c2ccfffd 100644 --- a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs @@ -65,8 +65,8 @@ public interface JaggedArrayTests_ValidInterface_NoJaggedArray // public property in class public sealed class JaggedArray_Properties_Invalid { - private int[][] Arr { get; set; } // this didn't - public int[][] ArrP { get; set; } // this got dinged + private int[][] ArrP { get; set; } // this didn't + public int[][] Arr { get; set; } // this got dinged public int[][][] Arr3 { get; set; } // this got dinged private int[][][] Arr3P { get; set; } } diff --git a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs index 155b4551d..9e344a61b 100644 --- a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs @@ -129,7 +129,7 @@ public sealed class NZLBArraySignature_3D_Valid // methods ?? internal sealed class NZLBInternalPublic_Valid { - public System.Array NZLB_ReturnOnly() { return new int[4, 2]; } + public System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } @@ -137,21 +137,11 @@ internal sealed class NZLBInternalPublic_Valid public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } } - internal sealed class D3InternalPublic_Valid - { - public System.Array NZLB_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } - public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - } - // tests return type and paramteter cases for 3-dimensional arrays // we expect normal compilation since the methods are private public sealed class NZLBPublicPrivate_Valid { - private System.Array NZLB_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + private System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } private System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } private System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } private System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } @@ -177,7 +167,7 @@ public sealed class NZLBArraySignature_2D_Invalid // we expect diagnostics to be raised since the methods are public public sealed class NZLBPublicPublic_Invalid { - public System.Array NZLB_ReturnOnly() { return new int[4, 2]; } + public System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index 0dc3e724b..d6d84ada1 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -12,7 +12,6 @@ namespace TestDiagnostics // ---------------------------------------------------------------------------- - // todo: fix the error message on operator -- says "operator" instead of "+" public sealed class ClassThatOverloadsOperator { public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index 62d4da317..7e982f463 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -123,37 +123,7 @@ private bool MethodIsPublic(MethodDeclarationSyntax m) return false; } - public bool CheckArraySignature_ClassProperties(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - bool found = false; - var props = classDeclaration.DescendantNodes().OfType(); - foreach (var p in props.Where(PropertyIsPublic)) - { - - found |= IfAnyAndFirstEquals_Prop(ref context, p, classDeclaration, "System.Array"); - found |= IfAnyAndFirstEquals_Prop(ref context, p, classDeclaration, "Array"); - var arrTypes = p.DescendantNodes().OfType(); - if (arrTypes.Any()) - { - foreach (var arrType in arrTypes) - { - var rankSpecs = arrType.DescendantNodes().OfType(); - if (rankSpecs.Count() > 1) - { - context.ReportDiagnostic(Diagnostic.Create(ArraySignature_JaggedArrayRule, p.GetLocation(), classDeclaration.Identifier, p.Identifier)); - found |= true; - } - else if (rankSpecs.Count() == 1 && rankSpecs.First().ToString().Contains(",")) - { - context.ReportDiagnostic(Diagnostic.Create(ArraySignature_MultiDimensionalArrayRule, p.GetLocation(), classDeclaration.Identifier, p.Identifier)); - found |= true; - } - } - } - } - return found; - } - + #region AsyncInterfaces /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ static string[] ProhibitedAsyncInterfaces = { "Windows.Foundation.IAsyncAction", @@ -192,6 +162,9 @@ public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INam return false; } + #endregion + + #region Misc /* HasMultipleConstructorsOfSameArity * keeps track of the arity of all constructors, and reports the diagnostic (and exits) as soon as a two constructors of the same arity are seen. */ public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) @@ -252,18 +225,18 @@ private bool MethodHasAttribute(string attrName, MethodDeclarationSyntax method) } /// - /// Returns true if multiple overloads of a method are found where more than one has been designated as the default overload + /// Keeps track of repeated declarations of a method (overloads) and raises diagnostics according to the rule that exactly one overload should be attributed the default /// /// The method to check attributes for /// Keeps track of the method (via name + arity) and whether it was declared with the DefaultOverload attribute /// Keeps track of the methods that are overloads but don't have the DefaultOverload attribute (yet) - /// The class the method lives in -- used for creating the diagnostic + /// The class the method lives in -- used for creating the diagnostic /// The SourceGenerator context the code lives in - /// + /// True iff multiple overloads of a method are found, where more than one has been designated as the default overload private bool CheckOverloadAttributes(MethodDeclarationSyntax method, ref Dictionary methodHasAttributeMap, ref Dictionary overloadsWithoutAttributeMap, - ClassDeclarationSyntax classDeclaration, + SyntaxToken classIdentifier, ref GeneratorExecutionContext context) { bool found = false; @@ -288,13 +261,13 @@ private bool CheckOverloadAttributes(MethodDeclarationSyntax method, { // raise the "can't have multiple default attributes" diagnostic context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), - methodArity, method.Identifier, classDeclaration.Identifier)); + methodArity, method.Identifier, classIdentifier)); found |= true; } else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) { // we could see this method later with the attribute, so hold onto the diagnostic for it until we know it doesn't have the attribute - Diagnostic diagnostic = Diagnostic.Create(MethodOverload_NeedDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classDeclaration.Identifier); + Diagnostic diagnostic = Diagnostic.Create(MethodOverload_NeedDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classIdentifier); overloadsWithoutAttributeMap[methodNameWithArity] = diagnostic; } } @@ -307,29 +280,149 @@ private bool CheckOverloadAttributes(MethodDeclarationSyntax method, return found; } + /// + /// Checks to see if the class declares any operators (overloading them) + /// + /// + /// + /// True iff an operator is overloaded by the given class + public bool OverloadsOperator(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + var operatorDeclarations = classDeclaration.DescendantNodes().OfType(); + if (operatorDeclarations.Any()) + { + var overloadedOperator = operatorDeclarations.First(); + context.ReportDiagnostic(Diagnostic.Create(OperatorOverloadedRule, overloadedOperator.GetLocation(), overloadedOperator.OperatorToken)); + return true; + } + return false; + } + + #endregion + + #region ArraySignatureChecking - private bool IfAnyAndFirstEquals_Method(ref GeneratorExecutionContext context, MethodDeclarationSyntax method, ClassDeclarationSyntax classDeclaration, string typeName) + /// + /// Looks at all the methods declared on the given interface and checks them for improper array types (System.Array instances, multidimensional, jagged) + /// + /// + /// + /// True iff any of the invalid array types are used in any of the method signatures on the given interface + public bool Interface_CheckArraySignature(ref GeneratorExecutionContext context, InterfaceDeclarationSyntax interfaceDeclaration) + { + bool found = false; + var methodDeclarations = interfaceDeclaration.DescendantNodes().OfType(); + foreach (var method in methodDeclarations) // interfaces don't have private methods, right? + { + found |= Method_CheckForSystemArrayType(ref context, method, interfaceDeclaration.Identifier, "System.Array"); + found |= Method_CheckForSystemArrayType(ref context, method, interfaceDeclaration.Identifier, "Array"); + found |= CheckForInvalidArrayType(method.DescendantNodes().OfType(), ref context, interfaceDeclaration.Identifier, method.Identifier, method.GetLocation()); + } + return found; + } + + /// + /// Looks at all the properties of the given class and checks them for improper array types (System.Array instances, multidimensional, jagged) + /// + /// + /// + /// True iff any of the invalid array types are used in any of the propertyy signatures in the given class + public bool Class_CheckArraySignature(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + bool found = false; + var props = classDeclaration.DescendantNodes().OfType(); + foreach (var prop in props.Where(PropertyIsPublic)) + { + found |= Property_CheckForSystemArrayType(ref context, prop, classDeclaration.Identifier, "System.Array"); + found |= Property_CheckForSystemArrayType(ref context, prop, classDeclaration.Identifier, "Array"); + found |= CheckForInvalidArrayType(prop.DescendantNodes().OfType(), ref context, classDeclaration.Identifier, prop.Identifier, prop.GetLocation()); + } + return found; + } + + /// + /// Look at all the array types and if any are of the form [][]+ or [,+] then raise the corresponding diagnostic and return true + /// + /// + /// + /// The type the array lives in + /// The code the array is a part of the signature for; e.g. property or method + /// + /// True iff any of the array types given are multidimensional or jagged + private bool CheckForInvalidArrayType(IEnumerable arrTypes, ref GeneratorExecutionContext context, SyntaxToken typeIdentifier, SyntaxToken fieldIdentifier, Location loc) + { + if (arrTypes.Any()) + { + foreach (var arrType in arrTypes) + { + var rankSpecs = arrType.DescendantNodes().OfType(); + if (rankSpecs.Count() > 1) + { + context.ReportDiagnostic(Diagnostic.Create(ArraySignature_JaggedArrayRule, loc, typeIdentifier, fieldIdentifier)); + return true; // could do or-eq on a `found` boolean instead of exiting as soon as we see invalid... + } + else if (rankSpecs.Count() == 1 && rankSpecs.First().ToString().Contains(",")) + { + context.ReportDiagnostic(Diagnostic.Create(ArraySignature_MultiDimensionalArrayRule, loc, typeIdentifier, fieldIdentifier)); + return true; + } + } + } + return false; + } + + /// + /// Checks method signatures with nodes of the generic type given for the given typename + /// + /// + /// The method is generic because we need to use this on fields that are of type QualifiedNameSyntax and IdentifierSyntax; e.g. the System.Array type and Array type + /// + /// Compilation unit + /// The method declaration + /// The type the method lives in + /// The string representation of the type we are looking for -- either "Array" or "System.Array" + /// True iff the return type of the given method matches the given type + private bool Method_CheckForSystemArrayType(ref GeneratorExecutionContext context, MethodDeclarationSyntax method, SyntaxToken classIdentifier, string typeName) { var qualName = method.DescendantNodes().OfType(); if (qualName.Any() && qualName.First().ToString().Equals(typeName)) { - context.ReportDiagnostic(Diagnostic.Create(ArraySignature_SystemArrayRule, method.GetLocation(), classDeclaration.Identifier, method.Identifier)); + context.ReportDiagnostic(Diagnostic.Create(ArraySignature_SystemArrayRule, method.GetLocation(), classIdentifier, method.Identifier)); return true; } return false; } - // would be nice to have some abstraction of the above/below method - private bool IfAnyAndFirstEquals_Prop(ref GeneratorExecutionContext context, PropertyDeclarationSyntax prop, ClassDeclarationSyntax classDeclaration, string typeName) + + /// + /// Checks property signatures with nodes of the generic type given for the given typename + /// + /// + /// The method is generic because we need to use this on fields that are of type QualifiedNameSyntax and IdentifierSyntax; e.g. the System.Array type and Array type + /// + /// Compilation unit + /// The property declaration + /// The type the property lives in + /// The string representation of the type we are looking for -- either "Array" or "System.Array" + /// True if the return type of the given property matches the given type + private bool Property_CheckForSystemArrayType(ref GeneratorExecutionContext context, PropertyDeclarationSyntax prop, SyntaxToken classIdentifier, string typeName) { var qualName = prop.DescendantNodes().OfType(); if (qualName.Any() && qualName.First().ToString().Equals(typeName)) { - context.ReportDiagnostic(Diagnostic.Create(ArraySignature_SystemArrayRule, prop.GetLocation(), classDeclaration.Identifier, prop.Identifier)); + context.ReportDiagnostic(Diagnostic.Create(ArraySignature_SystemArrayRule, prop.GetLocation(), classIdentifier, prop.Identifier)); return true; } return false; } + #endregion + + /// + /// Loops over each method declared in the given class and checks for various diagnostics + /// + /// + /// + /// True iff any of the diagnostics checked for are found. public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { bool found = false; @@ -346,27 +439,17 @@ public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDecla foreach (MethodDeclarationSyntax method in methods.Where(MethodIsPublic)) { /* Gather information on overloaded methods; make sure there is only one marked DefaultOverload */ - found |= CheckOverloadAttributes(method, ref methodsHasAttributeMap, ref overloadsWithoutAttributeMap, classDeclaration, ref context); + found |= CheckOverloadAttributes(method, ref methodsHasAttributeMap, ref overloadsWithoutAttributeMap, classDeclaration.Identifier, ref context); /* make sure no parameter has the name "__retval" */ found |= HasParameterNamedValue(ref context, method); - - var paramLists = method.DescendantNodes().OfType(); - if (paramLists.Any()) - { - var paramList = paramLists.First(); - foreach (var thing in paramList.Parameters) - { - // thing.Type.IsKind(ArrayTypeSyntax); - } - } - /* see if method return type is System.Array or Array */ - found |= IfAnyAndFirstEquals_Method(ref context, method, classDeclaration, "System.Array"); - found |= IfAnyAndFirstEquals_Method(ref context, method, classDeclaration, "Array"); - // need to check all parameters too + /* see if method signature contains the types System.Array or Array */ + found |= Method_CheckForSystemArrayType(ref context, method, classDeclaration.Identifier, "System.Array"); + found |= Method_CheckForSystemArrayType(ref context, method, classDeclaration.Identifier, "Array"); } + /* Finishes up the work started by `CheckOverloadAttributes` */ foreach (var thing in overloadsWithoutAttributeMap) { context.ReportDiagnostic(thing.Value); @@ -375,8 +458,10 @@ public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDecla return found; } + #region StructChecks + /* SimplifySyntaxTypeString - * returns the more common term for the given kind of syntax; used when creating a diagnostic for an invalid field in a struct */ + * returns the more common term for the given kind of syntax; used when creating a diagnostic for an invalid field in a struct */ private string SimplifySyntaxTypeString(string syntaxType) { switch (syntaxType) @@ -416,7 +501,6 @@ public bool StructHasFieldOfType(ref GeneratorExecutionContext context, Struc return false; } - /* StructHasInvalidFields * returns true if there is a field declared private, * or (inclusive) declared with a type that is a class or one of object, byte or dynamic */ @@ -451,16 +535,6 @@ public bool StructHasFieldOfInvalidType(ref GeneratorExecutionContext context, F return found; } - public bool OverloadsOperator(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - var operatorDeclarations = classDeclaration.DescendantNodes().OfType(); - if (operatorDeclarations.Any()) - { - var overloadedOperator = operatorDeclarations.First(); - context.ReportDiagnostic(Diagnostic.Create(OperatorOverloadedRule, overloadedOperator.GetLocation(), overloadedOperator.OperatorKeyword.Text)); - return true; - } - return false; - } + #endregion } } diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index 3bb6c1a08..34d76d618 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -137,6 +137,30 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } + private bool ClassIsPublic(ClassDeclarationSyntax m) + { + foreach (var thing in m.Modifiers) + { + if (thing.ValueText.Equals("public")) + { + return true; + } + } + return false; + } + + private bool InterfaceIsPublic(InterfaceDeclarationSyntax m) + { + foreach (var thing in m.Modifiers) + { + if (thing.ValueText.Equals("public")) + { + return true; + } + } + return false; + } + private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) { bool found = false; @@ -146,7 +170,8 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) var model = context.Compilation.GetSemanticModel(tree); var nodes = tree.GetRoot().DescendantNodes(); - var classes = nodes.OfType(); + var classes = nodes.OfType().Where(ClassIsPublic); + var interfaces = nodes.OfType().Where(InterfaceIsPublic); var structs = nodes.OfType(); // Used in the checking of structure fields @@ -160,7 +185,7 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) classNames.Add(classDeclaration.Identifier.ToString()); /* exports multidimensional array */ - found |= winrtRules.CheckArraySignature_ClassProperties(ref context, classDeclaration); + found |= winrtRules.Class_CheckArraySignature(ref context, classDeclaration); /* exposes an operator overload */ found |= winrtRules.OverloadsOperator(ref context, classDeclaration); @@ -176,6 +201,11 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) found |= winrtRules.ImplementsAsyncInterface(ref context, classSymbol, classDeclaration); } + foreach (InterfaceDeclarationSyntax interfaceDeclaration in interfaces) + { + found |= winrtRules.Interface_CheckArraySignature(ref context, interfaceDeclaration); + } + /* Check all structs */ foreach (StructDeclarationSyntax structDeclaration in structs) { From 94fda2cfe4056841b1b31e9507c8c38b7cd308bb Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 30 Nov 2020 17:31:50 -0800 Subject: [PATCH 25/41] raising all diagnostics for array signatures --- Authoring/TestDiagnostics/JaggedArraySignatureTests.cs | 2 +- Authoring/WinRT.SourceGenerator/DiagnosticRules.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs index 2c2ccfffd..48dfbc00e 100644 --- a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs @@ -112,7 +112,7 @@ public int[][][] J3_ReturnOnly() // tests return type and paramteter cases for 3-dimensional arrays // we expect normal compilation since the methods are private - public sealed class J3PublicPrivate_Invalid + public sealed class J3PublicPrivate_Valid { private int[][][] D3_ReturnOnly() { diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index 7e982f463..8c2db764f 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -447,6 +447,7 @@ public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDecla /* see if method signature contains the types System.Array or Array */ found |= Method_CheckForSystemArrayType(ref context, method, classDeclaration.Identifier, "System.Array"); found |= Method_CheckForSystemArrayType(ref context, method, classDeclaration.Identifier, "Array"); + found |= CheckForInvalidArrayType(method.DescendantNodes().OfType(), ref context, classDeclaration.Identifier, method.Identifier, method.GetLocation()); } /* Finishes up the work started by `CheckOverloadAttributes` */ From 89cdd830863e527939ba70ec54c0e1b8950d9514 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 30 Nov 2020 17:46:36 -0800 Subject: [PATCH 26/41] cleanup before PR --- Authoring/AuthoringSample/Program.cs | 1 - .../JaggedArraySignatureTests.cs | 55 ++++++++----------- .../TestDiagnostics/MethodOverloadTests.cs | 14 +---- .../NonZeroLowerBoundArraySignatureTests.cs | 8 +-- Authoring/TestDiagnostics/Scenarios.cs | 3 - 5 files changed, 27 insertions(+), 54 deletions(-) diff --git a/Authoring/AuthoringSample/Program.cs b/Authoring/AuthoringSample/Program.cs index aaa5af755..de46e0aac 100644 --- a/Authoring/AuthoringSample/Program.cs +++ b/Authoring/AuthoringSample/Program.cs @@ -6,7 +6,6 @@ namespace AuthoringSample { - public enum BasicEnum { First = -1, diff --git a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs index 48dfbc00e..35940d7b6 100644 --- a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs @@ -6,8 +6,6 @@ namespace TestDiagnostics { - /* ** jagged array ** */ - /* * Valid tests */ @@ -53,26 +51,42 @@ public int[][][] J3_ReturnOnly() public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } } - public interface JaggedArrayTests_ValidInterface_NoJaggedArray + public interface JaggedArrayTests_ValidInterface { int[] foo(); bool bar(int[] arr); } + public sealed class J3PublicPrivate_Valid + { + private int[][][] D3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + private int[][][] D3_ReturnAndInput1(int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } + /* * Invalid tests */ - // public property in class public sealed class JaggedArray_Properties_Invalid { - private int[][] ArrP { get; set; } // this didn't - public int[][] Arr { get; set; } // this got dinged - public int[][][] Arr3 { get; set; } // this got dinged + private int[][] ArrP { get; set; } + public int[][] Arr { get; set; } + public int[][][] Arr3 { get; set; } private int[][][] Arr3P { get; set; } } - // tests return type and paramteter cases for 2-dimensional arrays - // we expect diagnostics to be raised since the methods are public public sealed class J2PublicPublic_Invalid { public int[][] J2_ReturnOnly() @@ -89,8 +103,6 @@ public int[][] J2_ReturnOnly() public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } } - // tests return type and paramteter cases for 3-dimensional arrays - // we expect diagnostics to be raised since the methods are public public sealed class J3PublicPublic_Invalid { public int[][][] J3_ReturnOnly() @@ -110,27 +122,6 @@ public int[][][] J3_ReturnOnly() public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } } - // tests return type and paramteter cases for 3-dimensional arrays - // we expect normal compilation since the methods are private - public sealed class J3PublicPrivate_Valid - { - private int[][][] D3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - private int[][][] D3_ReturnAndInput1(int[][][] arr) { return arr; } - private int[][][] D3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } - public interface J2MemberOfInterface_Invalid { public int[][] J2_ReturnOnly(); diff --git a/Authoring/TestDiagnostics/MethodOverloadTests.cs b/Authoring/TestDiagnostics/MethodOverloadTests.cs index 647baf3ee..6e0013321 100644 --- a/Authoring/TestDiagnostics/MethodOverloadTests.cs +++ b/Authoring/TestDiagnostics/MethodOverloadTests.cs @@ -6,18 +6,10 @@ namespace TestDiagnostics { - // valid method overload tests public sealed class TwoOverloads_DiffParamCount_Valid { - - // pretty sure diagnostic will get thrown for this right now BUT it shouldn't - - // the fix could be to append the method name (as a string) with its arity (as a string) and add that as the key to the map - // so the map isnt exactly the method name, but methodnameN where N is the arity of the methodname at that time - // think this fix would mean no logic has to change on the "have we seen this methodname before and did it have the attribute" - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n, int m) { return n; } + public string OverloadExample(string s) { return s; } + public int OverloadExample(int n, int m) { return n; } } public sealed class TwoOverloads_OneAttribute_OneInList_Valid @@ -82,7 +74,6 @@ public sealed class TwoOverloads_OneAttribute_3_Valid // invalid method overload tests public sealed class TwoOverloads_NoAttribute_Invalid { - // hmm public string OverloadExample(string s) { return s; } public int OverloadExample(int n) { return n; } @@ -101,7 +92,6 @@ public sealed class TwoOverloads_TwoAttribute_OneInList_Invalid public sealed class TwoOverloads_NoAttribute_OneIrrevAttr_Invalid { - // hmm [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] public string OverloadExample(string s) { return s; } diff --git a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs index 9e344a61b..4185290f3 100644 --- a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs @@ -7,7 +7,7 @@ namespace TestDiagnostics { - /* ** non-zero lowerbound array ** */ + /* NZLB = non-zero lowerbound array */ // public property in class public sealed class NonZeroLowerBound_PublicProperty_Invalid @@ -109,10 +109,6 @@ internal interface InterfaceWithNonZeroLowerBound_Valid System.Array Method3(); } - /* - * Valid tests include `internal` classes and `private` properties - * and public methods in `ineternal` classes ? - */ internal class NZLBArraySignature_2D_PrivateClass_Valid { public System.Array Arr_2d { get; set; } @@ -149,7 +145,7 @@ public sealed class NZLBPublicPrivate_Valid private bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } } - public interface NZLB_ValidInterface_NoNZLB + public interface NZLB_ValidInterface { int[] foo(); bool bar(int[] arr); diff --git a/Authoring/TestDiagnostics/Scenarios.cs b/Authoring/TestDiagnostics/Scenarios.cs index d6d84ada1..de1da64e3 100644 --- a/Authoring/TestDiagnostics/Scenarios.cs +++ b/Authoring/TestDiagnostics/Scenarios.cs @@ -10,8 +10,6 @@ namespace TestDiagnostics { - // ---------------------------------------------------------------------------- - public sealed class ClassThatOverloadsOperator { public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) @@ -20,7 +18,6 @@ public sealed class ClassThatOverloadsOperator } } - public sealed class ParameterNamedDunderRetVal { public int Identity(int __retval) From 85d7262b7901993a872a7f42893c9c52f9ea3be3 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 30 Nov 2020 17:51:09 -0800 Subject: [PATCH 27/41] more cleanup --- .../JaggedArraySignatureTests.cs | 4 +-- .../MultidimensionalArraySignatureTests.cs | 13 -------- .../NonZeroLowerBoundArraySignatureTests.cs | 5 ++- .../WinRT.SourceGenerator/DiagnosticRules.cs | 25 ++++++++++++++ Authoring/WinRT.SourceGenerator/Generator.cs | 33 +++---------------- 5 files changed, 33 insertions(+), 47 deletions(-) diff --git a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs index 35940d7b6..278710361 100644 --- a/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs @@ -12,8 +12,8 @@ namespace TestDiagnostics internal sealed class JaggedArray_Properties_Valid { private int[][] Arr { get; set; } - public int[][] ArrP { get; set; } // this got dinged - public int[][][] Arr3 { get; set; } // this got dinged + public int[][] ArrP { get; set; } + public int[][][] Arr3 { get; set; } private int[][][] Arr3P { get; set; } } diff --git a/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs b/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs index 38d6ad39e..16ed2d99a 100644 --- a/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs @@ -6,10 +6,6 @@ namespace TestDiagnostics { - /* - * Valid tests include `internal` classes and `private` properties - * and public methods in `ineternal` classes ? - */ internal class MultidimensionalArraySignature_2D_PrivateClass_Valid { public int[,] Arr_2d { get; set; } @@ -24,7 +20,6 @@ public sealed class MultidimensionalArraySignature_3D_Valid private int[,,] PrivArr_3d { get; set; } } - // methods ?? internal sealed class D2InternalPublic_Valid { public int[,] D2_ReturnOnly() { return new int[4, 2]; } @@ -47,8 +42,6 @@ internal sealed class D3InternalPublic_Valid } - // tests return type and paramteter cases for 3-dimensional arrays - // we expect normal compilation since the methods are private public sealed class MultiDimPublicPrivate_Valid { private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } @@ -76,8 +69,6 @@ public sealed class MultidimensionalArraySignature_2D_Invalid private int[,] PrivArr_2d { get; set; } /* below should pass through undetected (private property) */ } - // tests return type and paramteter cases for 2-dimensional arrays - // we expect diagnostics to be raised since the methods are public public sealed class D2PublicPublic_Invalid { public int[,] D2_ReturnOnly() { return new int[4, 2]; } @@ -89,7 +80,6 @@ public sealed class D2PublicPublic_Invalid } - // do methods count?? I think so... public sealed class D3PublicPublic_Invalid { public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } @@ -98,11 +88,8 @@ public sealed class D3PublicPublic_Invalid public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } - // field in struct -- think this will get covered already, but we'll see - // yeah you can't even have methods in fields in Windows Runtime public struct D2FieldInStruct { public int[,,] D3Method(bool b) { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } diff --git a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs index 4185290f3..25c579fda 100644 --- a/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs +++ b/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs @@ -159,9 +159,8 @@ public sealed class NZLBArraySignature_2D_Invalid public System.Array Arr_3d { get; set; } private System.Array PrivArr_2d { get; set; } /* below should pass through undetected (private property) */ } - // tests return type and paramteter cases for 2-dimensional arrays - // we expect diagnostics to be raised since the methods are public - public sealed class NZLBPublicPublic_Invalid + + public sealed class NZLBPublicPublic_Invalid { public System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } diff --git a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index 8c2db764f..7c4896622 100644 --- a/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -123,6 +123,31 @@ private bool MethodIsPublic(MethodDeclarationSyntax m) return false; } + public bool ClassIsPublic(ClassDeclarationSyntax m) + { + foreach (var thing in m.Modifiers) + { + if (thing.ValueText.Equals("public")) + { + return true; + } + } + return false; + } + + public bool InterfaceIsPublic(InterfaceDeclarationSyntax m) + { + foreach (var thing in m.Modifiers) + { + if (thing.ValueText.Equals("public")) + { + return true; + } + } + return false; + } + + #region AsyncInterfaces /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ static string[] ProhibitedAsyncInterfaces = { diff --git a/Authoring/WinRT.SourceGenerator/Generator.cs b/Authoring/WinRT.SourceGenerator/Generator.cs index 34d76d618..4cc0fca6c 100644 --- a/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/Authoring/WinRT.SourceGenerator/Generator.cs @@ -120,7 +120,7 @@ private string GetWinmdOutputFile(GeneratorExecutionContext context) } private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) - { + { Logger.Log("Writing " + outputFile); var managedPeBuilder = new ManagedPEBuilder( new PEHeaderBuilder( @@ -137,30 +137,7 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } - private bool ClassIsPublic(ClassDeclarationSyntax m) - { - foreach (var thing in m.Modifiers) - { - if (thing.ValueText.Equals("public")) - { - return true; - } - } - return false; - } - - private bool InterfaceIsPublic(InterfaceDeclarationSyntax m) - { - foreach (var thing in m.Modifiers) - { - if (thing.ValueText.Equals("public")) - { - return true; - } - } - return false; - } - + private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) { bool found = false; @@ -170,15 +147,13 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) var model = context.Compilation.GetSemanticModel(tree); var nodes = tree.GetRoot().DescendantNodes(); - var classes = nodes.OfType().Where(ClassIsPublic); - var interfaces = nodes.OfType().Where(InterfaceIsPublic); + var classes = nodes.OfType().Where(winrtRules.ClassIsPublic); + var interfaces = nodes.OfType().Where(winrtRules.InterfaceIsPublic); var structs = nodes.OfType(); // Used in the checking of structure fields List classNames = new List(); - // need an interfaces loop for the array signature rule - /* Check all classes */ foreach (ClassDeclarationSyntax classDeclaration in classes) { From bcb00bcb7361719fd294c312699e302de6e7ed9e Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Tue, 8 Dec 2020 02:43:56 -0800 Subject: [PATCH 28/41] Add array param diagnostics (#624) * add test cases for array param diagnostics * restructure rules into separate file * fixups to struct checks * add docs --- .../TestDiagnostics/ArrayParameterTests.cs | 132 ++++ .../TestDiagnostics/AsyncInterfaceTests.cs | 4 +- .../JaggedArraySignatureTests.cs | 10 +- .../TestDiagnostics/MethodOverloadTests.cs | 2 + .../MultidimensionalArraySignatureTests.cs | 13 +- .../NonZeroLowerBoundArraySignatureTests.cs | 176 ++--- src/Authoring/TestDiagnostics/Scenarios.cs | 14 +- .../StructField_StructInNamespaceTests.cs | 20 +- .../WinRT.SourceGenerator/DiagnosticRules.cs | 614 ++++------------- .../WinRT.SourceGenerator/DiagnosticUtils.cs | 619 ++++++++++++++++++ .../WinRT.SourceGenerator/Generator.cs | 6 +- 11 files changed, 992 insertions(+), 618 deletions(-) create mode 100644 src/Authoring/TestDiagnostics/ArrayParameterTests.cs create mode 100644 src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs diff --git a/src/Authoring/TestDiagnostics/ArrayParameterTests.cs b/src/Authoring/TestDiagnostics/ArrayParameterTests.cs new file mode 100644 index 000000000..3f05ba1a8 --- /dev/null +++ b/src/Authoring/TestDiagnostics/ArrayParameterTests.cs @@ -0,0 +1,132 @@ +using System.Runtime.InteropServices; + +namespace TestDiagnostics +{ + /* TODO: + * what happens if you put another random attribute on an array param? + * check in WRC3 project ... + */ + public class ReadOnlyArray : System.Attribute + { + public ReadOnlyArray() { } + } + + public class WriteOnlyArray : System.Attribute + { + public WriteOnlyArray() { } + } + + /* + public interface IHaveAMethodNamedArray_Valid + { + void Array(int i); + int[] Foo(out int[] arr); + } + + public sealed class OutParam_Valid + { + public void Foo(out int[] arr) { arr = new int[] { }; } + } + + // method with `ref` param + public sealed class OnlyParam + { + // array param with both attributes + public void BothAttributes_Separate([WriteOnlyArray()][ReadOnlyArray()] int[] arr) { } + + public void BothAttributes_Together([WriteOnlyArray(), ReadOnlyArray()] int[] arr) { } + + // array marked `out` but marked with ReadOnlyArray Attribute + public void MarkedOutAndReadOnly([ReadOnlyArray()] out int[] arr) { arr = new int[] { }; } + public void MarkedReadOnly_Valid([ReadOnlyArray()] int[] arr) { } + + // Valid WriteOnlyArray Tests + public void MarkedWriteOnly_Valid([WriteOnlyArray()] int[] arr) { } + public void MarkedOutAndWriteOnly_Valid([WriteOnlyArray()] out int[] arr) { arr = new int[] { }; } + public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } + + // param is array, and marked either InAttribute or OutAttribute + // must have ReadOnlyArray or WriteOnlyArray + public void ArrayMarkedIn([In] int[] arr) { } + public void ArrayMarkedOut([Out] int[] arr) { } + + // method has param marked with ReadOnlyArray / WriteOnlyArray + // but param isnt array + public void NonArrayMarkedReadOnly([ReadOnlyArray()] int arr) { } + public void NonArrayMarkedWriteOnly([WriteOnlyArray()] int arr) { } + + // param marked InAttribute or OutAttribute , disallowed in total + public void ParamMarkedIn([In] int arr) { } + public void ParamMarkedOut([Out] int arr) { } + + // array as param but not marked either way + public void ArrayNotMarked(int[] arr) { } + + public void ArrayNotMarked_Valid(out int[] arr) { arr = new int[] { }; } + } + + public sealed class TwoParam + { + public void BothAttributes(int i, [WriteOnlyArray()][ReadOnlyArray()] int[] arr) { } + // array marked `out` but marked with ReadOnlyArray Attribute + public void MarkedOutAndReadOnly(int i, [ReadOnlyArray()] out int[] arr) { arr = new int[] { }; } + public void MarkedReadOnly_Valid(int i, [ReadOnlyArray()] int[] arr) { } + + // Valid WriteOnlyArray Tests + public void MarkedWriteOnly_Valid(int i, [WriteOnlyArray()] int[] arr) { } + public void MarkedOutAndWriteOnly_Valid(int i, [WriteOnlyArray()] out int[] arr) { arr = new int[] { }; } + public void MarkedOut_Valid(int i, out int[] arr) { arr = new int[] { }; } + + // param is array, and marked either InAttribute or OutAttribute + // must have ReadOnlyArray or WriteOnlyArray + public void ArrayMarkedIn(int i, [In] int[] arr) { } + public void ArrayMarkedOut(int i, [Out] int[] arr) { } + + // method has param marked with ReadOnlyArray / WriteOnlyArray + // but param isnt array + public void NonArrayMarkedReadOnly(int i, [ReadOnlyArray()] int arr) { } + public void NonArrayMarkedWriteOnly(int i, [WriteOnlyArray()] int arr) { } + + // param marked InAttribute or OutAttribute , disallowed in total + public void ParamMarkedIn(int i, [In] int arr) { } // hey! + public void ParamMarkedOut(int i, [Out] int arr) { } + + // array as param but not marked either way + public void ArrayNotMarked(int i, int[] arr) { } + } + + public sealed class TwoArrays + { + public void OneValidOneInvalid_1([WriteOnlyArray] int[] xs, [WriteOnlyArray()][ReadOnlyArray()] int[] ys) { } + public void OneValidOneInvalid_2([WriteOnlyArray][ReadOnlyArray()] int[] xs, [WriteOnlyArray()] int[] ys) { } + + // array marked `out` but marked with ReadOnlyArray Attribute + public void MarkedOutAndReadOnly([ReadOnlyArray()] int[] xs, [ReadOnlyArray()] out int[] arr) { arr = new int[] { }; } + public void MarkedReadOnly_Valid([ReadOnlyArray()] int[] xs, [ReadOnlyArray()] int[] arr) { } + + // Valid WriteOnlyArray Tests + public void MarkedWriteOnly_Valid([ReadOnlyArray()] int[] xs, [WriteOnlyArray()] int[] arr) { } + public void MarkedOutAndWriteOnly_Valid([ReadOnlyArray()] int[] xs, [WriteOnlyArray()] out int[] arr) { arr = new int[] { }; } + public void MarkedOut_Valid([WriteOnlyArray()] int[] xs, out int[] arr) { arr = new int[] { }; } + + // param is array, and marked either InAttribute or OutAttribute + // must have ReadOnlyArray or WriteOnlyArray + public void ArrayMarkedIn(int i, [In] int[] arr) { } + public void ArrayMarkedIn2([ReadOnlyArray()] int[] xs, [In] int[] arr) { } + public void ArrayMarkedOut([ReadOnlyArray()] int[] xs, [Out] int[] arr) { } + + // method has param marked with ReadOnlyArray / WriteOnlyArray but param isnt array + public void NonArrayMarkedReadOnly([ReadOnlyArray()] int[] xs, [ReadOnlyArray()] int i) { } + public void NonArrayMarkedWriteOnly([ReadOnlyArray()] int[] xs, [WriteOnlyArray()] int i) { } + public void NonArrayMarkedWriteOnly2([ReadOnlyArray()] int i, [WriteOnlyArray()] int[] arr) { } + + // param marked InAttribute or OutAttribute , disallowed in total + public void ParamMarkedIn([ReadOnlyArray()] int[] xs, [In] int arr) { } + public void ParamMarkedOut([ReadOnlyArray()] int[] xs, [Out] int arr) { } + public void ParamMarkedOut2([Out] int arr, [ReadOnlyArray()] int[] xs) { } + + // array as param but not marked either way + public void ArrayNotMarked([ReadOnlyArray()] int[] xs, int[] arr) { } + } + */ +} diff --git a/src/Authoring/TestDiagnostics/AsyncInterfaceTests.cs b/src/Authoring/TestDiagnostics/AsyncInterfaceTests.cs index 5880c6339..e05d49ab4 100644 --- a/src/Authoring/TestDiagnostics/AsyncInterfaceTests.cs +++ b/src/Authoring/TestDiagnostics/AsyncInterfaceTests.cs @@ -6,7 +6,8 @@ using Windows.Foundation; namespace TestDiagnostics -{ +{ + /* public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress { public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -122,4 +123,5 @@ int IAsyncOperation.GetResults() throw new NotImplementedException(); } } + */ } diff --git a/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs index 278710361..7466bf341 100644 --- a/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs +++ b/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs @@ -54,7 +54,7 @@ public int[][][] J3_ReturnOnly() public interface JaggedArrayTests_ValidInterface { int[] foo(); - bool bar(int[] arr); + bool bar([ReadOnlyArray()] int[] arr); } public sealed class J3PublicPrivate_Valid @@ -79,6 +79,8 @@ private int[][][] D3_ReturnOnly() /* * Invalid tests */ + + /* public sealed class JaggedArray_Properties_Invalid { private int[][] ArrP { get; set; } @@ -141,7 +143,7 @@ public interface J3MemberOfInterface_Invalid public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); } - + namespace SubNamespace { public interface SubNamespaceInterface_J2Methods_Invalid @@ -153,7 +155,8 @@ public interface SubNamespaceInterface_J2Methods_Invalid public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); } - + + /* public interface SubNamespaceInterface_J3Methods_Invalid { public int[][][] J3_ReturnOnly(); @@ -164,5 +167,6 @@ public interface SubNamespaceInterface_J3Methods_Invalid public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); } } // end SubNamespace + */ } diff --git a/src/Authoring/TestDiagnostics/MethodOverloadTests.cs b/src/Authoring/TestDiagnostics/MethodOverloadTests.cs index 6e0013321..fe2449c3a 100644 --- a/src/Authoring/TestDiagnostics/MethodOverloadTests.cs +++ b/src/Authoring/TestDiagnostics/MethodOverloadTests.cs @@ -71,6 +71,7 @@ public sealed class TwoOverloads_OneAttribute_3_Valid public int OverloadExample(int n) { return n; } } + /* // invalid method overload tests public sealed class TwoOverloads_NoAttribute_Invalid { @@ -165,4 +166,5 @@ public sealed class ThreeOverloads_TwoAttributes_Invalid [Windows.Foundation.Metadata.DefaultOverload()] public bool OverloadExample(bool b) { return b; } } + */ } diff --git a/src/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs b/src/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs index 16ed2d99a..8a573adf5 100644 --- a/src/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs +++ b/src/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs @@ -53,20 +53,16 @@ public sealed class MultiDimPublicPrivate_Valid } - public interface MultiDimArrayTests_ValidInterface_NoMultiDim - { - int[] foo(); - bool bar(int[] arr); - } - /* * Invalid tests include public properties in public classes, public interface methods, */ + + /* public sealed class MultidimensionalArraySignature_2D_Invalid { public int[,] Arr_2d { get; set; } public int[,,] Arr_3d { get; set; } - private int[,] PrivArr_2d { get; set; } /* below should pass through undetected (private property) */ + private int[,] PrivArr_2d { get; set; } } public sealed class D2PublicPublic_Invalid @@ -137,4 +133,5 @@ public interface SubNamespaceInterface_D3Methods_Invalid public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); } } -} // End TestDiagnostics namespace + */ +} diff --git a/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs b/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs index 25c579fda..498473da9 100644 --- a/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs +++ b/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs @@ -9,7 +9,11 @@ namespace TestDiagnostics /* NZLB = non-zero lowerbound array */ - // public property in class + /* + * Invalid tests include public properties in public classes, public interface methods, + */ + + /* public sealed class NonZeroLowerBound_PublicProperty_Invalid { public int[] Arr @@ -32,7 +36,59 @@ public System.Array Arr4 get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } } + + public interface InterfaceWithNonZeroLowerBound_Invalid + { + System.Array Id(System.Array arr); + void Method2(System.Array arr); + System.Array Method3(); + } + + public sealed class NZLBArraySignature_2D_Invalid + { + public System.Array Arr_2d { get; set; } + public System.Array Arr_3d { get; set; } + private System.Array PrivArr_2d { get; set; } + } + + public sealed class NZLBPublicPublic_Invalid + { + public System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } + public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } + + public interface NZLBMemberOfInterface_Invalid + { + public System.Array NZLB_ReturnOnly(); + public System.Array NZLB_ReturnAndInput1(System.Array arr); + public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr); + public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr); + public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b); + public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b); + } + + namespace SubNamespace + { + public interface SubNamespacInterface_NZLBMethods_Invalid + { + public System.Array D2_ReturnOnly(); + public System.Array D2_ReturnAndInput1(System.Array arr); + public System.Array D2_ReturnAndInput2of2(bool a, System.Array arr); + public System.Array D2_ReturnAndInput2of3(bool a, System.Array arr, bool b); + public bool D2_NotReturnAndInput2of2(bool a, System.Array arr); + public bool D2_NotReturnAndInput2of3(bool a, System.Array arr, bool b); + } + } + */ + + /* + * Valid tests + */ public sealed class NonZeroLowerBound_PrivateProperty_Valid { private int[] PrivArr @@ -95,101 +151,45 @@ private System.Array PrivArr4 } } - public interface InterfaceWithNonZeroLowerBound_Invalid + internal interface InterfaceWithNonZeroLowerBound_Valid { System.Array Id(System.Array arr); void Method2(System.Array arr); System.Array Method3(); } - internal interface InterfaceWithNonZeroLowerBound_Valid + internal class NZLBArraySignature_2D_PrivateClass_Valid { - System.Array Id(System.Array arr); - void Method2(System.Array arr); - System.Array Method3(); + public System.Array Arr_2d { get; set; } + public System.Array Arr_3d { get; set; } + private System.Array PrivArr_2d { get; set; } + private System.Array PrivArr_3d { get; set; } } + public sealed class NZLBArraySignature_3D_Valid + { + private System.Array PrivArr_2d { get; set; } - internal class NZLBArraySignature_2D_PrivateClass_Valid - { - public System.Array Arr_2d { get; set; } - public System.Array Arr_3d { get; set; } - private System.Array PrivArr_2d { get; set; } - private System.Array PrivArr_3d { get; set; } - } - public sealed class NZLBArraySignature_3D_Valid - { - private System.Array PrivArr_2d { get; set; } - - private Array PrivArr_3d { get; set; } - } - // methods ?? - internal sealed class NZLBInternalPublic_Valid - { - public System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } - public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - } - - // tests return type and paramteter cases for 3-dimensional arrays - // we expect normal compilation since the methods are private - public sealed class NZLBPublicPrivate_Valid - { - private System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - private System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } - private System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - private System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - private bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - private bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - } - - public interface NZLB_ValidInterface - { - int[] foo(); - bool bar(int[] arr); - } - /* - * Invalid tests include public properties in public classes, public interface methods, - */ - public sealed class NZLBArraySignature_2D_Invalid - { - public System.Array Arr_2d { get; set; } - public System.Array Arr_3d { get; set; } - private System.Array PrivArr_2d { get; set; } /* below should pass through undetected (private property) */ - } - - public sealed class NZLBPublicPublic_Invalid - { - public System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } - public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - } - - public interface NZLBMemberOfInterface_Invalid - { - public System.Array NZLB_ReturnOnly(); - public System.Array NZLB_ReturnAndInput1(System.Array arr); - public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr); - public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr); - public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b); - public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b); - } + private Array PrivArr_3d { get; set; } + } + internal sealed class NZLBInternalPublic_Valid + { + public System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } + public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } - namespace SubNamespace - { - public interface SubNamespacInterface_NZLBMethods_Invalid - { - public System.Array D2_ReturnOnly(); - public System.Array D2_ReturnAndInput1(System.Array arr); - public System.Array D2_ReturnAndInput2of2(bool a, System.Array arr); - public System.Array D2_ReturnAndInput2of3(bool a, System.Array arr, bool b); - public bool D2_NotReturnAndInput2of2(bool a, System.Array arr); - public bool D2_NotReturnAndInput2of3(bool a, System.Array arr, bool b); - } - } + // tests return type and paramteter cases for 3-dimensional arrays + // we expect normal compilation since the methods are private + public sealed class NZLBPublicPrivate_Valid + { + private System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + private System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } + private System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + private System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + private bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + private bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + } } diff --git a/src/Authoring/TestDiagnostics/Scenarios.cs b/src/Authoring/TestDiagnostics/Scenarios.cs index de1da64e3..92f5e6536 100644 --- a/src/Authoring/TestDiagnostics/Scenarios.cs +++ b/src/Authoring/TestDiagnostics/Scenarios.cs @@ -9,7 +9,17 @@ namespace TestDiagnostics { - + /* + public interface IHaveAMethodWithRefParam + { + void foo(ref int i); + } + + public sealed class ClassWithMethodUsingRefParam + { + public void MethodWithRefParam(ref int i) { i++; } + } + public sealed class ClassThatOverloadsOperator { public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) @@ -46,5 +56,5 @@ public SameArityConstructors(string s) // Can test that multiple constructors are allowed (has been verified already, too) // as long as they have different arities by making one take none or 2 arguments } - + */ } diff --git a/src/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs b/src/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs index de617cbc5..4674f117a 100644 --- a/src/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs +++ b/src/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs @@ -7,7 +7,7 @@ namespace TestDiagnostics { - + /* public sealed class SillyClass { public double Identity(double d) @@ -53,9 +53,11 @@ int foo(int x) return x; } } - public struct StructWithConst_Invalid // really invalid ? + + public struct StructWithConst_Invalid { const int five = 5; + private int six; } public enum BasicEnum @@ -94,23 +96,23 @@ public struct StructWithAllValidFields string str; } - public struct StructWithObjectField_Invalid // is this really invalid? + public struct StructWithObjectField_Invalid { - object obj; - + public object obj; } - public struct StructWithDynamicField_Invalid // is this really invalid? + public struct StructWithDynamicField_Invalid { - dynamic dyn; + public dynamic dyn; } - public struct StructWithByteField_Invalid // is this really invalid? + public struct StructWithByteField_Valid { - byte b; + public byte b; } public struct StructWithWinRTStructField { public Matrix3x2 matrix; } + */ } diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index 7c4896622..d88c12221 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -1,22 +1,24 @@ using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -namespace Generator +namespace WinRT.SourceGenerator { - public class WinRTRules + public class CheckEqual : System.Attribute { - #region RuleDescriptors + public CheckEqual(DiagnosticDescriptor d) + { + } + } - /* MakeRule is a helper function that does most of the boilerplate information needed for Diagnostics - param id : string, a short identifier for the diagnostic - param title : string, a few words generally describing the diagnostic - param messageFormat : string, describes the diagnostic -- formatted with {0}, ... -- - such that data can be passed in for the code the diagnostic is reported for */ - static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) + public class DiagnosticRules + { + /// + /// helper function that does most of the boilerplate information needed for Diagnostics + /// + /// string, a short identifier for the diagnostic + /// string, a few words generally describing the diagnostic + /// string, describes the diagnostic -- formatted with {0}, ... -- + /// such that data can be passed in for the code the diagnostic is reported for /// + private static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) { return new DiagnosticDescriptor( id: id, @@ -30,537 +32,141 @@ static DiagnosticDescriptor MakeRule(string id, string title, string messageForm helpLinkUri: "https://docs.microsoft.com/en-us/previous-versions/hh977010(v=vs.110)"); } - static DiagnosticDescriptor AsyncRule = MakeRule( + public static DiagnosticDescriptor AsyncRule = MakeRule( "WME1084", "Async Interfaces Rule", "Runtime component class {0} cannot implement async interface {1}; use AsyncInfo class methods instead of async interfaces"); - - static DiagnosticDescriptor ClassConstructorRule = MakeRule( + + public static DiagnosticDescriptor ClassConstructorRule = MakeRule( "WME1099", "Class Constructor Rule", "Runtime component class {0} cannot have multiple constructors of the same arity {1}"); - static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( + public static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( "WME1092", "Parameter Named Value Rule", ("The method {0} has a parameter named {1} which is the same as the default return value name. " + "Consider using another name for the parameter or use the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute " + "to explicitly specify the name of the return value.")); - static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( + public static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( "WME1060(b)", "Private field in struct", - "Structure {0} has private field. All fields must be public for Windows Runtime structures."); + "Structure {0} has non-public field. All fields must be public for Windows Runtime structures."); + - static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( + public static DiagnosticDescriptor StructHasConstFieldRule = MakeRule( + "WME1060(b)", + "Const field in struct", + "Structure {0} has const field. Constants can only appear on Windows Runtime enumerations."); + + public static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( "WME1060", "Invalid field in struct", - ("Structure {0} has field '{1}' of type {2}; {2} is not a valid Windows Runtime field type. Each field " + ("Structure {0} has field '{1}' of type {2}; {2} is not a valid Windows Runtime field type. Each field " + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.")); - - static DiagnosticDescriptor StructHasInvalidFieldRule2 = MakeRule( + + public static DiagnosticDescriptor StructHasInvalidFieldRule2 = MakeRule( "WME1060", "Invalid field in struct", - ("Structure {0} has a field of type {1}; {1} is not a valid Windows Runtime field type. Each field " + ("Structure {0} has a field of type {1}; {1} is not a valid Windows Runtime field type. Each field " + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.")); - static DiagnosticDescriptor OperatorOverloadedRule = MakeRule( + public static DiagnosticDescriptor OperatorOverloadedRule = MakeRule( "WME1087", "Operator overload exposed", "{0} is an operator overload. Managed types cannot expose operator overloads in the Windows Runtime"); - static DiagnosticDescriptor MethodOverload_MultipleDefaultAttribute = MakeRule( + public static DiagnosticDescriptor MethodOverload_MultipleDefaultAttribute = MakeRule( "WME1059", "Only one overload should be designated default", // todo better msg - //"Multiple {0}-parameter overloads of '{1}.{2}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + //"Multiple {0}-parameter overloads of '{1}.{2}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); "In class {2}: Multiple {0}-parameter overloads of '{1}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); - static DiagnosticDescriptor MethodOverload_NeedDefaultAttribute = MakeRule( + public static DiagnosticDescriptor MethodOverload_NeedDefaultAttribute = MakeRule( "WME1085", "Multiple overloads seen, one needs a default", // todo better msg - //"The {0}-parameter overloads of {1}.{2} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + //"The {0}-parameter overloads of {1}.{2} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + // "In class {2}: The {0}-parameter overloads of {1} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); - static DiagnosticDescriptor ArraySignature_JaggedArrayRule = MakeRule( - "WME10??", - "Array signature found with jagged array, which is not a valid WinRT type", // todo better msg - "In type {0}: the method {1} has signature that contains a jagged array; use a different type like List"); + public static DiagnosticDescriptor ArraySignature_JaggedArrayRule = MakeRule( + "WME1036", + "Array signature found with jagged array, which is not a valid WinRT type", + // + "Method {0} has a nested array of type {1} in its signature. Arrays in Windows Runtime method signature cannot be nested."); - static DiagnosticDescriptor ArraySignature_MultiDimensionalArrayRule = MakeRule( - "WME10??", - "Array signature found with multi-dimensional array, which is not a valid WinRT type", // todo better msg - "In type {0}: the method {1} has signature that contains a multi-dimensional array; use a different type like List"); + public static DiagnosticDescriptor ArraySignature_MultiDimensionalArrayRule = MakeRule( + "WME1035", + "Array signature found with multi-dimensional array, which is not a valid WinRT type", + // + "Method '{0}' has a multi-dimensional array of type '{1}' in its signature. Arrays in Windows Runtime method signatures must be one dimensional."); - static DiagnosticDescriptor ArraySignature_SystemArrayRule = MakeRule( + public static DiagnosticDescriptor ArraySignature_SystemArrayRule = MakeRule( "WME10??", "Array signature found with System.Array instance, which is not a valid WinRT type", // todo better msg + // // "In type {0}: the method {1} has signature that contains a System.Array instance; use a different type like List"); // "Method {0} has a multi-dimensional array of type {1} in its signature. Arrays in Windows Runtime must be one dimensional" - #endregion - - private bool PropertyIsPublic(PropertyDeclarationSyntax p) - { - foreach (var thing in p.Modifiers) - { - if (thing.ValueText.Equals("public")) - { - return true; - } - } - return false; - } - - private bool MethodIsPublic(MethodDeclarationSyntax m) - { - foreach (var thing in m.Modifiers) - { - if (thing.ValueText.Equals("public")) - { - return true; - } - } - return false; - } - - public bool ClassIsPublic(ClassDeclarationSyntax m) - { - foreach (var thing in m.Modifiers) - { - if (thing.ValueText.Equals("public")) - { - return true; - } - } - return false; - } - - public bool InterfaceIsPublic(InterfaceDeclarationSyntax m) - { - foreach (var thing in m.Modifiers) - { - if (thing.ValueText.Equals("public")) - { - return true; - } - } - return false; - } - - - #region AsyncInterfaces - /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ - static string[] ProhibitedAsyncInterfaces = { - "Windows.Foundation.IAsyncAction", - "Windows.Foundation.IAsyncActionWithProgress`1", - "Windows.Foundation.IAsyncOperation`1", - "Windows.Foundation.IAsyncOperationWithProgress`2" - }; - - /* SameAsyncInterface uses the proper ISymbol equality check on the OriginalDefinition of the given symbols */ - private bool SameAsyncInterface(INamedTypeSymbol interfaceA, INamedTypeSymbol interfaceB) - { - /* Using OriginalDefinition b/c the generic field of the metadata type has the template name, e.g. `TProgress` - * and the actual interface will have a concrete type, e.g. `int` */ - return SymbolEqualityComparer.Default.Equals(interfaceA.OriginalDefinition, interfaceB.OriginalDefinition); - } - - /* ImplementsAsyncInterface - * returns true if the class represented by the symbol implements any of the interfaces defined in ProhibitedAsyncInterfaces */ - public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INamedTypeSymbol classSymbol, ClassDeclarationSyntax classDeclaration) - { - foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) - { - INamedTypeSymbol asyncInterface = context.Compilation.GetTypeByMetadataName(prohibitedInterface); - foreach (INamedTypeSymbol interfaceImplemented in classSymbol.AllInterfaces) - { - if (SameAsyncInterface(interfaceImplemented, asyncInterface)) - { - context.ReportDiagnostic(Diagnostic.Create(AsyncRule, classDeclaration.GetLocation(), classDeclaration.Identifier, interfaceImplemented)); - return true; - /* By exiting early, we only report diagnostic for first prohibited interface we see. - If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. - could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported */ - } - } - } - return false; - } - - #endregion - - #region Misc - /* HasMultipleConstructorsOfSameArity - * keeps track of the arity of all constructors, and reports the diagnostic (and exits) as soon as a two constructors of the same arity are seen. */ - public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - IEnumerable constructors = classDeclaration.ChildNodes().OfType(); - - /* more performant data structure? or use a Set, in order to not have to call Contains()? */ - IList aritiesSeenSoFar = new List(); - - foreach (ConstructorDeclarationSyntax constructor in constructors) - { - int arity = constructor.ParameterList.Parameters.Count; - - if (aritiesSeenSoFar.Contains(arity)) - { - context.ReportDiagnostic(Diagnostic.Create(ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity)); - return true; - } - else - { - aritiesSeenSoFar.Add(arity); - } - } - return false; - } - - /* HasParameterNamedValue - * the generated code for components uses the name "__retval" for the output variable, - * we report diagnostic if a user uses this same identifier as a parameter to a method */ - public bool HasParameterNamedValue(ref GeneratorExecutionContext context, MethodDeclarationSyntax method) - { - foreach (ParameterSyntax parameter in method.ParameterList.Parameters) - { - if (parameter.Identifier.Value.Equals("__retval")) - { - context.ReportDiagnostic(Diagnostic.Create(ParameterNamedValueRule, parameter.GetLocation(), method.Identifier, parameter.Identifier)); - return true; - } - } - return false; - } - - /// MethodHasAttribute looks at all possible attributes on a given method declaration - /// returns true iff any are (string) equal to the given attribute name - private bool MethodHasAttribute(string attrName, MethodDeclarationSyntax method) - { - foreach (var attrList in method.AttributeLists) - { - foreach (var attr in attrList.Attributes) - { - if (attr.Name.ToString().Equals(attrName)) - { - return true; - } - } - } - return false; - } - - /// - /// Keeps track of repeated declarations of a method (overloads) and raises diagnostics according to the rule that exactly one overload should be attributed the default - /// - /// The method to check attributes for - /// Keeps track of the method (via name + arity) and whether it was declared with the DefaultOverload attribute - /// Keeps track of the methods that are overloads but don't have the DefaultOverload attribute (yet) - /// The class the method lives in -- used for creating the diagnostic - /// The SourceGenerator context the code lives in - /// True iff multiple overloads of a method are found, where more than one has been designated as the default overload - private bool CheckOverloadAttributes(MethodDeclarationSyntax method, - ref Dictionary methodHasAttributeMap, - ref Dictionary overloadsWithoutAttributeMap, - SyntaxToken classIdentifier, - ref GeneratorExecutionContext context) - { - bool found = false; - int methodArity = method.ParameterList.Parameters.Count; - string methodNameWithArity = method.Identifier.Text + methodArity.ToString(); - - // look at all the attributes on this method and see if any of them is the DefaultOverload attribute - bool hasDefaultOverloadAttribute = MethodHasAttribute("Windows.Foundation.Metadata.DefaultOverload", method); - - bool seenMethodBefore = methodHasAttributeMap.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); - - // Do we have an overload ? - if (seenMethodBefore) - { - if (hasDefaultOverloadAttribute && !methodHasAttrAlready) - { - // we've seen it, but it didnt have the attribute, so mark that it has it now - methodHasAttributeMap[methodNameWithArity] = true; - overloadsWithoutAttributeMap.Remove(methodNameWithArity); - } - else if (hasDefaultOverloadAttribute && methodHasAttrAlready) - { - // raise the "can't have multiple default attributes" diagnostic - context.ReportDiagnostic(Diagnostic.Create(MethodOverload_MultipleDefaultAttribute, method.GetLocation(), - methodArity, method.Identifier, classIdentifier)); - found |= true; - } - else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) - { - // we could see this method later with the attribute, so hold onto the diagnostic for it until we know it doesn't have the attribute - Diagnostic diagnostic = Diagnostic.Create(MethodOverload_NeedDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classIdentifier); - overloadsWithoutAttributeMap[methodNameWithArity] = diagnostic; - } - } - else - { - // first time we're seeing the method, add a pair in the map for its name and whether it has the attribute - methodHasAttributeMap[methodNameWithArity] = hasDefaultOverloadAttribute; - } - - return found; - } - - /// - /// Checks to see if the class declares any operators (overloading them) - /// - /// - /// - /// True iff an operator is overloaded by the given class - public bool OverloadsOperator(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - var operatorDeclarations = classDeclaration.DescendantNodes().OfType(); - if (operatorDeclarations.Any()) - { - var overloadedOperator = operatorDeclarations.First(); - context.ReportDiagnostic(Diagnostic.Create(OperatorOverloadedRule, overloadedOperator.GetLocation(), overloadedOperator.OperatorToken)); - return true; - } - return false; - } - - #endregion - - #region ArraySignatureChecking - - /// - /// Looks at all the methods declared on the given interface and checks them for improper array types (System.Array instances, multidimensional, jagged) - /// - /// - /// - /// True iff any of the invalid array types are used in any of the method signatures on the given interface - public bool Interface_CheckArraySignature(ref GeneratorExecutionContext context, InterfaceDeclarationSyntax interfaceDeclaration) - { - bool found = false; - var methodDeclarations = interfaceDeclaration.DescendantNodes().OfType(); - foreach (var method in methodDeclarations) // interfaces don't have private methods, right? - { - found |= Method_CheckForSystemArrayType(ref context, method, interfaceDeclaration.Identifier, "System.Array"); - found |= Method_CheckForSystemArrayType(ref context, method, interfaceDeclaration.Identifier, "Array"); - found |= CheckForInvalidArrayType(method.DescendantNodes().OfType(), ref context, interfaceDeclaration.Identifier, method.Identifier, method.GetLocation()); - } - return found; - } - - /// - /// Looks at all the properties of the given class and checks them for improper array types (System.Array instances, multidimensional, jagged) - /// - /// - /// - /// True iff any of the invalid array types are used in any of the propertyy signatures in the given class - public bool Class_CheckArraySignature(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - bool found = false; - var props = classDeclaration.DescendantNodes().OfType(); - foreach (var prop in props.Where(PropertyIsPublic)) - { - found |= Property_CheckForSystemArrayType(ref context, prop, classDeclaration.Identifier, "System.Array"); - found |= Property_CheckForSystemArrayType(ref context, prop, classDeclaration.Identifier, "Array"); - found |= CheckForInvalidArrayType(prop.DescendantNodes().OfType(), ref context, classDeclaration.Identifier, prop.Identifier, prop.GetLocation()); - } - return found; - } - - /// - /// Look at all the array types and if any are of the form [][]+ or [,+] then raise the corresponding diagnostic and return true - /// - /// - /// - /// The type the array lives in - /// The code the array is a part of the signature for; e.g. property or method - /// - /// True iff any of the array types given are multidimensional or jagged - private bool CheckForInvalidArrayType(IEnumerable arrTypes, ref GeneratorExecutionContext context, SyntaxToken typeIdentifier, SyntaxToken fieldIdentifier, Location loc) - { - if (arrTypes.Any()) - { - foreach (var arrType in arrTypes) - { - var rankSpecs = arrType.DescendantNodes().OfType(); - if (rankSpecs.Count() > 1) - { - context.ReportDiagnostic(Diagnostic.Create(ArraySignature_JaggedArrayRule, loc, typeIdentifier, fieldIdentifier)); - return true; // could do or-eq on a `found` boolean instead of exiting as soon as we see invalid... - } - else if (rankSpecs.Count() == 1 && rankSpecs.First().ToString().Contains(",")) - { - context.ReportDiagnostic(Diagnostic.Create(ArraySignature_MultiDimensionalArrayRule, loc, typeIdentifier, fieldIdentifier)); - return true; - } - } - } - return false; - } - - /// - /// Checks method signatures with nodes of the generic type given for the given typename - /// - /// - /// The method is generic because we need to use this on fields that are of type QualifiedNameSyntax and IdentifierSyntax; e.g. the System.Array type and Array type - /// - /// Compilation unit - /// The method declaration - /// The type the method lives in - /// The string representation of the type we are looking for -- either "Array" or "System.Array" - /// True iff the return type of the given method matches the given type - private bool Method_CheckForSystemArrayType(ref GeneratorExecutionContext context, MethodDeclarationSyntax method, SyntaxToken classIdentifier, string typeName) - { - var qualName = method.DescendantNodes().OfType(); - if (qualName.Any() && qualName.First().ToString().Equals(typeName)) - { - context.ReportDiagnostic(Diagnostic.Create(ArraySignature_SystemArrayRule, method.GetLocation(), classIdentifier, method.Identifier)); - return true; - } - return false; - } - - /// - /// Checks property signatures with nodes of the generic type given for the given typename - /// - /// - /// The method is generic because we need to use this on fields that are of type QualifiedNameSyntax and IdentifierSyntax; e.g. the System.Array type and Array type - /// - /// Compilation unit - /// The property declaration - /// The type the property lives in - /// The string representation of the type we are looking for -- either "Array" or "System.Array" - /// True if the return type of the given property matches the given type - private bool Property_CheckForSystemArrayType(ref GeneratorExecutionContext context, PropertyDeclarationSyntax prop, SyntaxToken classIdentifier, string typeName) - { - var qualName = prop.DescendantNodes().OfType(); - if (qualName.Any() && qualName.First().ToString().Equals(typeName)) - { - context.ReportDiagnostic(Diagnostic.Create(ArraySignature_SystemArrayRule, prop.GetLocation(), classIdentifier, prop.Identifier)); - return true; - } - return false; - } - - #endregion - - /// - /// Loops over each method declared in the given class and checks for various diagnostics - /// - /// - /// - /// True iff any of the diagnostics checked for are found. - public bool HasErrorsInMethods(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - bool found = false; - IEnumerable methods = classDeclaration.ChildNodes().OfType(); - - Dictionary methodsHasAttributeMap = new Dictionary(); - - /* we can't throw the diagnostic as soon as we see a second overload without an attribute, - * as there could be a third overload with the default attribute - * we use this map to keep track of these cases, and after we have checked all methods, - * we check the elements of the map to raise diagnostics for those that didn't get attributed */ - Dictionary overloadsWithoutAttributeMap = new Dictionary(); - - foreach (MethodDeclarationSyntax method in methods.Where(MethodIsPublic)) - { - /* Gather information on overloaded methods; make sure there is only one marked DefaultOverload */ - found |= CheckOverloadAttributes(method, ref methodsHasAttributeMap, ref overloadsWithoutAttributeMap, classDeclaration.Identifier, ref context); - - /* make sure no parameter has the name "__retval" */ - found |= HasParameterNamedValue(ref context, method); - - /* see if method signature contains the types System.Array or Array */ - found |= Method_CheckForSystemArrayType(ref context, method, classDeclaration.Identifier, "System.Array"); - found |= Method_CheckForSystemArrayType(ref context, method, classDeclaration.Identifier, "Array"); - found |= CheckForInvalidArrayType(method.DescendantNodes().OfType(), ref context, classDeclaration.Identifier, method.Identifier, method.GetLocation()); - } - - /* Finishes up the work started by `CheckOverloadAttributes` */ - foreach (var thing in overloadsWithoutAttributeMap) - { - context.ReportDiagnostic(thing.Value); - found |= true; - } - return found; - } - - #region StructChecks - - /* SimplifySyntaxTypeString - * returns the more common term for the given kind of syntax; used when creating a diagnostic for an invalid field in a struct */ - private string SimplifySyntaxTypeString(string syntaxType) - { - switch (syntaxType) - { - case "EventFieldDeclarationSyntax": - return "event"; - case "ConstructorDeclarationSyntax": - return "constructor"; - case "DelegateDeclarationSyntax": - return "delegate"; - case "IndexerDeclarationSyntax": - return "indexer"; - case "MethodDeclarationSyntax": - return "method"; - case "OperatorDeclarationSyntax": - return "operator"; - case "PropertyDeclarationSyntax": - return "property"; - default: - return "unknown syntax type: " + syntaxType; - } - } - - /* StructHasFieldOfType - * returns true iff there is a field of the given type in the given struct - * e.g., if T is PropertyDeclarationSyntax, then if the struct has a property, we report a diagnostic and return true */ - public bool StructHasFieldOfType(ref GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) - { - if (structDeclaration.DescendantNodes().OfType().Any()) - { - context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule2, - structDeclaration.GetLocation(), - structDeclaration.Identifier, - SimplifySyntaxTypeString(typeof(T).Name))); - return true; - } - return false; - } - - /* StructHasInvalidFields - * returns true if there is a field declared private, - * or (inclusive) declared with a type that is a class or one of object, byte or dynamic */ - public bool StructHasFieldOfInvalidType(ref GeneratorExecutionContext context, FieldDeclarationSyntax field, StructDeclarationSyntax structDeclaration, List classNames) - { - bool found = false; - - /* No private fields allowed in Windows Runtime components */ - if (field.GetFirstToken().ToString().Equals("private")) // hmm - { - context.ReportDiagnostic(Diagnostic.Create(StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); - found |= true; - } - - foreach (var variable in field.DescendantNodes().OfType()) - { - var typeStr = variable.Type.ToString(); - - List invalidTypes = new List { "object", "byte", "dynamic" }; - invalidTypes.AddRange(classNames); - - if (invalidTypes.Contains(typeStr)) - { - context.ReportDiagnostic(Diagnostic.Create(StructHasInvalidFieldRule, - variable.GetLocation(), - structDeclaration.Identifier, - field.ToString(), - typeStr)); - found |= true; - } - } - return found; - } - - #endregion + public static DiagnosticDescriptor RefParameterFound = MakeRule( + "WME11??", + "Parameter passed by reference", + // + "Method '{0}' has parameter '{1}' marked `ref`. Reference parameters are not allowed in Windows Runtime."); + + public static DiagnosticDescriptor ArrayMarkedInOrOut = MakeRule( + "WME1103", + "Array parameter marked InAttribute or OutAttribute", + // + "Method '{0}' has parameter '{1}' which is an array, and which has either a " + + "System.Runtime.InteropServices.InAttribute or a System.Runtime.InteropServices.OutAttribute. " + + "In the Windows Runtime, array parameters must have either ReadOnlyArray or WriteOnlyArray. " + + "Please remove these attributes or replace them with the appropriate Windows " + + "Runtime attribute if necessary."); + + public static DiagnosticDescriptor NonArrayMarkedInOrOut = MakeRule( + "WME1105", + "Parameter (not array type) marked InAttribute or OutAttribute", + "Method '{0}' has parameter '{1}' with a System.Runtime.InteropServices.InAttribute " + // + + "or System.Runtime.InteropServices.OutAttribute.Windows Runtime does not support " + + "marking parameters with System.Runtime.InteropServices.InAttribute or " + + "System.Runtime.InteropServices.OutAttribute. Please consider removing " + + "System.Runtime.InteropServices.InAttribute and replace " + + "System.Runtime.InteropServices.OutAttribute with 'out' modifier instead."); + + public static DiagnosticDescriptor ArrayParamMarkedBoth = MakeRule( + "WME1101", + "Array paramter marked both ReadOnlyArray and WriteOnlyArray", + // + "Method '{0}' has parameter '{1}' which is an array, and which has both ReadOnlyArray and WriteOnlyArray. " + + "In the Windows Runtime, the contents array parameters must be either readable " + + "or writable.Please remove one of the attributes from '{1}'."); + + /// WME1102 + public static DiagnosticDescriptor ArrayOutputParamMarkedRead = MakeRule( + "WME1102", + "Array parameter marked `out` and ReadOnlyArray", + // + "Method '{0}' has an output parameter '{1}' which is an array, but which has ReadOnlyArray attribute. In the Windows Runtime, " + + "the contents of output arrays are writable.Please remove the attribute from '{1}'."); + + /// WME1106 + public static DiagnosticDescriptor ArrayParamNotMarked = MakeRule( + "WME1106", + "Array parameter not marked ReadOnlyArray or WriteOnlyArray way", + // + "Method '{0}' has parameter '{1}' which is an array. In the Windows Runtime, the " + + "contents of array parameters must be either readable or writable.Please apply either ReadOnlyArray or WriteOnlyArray to '{1}'." + + "hasWriteOnly: {2} ; hasReadOnly: {3} ; HasOut: {4}"); + + public static DiagnosticDescriptor NonArrayMarked = MakeRule( + "WME1104", + "Non-array parameter marked with ReadOnlyArray or WriteOnlyArray", + // + "Method '{0}' has parameter '{1}' which is not an array, and which has either a " + + "ReadOnlyArray attribute or a WriteOnlyArray attribute . Windows Runtime does " + + "not support marking non-array parameters with ReadOnlyArray or WriteOnlyArray."); } } diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs new file mode 100644 index 000000000..245dc88ef --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -0,0 +1,619 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Collections.Generic; +using System.Linq; +using WinRT.SourceGenerator; + +namespace Generator +{ + public class WinRTRules + { + + #region ModifierHelpers + private bool SyntaxTokenIs(SyntaxToken stx, string str) { return stx.Value.Equals(str); } + + private bool ModifiersContains(SyntaxTokenList modifiers, string str) + { + foreach (var modifier in modifiers) + { + if (SyntaxTokenIs(modifier, str)) { return true; } + } + return false; + } + + private bool PropertyIsPublic(PropertyDeclarationSyntax p) { return ModifiersContains(p.Modifiers, "public"); } + private bool MethodIsPublic(MethodDeclarationSyntax m) { return ModifiersContains(m.Modifiers, "public"); } + public bool ClassIsPublic(ClassDeclarationSyntax c) { return ModifiersContains(c.Modifiers, "public"); } + public bool InterfaceIsPublic(InterfaceDeclarationSyntax i) { return ModifiersContains(i.Modifiers, "public"); } + + #endregion + + #region AttributeHelpers + + /// + /// Attributes can come in one list or many, e.g. [A()][B()] vs. [A(),B()] + /// look at all possible attributes and see if any match the given string + /// + /// + /// attribute names need to be fully qualified, + /// e.g. DefaultOverload is really Windows.Foundation.Metadata.DefaultOverload + /// + /// all the syntax nodes that correspond to an attribute list + /// true iff the given attribute is in the list + private bool MatchesAnyAttribute(string attrName, SyntaxList ls) + { + foreach (var attrList in ls) + { + foreach (var attr in attrList.Attributes) + { + if (attr.Name.ToString().Equals(attrName)) + { + return true; + } + } + } + return false; + } + + /// + /// Looks at all possible attributes on a given method declaration + /// + /// + /// returns true iff any are (string) equal to the given attribute name + /// + private bool MethodHasAttribute(string attrName, MethodDeclarationSyntax method) { return MatchesAnyAttribute(attrName, method.AttributeLists); } + + /// + /// Looks at all possible attributes on a given parameter declaration + /// + /// + /// returns true iff any are (string) equal to the given attribute name + /// + private bool ParamHasAttribute(string attrName, ParameterSyntax param) { return MatchesAnyAttribute(attrName, param.AttributeLists); } + + /// + /// Keeps track of repeated declarations of a method (overloads) and raises diagnostics according to the rule that exactly one overload should be attributed the default + /// + /// + /// The method to check attributes for + /// + /// Keeps track of the method (via name + arity) and whether it was declared with the DefaultOverload attribute + /// + /// Keeps track of the methods that are overloads but don't have the DefaultOverload attribute (yet) + /// Used after this function executes, hence the reference parameter + /// + /// The class the method lives in -- used for creating the diagnostic + /// The SourceGenerator context the code lives in + /// True iff multiple overloads of a method are found, where more than one has been designated as the default overload + private bool CheckOverloadAttributes(MethodDeclarationSyntax method, + ref Dictionary methodHasAttributeMap, + ref Dictionary overloadsWithoutAttributeMap, + SyntaxToken classId, + ref GeneratorExecutionContext context) + { + bool found = false; + int methodArity = method.ParameterList.Parameters.Count; + string methodNameWithArity = method.Identifier.Text + methodArity.ToString(); + + // look at all the attributes on this method and see if any of them is the DefaultOverload attribute + bool hasDefaultOverloadAttribute = MethodHasAttribute("Windows.Foundation.Metadata.DefaultOverload", method); + + bool seenMethodBefore = methodHasAttributeMap.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); + + // Do we have an overload ? + if (seenMethodBefore) + { + if (hasDefaultOverloadAttribute && !methodHasAttrAlready) + { + // we've seen it, but it didnt have the attribute, so mark that it has it now + methodHasAttributeMap[methodNameWithArity] = true; + overloadsWithoutAttributeMap.Remove(methodNameWithArity); + } + else if (hasDefaultOverloadAttribute && methodHasAttrAlready) + { + // raise the "can't have multiple default attributes" diagnostic + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.MethodOverload_MultipleDefaultAttribute, method.GetLocation(), + methodArity, method.Identifier, classId)); + found |= true; + } + else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) + { + // we could see this method later with the attribute, so hold onto the diagnostic for it until we know it doesn't have the attribute + Diagnostic diagnostic = Diagnostic.Create(DiagnosticRules.MethodOverload_NeedDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classId); + overloadsWithoutAttributeMap[methodNameWithArity] = diagnostic; + } + } + else + { + // first time we're seeing the method, add a pair in the map for its name and whether it has the attribute + methodHasAttributeMap[methodNameWithArity] = hasDefaultOverloadAttribute; + } + + return found; + } + + #endregion + + #region AsyncInterfaces + /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ + static string[] ProhibitedAsyncInterfaces = { + "Windows.Foundation.IAsyncAction", + "Windows.Foundation.IAsyncActionWithProgress`1", + "Windows.Foundation.IAsyncOperation`1", + "Windows.Foundation.IAsyncOperationWithProgress`2" + }; + + /// + /// uses the proper ISymbol equality check on the OriginalDefinition of the given symbols + /// + /// true iff the two types are equivalent + private bool SameAsyncInterface(INamedTypeSymbol interfaceA, INamedTypeSymbol interfaceB) + { + /* Using OriginalDefinition b/c the generic field of the metadata type has the template name, e.g. `TProgress` + * and the actual interface will have a concrete type, e.g. `int` */ + return SymbolEqualityComparer.Default.Equals(interfaceA.OriginalDefinition, interfaceB.OriginalDefinition); + } + + /// + /// returns true if the class represented by the symbol implements any of the interfaces defined in ProhibitedAsyncInterfaces + /// + /// + /// + /// + /// True iff the given class implements any of the IAsync interfaces that are not valid in Windows Runtime + public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INamedTypeSymbol classSymbol, ClassDeclarationSyntax classDeclaration) + { + foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) + { + INamedTypeSymbol asyncInterface = context.Compilation.GetTypeByMetadataName(prohibitedInterface); + foreach (INamedTypeSymbol interfaceImplemented in classSymbol.AllInterfaces) + { + if (SameAsyncInterface(interfaceImplemented, asyncInterface)) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.AsyncRule, classDeclaration.GetLocation(), classDeclaration.Identifier, interfaceImplemented)); + return true; + /* By exiting early, we only report diagnostic for first prohibited interface we see. + If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. + could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported */ + } + } + } + return false; + } + + #endregion + + /// + /// keeps track of the arity of all constructors, and reports the diagnostic (and exits) as soon as a two constructors of the same arity are seen. + /// + /// Object to raise diagnostic on + /// look for constructors of this class + /// True if multiple constructors of the same arity exist for the given class + public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + IEnumerable constructors = classDeclaration.ChildNodes().OfType(); + + // A true entry means a constructor of that arity has been seen + Dictionary aritiesSeenSoFar = new Dictionary(); + + foreach (ConstructorDeclarationSyntax constructor in constructors) + { + int arity = constructor.ParameterList.Parameters.Count; + if (aritiesSeenSoFar.ContainsKey(arity)) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity)); + return true; + } + else + { + aritiesSeenSoFar[arity] = true; + } + } + return false; + } + + /// + /// Checks each type in the given list of types and sees if any are equal to the given type name + /// + /// + /// + /// A list of the descendent nodes that are of the given type, possibly empty. + /// empty example: this property doesnt have any qualified types in its signature + /// + /// check to see if this type appears in the signature + /// name of the class this field is in + /// syntax location + /// either property or method + /// true if the given type is the same as the one in the list + private bool SignatureContainsTypeName(ref GeneratorExecutionContext context, + IEnumerable typesInSignature, + string typeName, + SyntaxToken classId, + Location loc, + SyntaxToken fieldKind) + { + foreach (T name in typesInSignature) + { + if (name.ToString().Equals(typeName)) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArraySignature_SystemArrayRule, loc, classId, fieldKind)); + return true; + } + } + return false; + } + + /// + /// Checks to see if the class declares any operators (overloading them) + /// + /// Compilation unit + /// + /// Class to check for operator declarations + /// operator declarations are just like method declarations except they use the `operator` keyword + /// + /// True iff an operator is overloaded by the given class + public bool OverloadsOperator(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + var operatorDeclarations = classDeclaration.DescendantNodes().OfType(); + foreach (var op in operatorDeclarations) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.OperatorOverloadedRule, op.GetLocation(), op.OperatorToken)); + return true; + } + return false; + } + + #region ArraySignatureChecking + + /// + /// Looks at all the properties of the given class and checks them for improper array types (System.Array instances, multidimensional, jagged) + /// + /// + /// + /// True iff any of the invalid array types are used in any of the propertyy signatures in the given class + public bool CheckPropertiesForArrayTypes(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + bool found = false; + var props = classDeclaration.DescendantNodes().OfType().Where(PropertyIsPublic); + foreach (var prop in props) + { + var loc = prop.GetLocation(); + var propId = prop.Identifier; + var classId = classDeclaration.Identifier; + + var qualName = prop.DescendantNodes().OfType(); + found |= SignatureContainsTypeName(ref context, qualName, "System.Array", classId, loc, propId); + + var idName = prop.DescendantNodes().OfType(); + found |= SignatureContainsTypeName(ref context, idName, "Array", classId, loc, propId); + + found |= ArrayIsntOneDim(prop.DescendantNodes().OfType(), ref context, classId, propId, loc); + } + return found; + } + + /// + /// Look at all the array types and if any are of the form [][]+ or [,+] then raise the corresponding diagnostic and return true + /// + /// + /// + /// The type the array lives in + /// The code the array is a part of the signature for; e.g. property or method + /// + /// True iff any of the array types given are multidimensional or jagged + private bool ArrayIsntOneDim(IEnumerable arrTypes, ref GeneratorExecutionContext context, SyntaxToken typeIdentifier, SyntaxToken fieldId, Location loc) + { + foreach (var arrType in arrTypes) + { + var brackets = arrType.DescendantNodes().OfType(); + if (brackets.Count() > 1) // [][]+ ? + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArraySignature_JaggedArrayRule, loc, fieldId, typeIdentifier)); + return true; // could do or-eq on a `found` boolean instead of exiting as soon as we see invalid... + } + // [,_] ? + else if (brackets.Count() == 1 && brackets.First().ToString().Contains(",")) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArraySignature_MultiDimensionalArrayRule, loc, fieldId, typeIdentifier)); + return true; + } + } + return false; + } + + #endregion + + #region Parameters + + private bool ParamHasInOrOutAttribute(ParameterSyntax param) + { + string baseString = ""; //"System.Runtime.InteropServices."; + return ParamHasAttribute(baseString + "In", param) || ParamHasAttribute(baseString + "Out", param); + } + + /// + /// e.g. `int foo(out int i) { ... }` + /// + /// + /// + private bool ParamMarkedOutput(ParameterSyntax param) { return ModifiersContains(param.Modifiers, "out"); } + + /// + /// e.g. `int foo(ref int i) { ... }` + /// + /// the parameter to look for the ref keyword on + /// + private bool ParamMarkedRef(ParameterSyntax param) { return ModifiersContains(param.Modifiers, "ref"); } + + /// + /// The code generation process makes functions with output param `__retval`, + /// we will shadow a user variable named the same thing -- so raise a diagnostic instead + /// + /// compilation unit to raise diagnostic on + /// the method whose parameteres we are inspecting + /// + public bool HasConflictingParameterName(ref GeneratorExecutionContext context, MethodDeclarationSyntax method) + { + foreach (ParameterSyntax parameter in method.ParameterList.Parameters) + { + if (SyntaxTokenIs(parameter.Identifier, "__retval")) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ParameterNamedValueRule, parameter.GetLocation(), method.Identifier, parameter.Identifier)); + return true; + } + } + return false; + } + + /// + /// Checks to see if an array parameter has been marked with both Write and Read attributes + /// Does extra work, by catching `ref` params, done here since this code can be used by class or interface related methods + /// + /// + /// + /// + /// true if array attributes are invalid (see summary) + private bool CheckParamsForArrayAttributes(MethodDeclarationSyntax method, ref GeneratorExecutionContext context) + { + bool found = false; + foreach (ParameterSyntax param in method.ParameterList.Parameters) + { + var isArrayType = param.ChildNodes().OfType().Any(); + bool hasReadOnlyArray = ParamHasAttribute("ReadOnlyArray", param); + bool hasWriteOnlyArray = ParamHasAttribute("WriteOnlyArray", param); + bool isOutputParam = ParamMarkedOutput(param); + + // Nothing can be marked `ref` + if (ParamMarkedRef(param)) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.RefParameterFound, method.GetLocation(), method.Identifier, param.Identifier)); + found |= true; + } + + if (ParamHasInOrOutAttribute(param)) + { + // recommend using ReadOnlyArray or WriteOnlyArray + if (isArrayType) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier)); + found |= true; + } + // if not array type, stil can't use [In] or [Out] + else + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.NonArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier)); + found |= true; + } + } + + if (isArrayType) + { + // can't be both ReadOnly and WriteOnly + if (hasReadOnlyArray && hasWriteOnlyArray) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArrayParamMarkedBoth, method.GetLocation(), method.Identifier, param.Identifier)); + found |= true; + } + // can't be both output (writeonly) and marked read only + else if (hasReadOnlyArray && isOutputParam) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArrayOutputParamMarkedRead, method.GetLocation(), method.Identifier, param.Identifier)); + found |= true; + } + // must have some indication of ReadOnly or WriteOnly + else if (!hasWriteOnlyArray && !hasReadOnlyArray && !isOutputParam) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArrayParamNotMarked, method.GetLocation(), method.Identifier, param.Identifier + , hasWriteOnlyArray, hasReadOnlyArray, isOutputParam)); + found |= true; + } + } + // Non-array types shouldn't have attributes meant for arrays + else if (hasWriteOnlyArray || hasReadOnlyArray) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.NonArrayMarked, method.GetLocation(), method.Identifier, param.Identifier)); + found |= true; + } + } + + return found; + } + +#endregion + + #region CheckingMethods + + /// + /// Loops over each method declared in the given class and checks for various diagnostics + /// + /// + /// + /// True iff any of the diagnostics checked for are found. + public bool ClassHasInvalidMethods(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + { + bool found = false; + IEnumerable methods = classDeclaration.ChildNodes().OfType(); + + Dictionary methodsHasAttributeMap = new Dictionary(); + + /* we can't throw the diagnostic as soon as we see a second overload without an attribute, + * as there could be a third overload with the default attribute + * we use this map to keep track of these cases, and after we have checked all methods, + * we check the elements of the map to raise diagnostics for those that didn't get attributed */ + Dictionary overloadsWithoutAttributeMap = new Dictionary(); + + foreach (MethodDeclarationSyntax method in methods.Where(MethodIsPublic)) + { + found |= CheckParamsForArrayAttributes(method, ref context); + + /* Gather information on overloaded methods; make sure there is only one marked DefaultOverload */ + found |= CheckOverloadAttributes(method, ref methodsHasAttributeMap, ref overloadsWithoutAttributeMap, classDeclaration.Identifier, ref context); + + /* make sure no parameter has the name "__retval" */ + found |= HasConflictingParameterName(ref context, method); + + /* see if method signature contains the types System.Array or Array */ + var qualName = method.DescendantNodes().OfType(); + found |= SignatureContainsTypeName(ref context, qualName, "System.Array", classDeclaration.Identifier, method.GetLocation(), method.Identifier); + + var idName = method.DescendantNodes().OfType(); + found |= SignatureContainsTypeName(ref context, idName, "Array", classDeclaration.Identifier, method.GetLocation(), method.Identifier); + + found |= ArrayIsntOneDim(method.DescendantNodes().OfType(), ref context, classDeclaration.Identifier, method.Identifier, method.GetLocation()); + } + + /* Finishes up the work started by `CheckOverloadAttributes` */ + foreach (var thing in overloadsWithoutAttributeMap) + { + context.ReportDiagnostic(thing.Value); + found |= true; + } + return found; + } + + /// + /// Looks at all the methods declared on the given interface and checks them for improper array types (System.Array instances, multidimensional, jagged) + /// + /// + /// + /// True iff any of the invalid array types are used in any of the method signatures on the given interface + public bool InterfaceHasInvalidMethods(ref GeneratorExecutionContext context, InterfaceDeclarationSyntax interfaceDeclaration) + { + bool found = false; + var methodDeclarations = interfaceDeclaration.DescendantNodes().OfType(); + foreach (var method in methodDeclarations) + { + var loc = method.GetLocation(); + var methodId = method.Identifier; + var interfaceId = interfaceDeclaration.Identifier; + + var qualifiedNames = method.DescendantNodes().OfType(); + found |= SignatureContainsTypeName(ref context, qualifiedNames, "System.Array", interfaceId, loc, methodId); + + var identifiers = method.DescendantNodes().OfType(); + found |= SignatureContainsTypeName(ref context, identifiers, "Array", interfaceId, loc, methodId); + + found |= ArrayIsntOneDim(method.DescendantNodes().OfType(), ref context, interfaceId, methodId, loc); + + found |= CheckParamsForArrayAttributes(method, ref context); + } + return found; + } + #endregion + + #region Structs + + /* SimplifySyntaxTypeString + * returns the more common term for the given kind of syntax; used when creating a diagnostic for an invalid field in a struct */ + private string SimplifySyntaxTypeString(string syntaxType) + { + switch (syntaxType) + { + case "EventFieldDeclarationSyntax": + return "event"; + case "ConstructorDeclarationSyntax": + return "constructor"; + case "DelegateDeclarationSyntax": + return "delegate"; + case "IndexerDeclarationSyntax": + return "indexer"; + case "MethodDeclarationSyntax": + return "method"; + case "OperatorDeclarationSyntax": + return "operator"; + case "PropertyDeclarationSyntax": + return "property"; + default: + return "unknown syntax type: " + syntaxType; + } + } + + /// + /// returns true iff there is a field of the given type in the given struct + /// e.g., if T is PropertyDeclarationSyntax, then if the struct has a property, we report a diagnostic and return true */ + /// + /// T can vary over MethodDeclartion, EventDeclaration, etc... + /// + /// + /// + public bool StructHasFieldOfType(ref GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) + { + if (structDeclaration.DescendantNodes().OfType().Any()) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructHasInvalidFieldRule2, + structDeclaration.GetLocation(), + structDeclaration.Identifier, + SimplifySyntaxTypeString(typeof(T).Name))); + return true; + } + return false; + } + + /// + /// returns true if there is a field declared private, + /// or (inclusive) declared with a type that is a class or one of object, byte or dynamic + /// + /// True if the struct has a field of an type that is not supported in Windows Runtime + public bool StructHasFieldOfInvalidType(ref GeneratorExecutionContext context, + FieldDeclarationSyntax field, + StructDeclarationSyntax structDeclaration, + List classNames) + { + bool found = false; + + /* No private fields allowed in Windows Runtime components */ + if (!ModifiersContains(field.Modifiers, "public")) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); + found |= true; + } + + if (ModifiersContains(field.Modifiers, "const")) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructHasConstFieldRule, field.GetLocation(), structDeclaration.Identifier)); + found |= true; + } + + foreach (var variable in field.DescendantNodes().OfType()) + { + var typeStr = variable.Type.ToString(); + + List invalidTypes = new List { "object", "dynamic" }; + invalidTypes.AddRange(classNames); + + if (invalidTypes.Contains(typeStr)) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructHasInvalidFieldRule, + variable.GetLocation(), + structDeclaration.Identifier, + field.ToString(), + typeStr)); + found |= true; + } + } + return found; + } + + #endregion + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index 4cc0fca6c..67eb96f63 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -160,13 +160,13 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) classNames.Add(classDeclaration.Identifier.ToString()); /* exports multidimensional array */ - found |= winrtRules.Class_CheckArraySignature(ref context, classDeclaration); + found |= winrtRules.CheckPropertiesForArrayTypes(ref context, classDeclaration); /* exposes an operator overload */ found |= winrtRules.OverloadsOperator(ref context, classDeclaration); /* parameters named __retval*/ - found |= winrtRules.HasErrorsInMethods(ref context, classDeclaration); + found |= winrtRules.ClassHasInvalidMethods(ref context, classDeclaration); /* multiple constructors of the same arity */ found |= winrtRules.HasMultipleConstructorsOfSameArity(ref context, classDeclaration); @@ -178,7 +178,7 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) foreach (InterfaceDeclarationSyntax interfaceDeclaration in interfaces) { - found |= winrtRules.Interface_CheckArraySignature(ref context, interfaceDeclaration); + found |= winrtRules.InterfaceHasInvalidMethods(ref context, interfaceDeclaration); } /* Check all structs */ From ea9bfc5dc10bf6207a90a040a2cce7de5bad7a85 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 15 Dec 2020 00:58:46 -0800 Subject: [PATCH 29/41] midway through changing unittests * fix async interface check to have more accurate condition * cherry-pick the array attributes * removing workaround * moving tests to new style (about half done) --- .../DiagnosticTests.Helpers.cs | 52 ++ .../DiagnosticTests/DiagnosticTests.csproj | 20 + .../DiagnosticTests/UnitTestDiagnostics.cs | 773 ++++++++++++++++++ .../TestDiagnostics/ArrayParameterTests.cs | 132 --- .../TestDiagnostics/AsyncInterfaceTests.cs | 127 --- .../JaggedArraySignatureTests.cs | 7 +- .../TestDiagnostics/NamespaceTests.cs | 47 ++ .../NonZeroLowerBoundArraySignatureTests.cs | 125 ++- src/Authoring/TestDiagnostics/Scenarios.cs | 60 -- .../StructField_StructInNamespaceTests.cs | 118 --- .../TestDiagnostics/TestDiagnostics.csproj | 3 +- .../WinRT.SourceGenerator/DiagnosticRules.cs | 7 - .../WinRT.SourceGenerator/DiagnosticUtils.cs | 57 +- .../WinRT.SourceGenerator/Generator.cs | 50 +- src/cswinrt.sln | 22 + 15 files changed, 1074 insertions(+), 526 deletions(-) create mode 100644 src/Authoring/DiagnosticTests/DiagnosticTests.Helpers.cs create mode 100644 src/Authoring/DiagnosticTests/DiagnosticTests.csproj create mode 100644 src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs delete mode 100644 src/Authoring/TestDiagnostics/ArrayParameterTests.cs delete mode 100644 src/Authoring/TestDiagnostics/AsyncInterfaceTests.cs create mode 100644 src/Authoring/TestDiagnostics/NamespaceTests.cs delete mode 100644 src/Authoring/TestDiagnostics/Scenarios.cs delete mode 100644 src/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs diff --git a/src/Authoring/DiagnosticTests/DiagnosticTests.Helpers.cs b/src/Authoring/DiagnosticTests/DiagnosticTests.Helpers.cs new file mode 100644 index 000000000..d8239e58b --- /dev/null +++ b/src/Authoring/DiagnosticTests/DiagnosticTests.Helpers.cs @@ -0,0 +1,52 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using NUnit.Framework; +using System.Collections.Immutable; +using System.Linq; +using System.Reflection; + +namespace DiagnosticTests +{ + public partial class TestDiagnostics + { + /// + /// CreateCompilation creates a CSharpCompilation + /// + /// string of source code + /// + public static Compilation CreateCompilation(string source) + => CSharpCompilation.Create( + assemblyName: "compilation", + syntaxTrees: new[] { CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Preview)) }, + references: new[] { MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location) }, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + + /// + /// CreateDriver makes a CSharpGeneratorDriver + /// + /// + /// + /// + public static GeneratorDriver CreateDriver(Compilation compilation, params ISourceGenerator[] generators) + => CSharpGeneratorDriver.Create( + generators: ImmutableArray.Create(generators), + additionalTexts: ImmutableArray.Empty, + parseOptions: (CSharpParseOptions)compilation.SyntaxTrees.First().Options, + optionsProvider: null); // todo: pass the CsWinRTComponent config option here so we don't have to comment out the check in the source generator + + + /// + /// RunGenerators makes a driver and applies the given generators to the compilation, storing diagnostics in an out param + /// + /// + /// + /// + /// + public static Compilation RunGenerators(Compilation compilation, out ImmutableArray diagnostics, params ISourceGenerator[] generators) + { + CreateDriver(compilation, generators).RunGeneratorsAndUpdateCompilation(compilation, out var updatedCompilation, out diagnostics); + return updatedCompilation; + } + } +} diff --git a/src/Authoring/DiagnosticTests/DiagnosticTests.csproj b/src/Authoring/DiagnosticTests/DiagnosticTests.csproj new file mode 100644 index 000000000..57dc7acde --- /dev/null +++ b/src/Authoring/DiagnosticTests/DiagnosticTests.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + + diff --git a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs new file mode 100644 index 000000000..b321f3841 --- /dev/null +++ b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs @@ -0,0 +1,773 @@ +using NUnit.Framework; +using Microsoft.CodeAnalysis; +using WinRT.SourceGenerator; +using System.Collections.Immutable; +using System.Collections.Generic; +using System.Linq; + +namespace DiagnosticTests +{ + + /* + * todo fix the `using` statement, based on Mano's PR comment + * ******************** + + private const string StructWithWinRTField = @" +using Some.Namespace +namespace Test +{ +public struct StructWithWinRTStructField + { + public Matrix3x2 matrix; + } +}"; + */ + + [TestFixture] + public partial class TestDiagnostics + { + + /// + /// CheckNoDiagnostic asserts that no diagnostics are raised on the + /// compilation produced from the cswinrt source generator based on the given source code + /// + /// Add unit tests by creating a source code like this: + /// private const string MyNewTest = @"namespace Test { ... }"; + /// + /// And have a DiagnosticDescriptor for the one to check for, they live in WinRT.SourceGenerator.DiagnosticRules + /// + /// Then go to the DiagnosticValidData class here and add an entry for it + /// + /// + [Test, TestCaseSource(nameof(ValidCases))] + public void CheckNoDiagnostic(string source) + { + Compilation compilation = CreateCompilation(source); + RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); + Assert.That(diagnosticsFound.IsEmpty); + } + + /// + /// CodeHasDiagnostic takes some source code (string) and a Diagnostic descriptor, + /// it checks that a diagnostic with the same description was raised by the source generator + /// + [Test, TestCaseSource(nameof(WinRTComponentCases))] + public void CodeHasDiagnostics(string testCode, params DiagnosticDescriptor[] rules) + { + Compilation compilation = CreateCompilation(testCode); + RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); + HashSet diagDescsFound = new HashSet(); + + foreach (var d in diagnosticsFound) + { + diagDescsFound.Add(d.Descriptor); + } + + foreach (var rule in rules) + { + Assert.That(diagDescsFound.Contains(rule)); + } + } + + private static IEnumerable WinRTComponentCases + { + get + { + yield return new TestCaseData(ConstructorsOfSameArity, DiagnosticRules.ClassConstructorRule).SetName("Multiple constructors of same arity"); + yield return new TestCaseData(ImplementsIAsyncOperation, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperation"); + yield return new TestCaseData(ImplementsIAsyncOperationWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperationWithProgress"); + yield return new TestCaseData(ImplementsIAsyncAction, DiagnosticRules.AsyncRule).SetName("Implements IAsyncAction"); + yield return new TestCaseData(ImplementsIAsyncActionWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncActionWithProgress"); + yield return new TestCaseData(TestArrayParamAttrUnary_1, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrUnary_1"); + yield return new TestCaseData(TestArrayParamAttrUnary_2, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrUnary_2"); + yield return new TestCaseData(TestArrayParamAttrUnary_3, DiagnosticRules.ArrayOutputParamMarkedRead).SetName("TestArrayParamAttrUnary_3"); + yield return new TestCaseData(TestArrayParamAttrUnary_4, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_4"); + yield return new TestCaseData(TestArrayParamAttrUnary_5, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_5"); + yield return new TestCaseData(TestArrayParamAttrUnary_6, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrUnary_6"); + yield return new TestCaseData(TestArrayParamAttrUnary_7, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrUnary_7"); + yield return new TestCaseData(TestArrayParamAttrUnary_8, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_8"); + yield return new TestCaseData(TestArrayParamAttrUnary_9, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_9"); + yield return new TestCaseData(TestArrayParamAttrUnary_10, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrUnary_10"); + yield return new TestCaseData(TestArrayParamAttrBinary_1, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_1"); + yield return new TestCaseData(TestArrayParamAttrBinary_2, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_2"); + yield return new TestCaseData(TestArrayParamAttrBinary_3, DiagnosticRules.ArrayOutputParamMarkedRead).SetName("TestArrayParamAttrBinary_3"); + yield return new TestCaseData(TestArrayParamAttrBinary_4, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_4"); + yield return new TestCaseData(TestArrayParamAttrBinary_5, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_5"); + yield return new TestCaseData(TestArrayParamAttrBinary_6, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_6"); + yield return new TestCaseData(TestArrayParamAttrBinary_7, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_7"); + yield return new TestCaseData(TestArrayParamAttrBinary_8, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_8"); + yield return new TestCaseData(TestArrayParamAttrBinary_9, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_9"); + yield return new TestCaseData(TestArrayParamAttrBinary_10, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrBinary_10"); + yield return new TestCaseData(TestArrayParamAttrBinary_11, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_11"); + yield return new TestCaseData(TestArrayParamAttrBinary_12, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_12"); + yield return new TestCaseData(TestArrayParamAttrBinary_13, DiagnosticRules.ArrayOutputParamMarkedRead).SetName("TestArrayParamAttrBinary_13"); + yield return new TestCaseData(TestArrayParamAttrBinary_14, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_14"); + yield return new TestCaseData(TestArrayParamAttrBinary_15, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_15"); + yield return new TestCaseData(TestArrayParamAttrBinary_16, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_16"); + yield return new TestCaseData(TestArrayParamAttrBinary_17, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrBinary_17"); + yield return new TestCaseData(TestArrayParamAttrBinary_18, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_18"); + yield return new TestCaseData(TestArrayParamAttrBinary_19, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_19"); + yield return new TestCaseData(TestArrayParamAttrBinary_20, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_20"); + yield return new TestCaseData(TestArrayParamAttrBinary_21, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_21"); + yield return new TestCaseData(TestArrayParamAttrBinary_22, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_22"); + yield return new TestCaseData(TestArrayParamAttrBinary_23, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_23"); + yield return new TestCaseData(TestArrayParamAttrBinary_24, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrBinary_24"); + yield return new TestCaseData(DunderRetValParam, DiagnosticRules.ParameterNamedValueRule).SetName("Test Parameter Name Conflict (__retval)"); + yield return new TestCaseData(OperatorOverload_Class, DiagnosticRules.OperatorOverloadedRule).SetName("Test Overload of Operator"); + yield return new TestCaseData(RefParam_ClassMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Class"); + yield return new TestCaseData(RefParam_InterfaceMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Interface"); + yield return new TestCaseData(StructWithClassField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Class Field"); + yield return new TestCaseData(StructWithDelegateField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Delegate Field"); + yield return new TestCaseData(StructWithIndexer, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Indexer Field"); + yield return new TestCaseData(StructWithMethods, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Method Field"); + yield return new TestCaseData(StructWithConst, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Const Field"); + yield return new TestCaseData(StructWithProperty, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Property Field"); + yield return new TestCaseData(StructWithPrivateField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Private Field"); + yield return new TestCaseData(StructWithObjectField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Object Field"); + yield return new TestCaseData(StructWithDynamicField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Dynamic Field"); + yield return new TestCaseData(StructWithByteField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Byte Field"); + yield return new TestCaseData(StructWithConstructor, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Constructor Field"); + } + } + + #region ValidTests + + private static IEnumerable ValidCases + { + get + { + yield return new TestCaseData(Valid_ArrayParamAttrUnary_1).SetName("Valid - ArrayParamAttrUnary_1"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_2).SetName("Valid - ArrayParamAttrUnary_2"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_3).SetName("Valid - ArrayParamAttrUnary_3"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_4).SetName("Valid - ArrayParamAttrUnary_4"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_5).SetName("Valid - ArrayParamAttrUnary_5"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_1).SetName("Valid - ArrayParamAttrBinary_1"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_2).SetName("Valid - ArrayParamAttrBinary_2"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_3).SetName("Valid - ArrayParamAttrBinary_3"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_4).SetName("Valid - ArrayParamAttrBinary_4"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_5).SetName("Valid - ArrayParamAttrBinary_5"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_6).SetName("Valid - ArrayParamAttrBinary_6"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_7).SetName("Valid - ArrayParamAttrBinary_7"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_8).SetName("Valid - ArrayParamAttrBinary_8"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_9).SetName("Valid - ArrayParamAttrBinary_9"); + yield return new TestCaseData(StructWithAllValidFields).SetName("Valid - Struct with only fields of basic types"); + } + } + + private const string Valid_ArrayParamAttrUnary_1 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public int GetSum([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } +}"; + private const string Valid_ArrayParamAttrUnary_2 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrUnary_3 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrUnary_4 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrUnary_5 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void ArrayNotMarked_Valid(out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_1 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public int GetSum(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } +}"; + private const string Valid_ArrayParamAttrBinary_2 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void MarkedWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_3 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void MarkedOutAndWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_4 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void MarkedOutOnly_Valid(int i, out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_5 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void ArrayNotMarked_Valid(int i, out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_6 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedReadOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_7 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_8 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_9 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedOut_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, out int[] arr) { arr = new int[] { }; } + } +}"; + private const string StructWithAllValidFields = @" +namespace Test +{ + public struct StructWithAllValidFields + { + bool boolean; + char character; + decimal dec; + double dbl; + float flt; + int i; + uint nat; + long lng; + ulong ulng; + short sh; + ushort us; + string str; + } +}"; + + #endregion + + #region DataTests + + private const string StructWithByteField = @" +namespace Test +{ +public struct StructWithByteField_Valid + { + public byte b; + } +}"; + private const string StructWithConstructor = @" + namespace Test +{ + public struct StructWithConstructor_Invalid + { + int X; + StructWithConstructor_Invalid(int x) + { + X = x; + } + } +} "; + private const string StructWithClassField = @" +namespace Test +{ + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + + public SillyClass() { } + } + + public struct StructWithClass_Invalid + { + public SillyClass classField; + } +}"; + private const string StructWithDelegateField = @" +namespace Test { +public struct StructWithDelegate_Invalid + { + public delegate int ADelegate(int x); + } +}"; + private const string ConstructorsOfSameArity = @" +namespace TestNamespace +{ +public sealed class SameArityConstructors +{ + private int num; + private string word; + + public SameArityConstructors(int i) + { + num = i; + word = ""dog""; + } + + public SameArityConstructors(string s) + { + num = 38; + word = s; + } +} +}"; + private const string ImplementsIAsyncOperationWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperationWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ImplementsIAsyncActionWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ +public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ImplementsIAsyncOperation = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ImplementsIAsyncAction = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class AsyAction : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string TestArrayParamAttrUnary_1 = @" +public sealed class OnlyParam +{ + public void BothAttributes_Separate([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_2 = @" +public sealed class OnlyParam +{ + public void BothAttributes_Together([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_3 = @" +public sealed class OnlyParam +{ + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } +}"; + private const string TestArrayParamAttrUnary_4 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedIn([In] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_5 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedOut([Out] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_6 = @" +public sealed class OnlyParam +{ + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrUnary_7 = @" +public sealed class OnlyParam +{ + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrUnary_8 = @" +public sealed class OnlyParam +{ + public void ParamMarkedIn([In] int arr) { } +}"; + private const string TestArrayParamAttrUnary_9 = @" +public sealed class OnlyParam +{ + public void ParamMarkedOut([Out] int arr) { } +}"; + private const string TestArrayParamAttrUnary_10 = @" +public sealed class OnlyParam +{ + public void ArrayNotMarked(int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_1 = @" +public sealed class TwoParam +{ + public void BothAttributes_Separate(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_2 = @" +public sealed class TwoParam +{ + public void BothAttributes_Together(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_3 = @" +public sealed class TwoParam +{ + public void MarkedOutAndReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } +}"; + private const string TestArrayParamAttrBinary_4 = @" +public sealed class TwoParam +{ + public void ArrayMarkedIn(int i, [In] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_5 = @" +public sealed class TwoParam +{ + public void ArrayMarkedOut(int i, [Out] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_6 = @" +public sealed class TwoParam +{ + public void NonArrayMarkedReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrBinary_7 = @" +public sealed class TwoParam +{ + public void NonArrayMarkedWriteOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrBinary_8 = @" +public sealed class TwoParam +{ + public void ParamMarkedIn(int i, [In] int arr) { } +}"; + private const string TestArrayParamAttrBinary_9 = @" +public sealed class TwoParam +{ + public void ParamMarkedOut(int i, [Out] int arr) { } +}"; + private const string TestArrayParamAttrBinary_10 = @" +public sealed class TwoParam +{ + public void ArrayNotMarked(int i, int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_11 = @" +public sealed class TwoArray +{ + public void OneValidOneInvalid_1( +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] +[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] ys) { } +}"; + private const string TestArrayParamAttrBinary_12 = @" +public sealed class TwoArray +{ + public void OneValidOneInvalid_2( +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] +[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] ys) { } +}"; + private const string TestArrayParamAttrBinary_13 = @" +public sealed class TwoArray +{ + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } +}"; + private const string TestArrayParamAttrBinary_14 = @" +public sealed class TwoParam +{ + public void ArrayMarkedIn(int i, [In] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_15 = @" +public sealed class TwoArray +{ + public void ArrayMarkedIn2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_16 = @" +public sealed class TwoArray +{ + public void ArrayMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_17 = @" +public sealed class TwoArray +{ + public void ArrayNotMarked(int i, int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_18 = @" +public sealed class TwoArray +{ + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i) { } +}"; + private const string TestArrayParamAttrBinary_19 = @" +public sealed class TwoArray +{ + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int i) { } +}"; + private const string TestArrayParamAttrBinary_20 = @" +public sealed class TwoArray +{ + public void NonArrayMarkedWriteOnly2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_21 = @" +public sealed class TwoArray +{ + public void ParamMarkedIn([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int arr) { } +}"; + private const string TestArrayParamAttrBinary_22 = @" +public sealed class TwoArray +{ + public void ParamMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int arr) { } +}"; + private const string TestArrayParamAttrBinary_23 = @" +public sealed class TwoArray +{ + public void ParamMarkedOut2([Out] int arr, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs) { } +}"; + private const string TestArrayParamAttrBinary_24 = @" +public sealed class TwoArray +{ + public void ArrayNotMarked([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, int[] arr) { } +}"; + private const string RefParam_InterfaceMethod = @" +public interface IHaveAMethodWithRefParam + { + void foo(ref int i); + } +"; + private const string RefParam_ClassMethod = @" +public sealed class ClassWithMethodUsingRefParam + { + public void MethodWithRefParam(ref int i) { i++; } + } +"; + private const string OperatorOverload_Class = @" + public sealed class ClassThatOverloadsOperator + { + public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) + { + return thing; + } + }"; + private const string DunderRetValParam = @" +public sealed class ParameterNamedDunderRetVal + { + public int Identity(int __retval) + { + return __retval; + } + } +"; + private const string StructWithIndexer = @" +namespace Test +{ +public struct StructWithIndexer_Invalid + { + int[] arr; + int this[int i] => arr[i]; + } +}"; + private const string StructWithMethods = @" +namespace Test +{ +public struct StructWithMethods_Invalid + { + int foo(int x) + { + return x; + } + } +}"; + private const string StructWithConst = @" +namespace Test +{ + public struct StructWithConst_Invalid + { + const int five = 5; + private int six; + } +}"; + private const string StructWithProperty = @" +namespace Test +{ + public enum BasicEnum + { + First = 0, + Second = 1 + } + + public struct Posn_Invalid + { + BasicEnum enumField; + + public int x { get; } + public int y { get; } + } +}"; + private const string StructWithPrivateField = @" +namespace Test +{ +public struct StructWithPrivateField_Invalid + { + const int ci = 5; + private int x; + } +}"; + private const string StructWithObjectField = @" +namespace Test +{ +public struct StructWithObjectField_Invalid + { + public object obj; + } +}"; + private const string StructWithDynamicField = @" +namespace Test +{ +public struct StructWithDynamicField_Invalid + { + public dynamic dyn; + } +}"; + + #endregion + } +} \ No newline at end of file diff --git a/src/Authoring/TestDiagnostics/ArrayParameterTests.cs b/src/Authoring/TestDiagnostics/ArrayParameterTests.cs deleted file mode 100644 index 3f05ba1a8..000000000 --- a/src/Authoring/TestDiagnostics/ArrayParameterTests.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System.Runtime.InteropServices; - -namespace TestDiagnostics -{ - /* TODO: - * what happens if you put another random attribute on an array param? - * check in WRC3 project ... - */ - public class ReadOnlyArray : System.Attribute - { - public ReadOnlyArray() { } - } - - public class WriteOnlyArray : System.Attribute - { - public WriteOnlyArray() { } - } - - /* - public interface IHaveAMethodNamedArray_Valid - { - void Array(int i); - int[] Foo(out int[] arr); - } - - public sealed class OutParam_Valid - { - public void Foo(out int[] arr) { arr = new int[] { }; } - } - - // method with `ref` param - public sealed class OnlyParam - { - // array param with both attributes - public void BothAttributes_Separate([WriteOnlyArray()][ReadOnlyArray()] int[] arr) { } - - public void BothAttributes_Together([WriteOnlyArray(), ReadOnlyArray()] int[] arr) { } - - // array marked `out` but marked with ReadOnlyArray Attribute - public void MarkedOutAndReadOnly([ReadOnlyArray()] out int[] arr) { arr = new int[] { }; } - public void MarkedReadOnly_Valid([ReadOnlyArray()] int[] arr) { } - - // Valid WriteOnlyArray Tests - public void MarkedWriteOnly_Valid([WriteOnlyArray()] int[] arr) { } - public void MarkedOutAndWriteOnly_Valid([WriteOnlyArray()] out int[] arr) { arr = new int[] { }; } - public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } - - // param is array, and marked either InAttribute or OutAttribute - // must have ReadOnlyArray or WriteOnlyArray - public void ArrayMarkedIn([In] int[] arr) { } - public void ArrayMarkedOut([Out] int[] arr) { } - - // method has param marked with ReadOnlyArray / WriteOnlyArray - // but param isnt array - public void NonArrayMarkedReadOnly([ReadOnlyArray()] int arr) { } - public void NonArrayMarkedWriteOnly([WriteOnlyArray()] int arr) { } - - // param marked InAttribute or OutAttribute , disallowed in total - public void ParamMarkedIn([In] int arr) { } - public void ParamMarkedOut([Out] int arr) { } - - // array as param but not marked either way - public void ArrayNotMarked(int[] arr) { } - - public void ArrayNotMarked_Valid(out int[] arr) { arr = new int[] { }; } - } - - public sealed class TwoParam - { - public void BothAttributes(int i, [WriteOnlyArray()][ReadOnlyArray()] int[] arr) { } - // array marked `out` but marked with ReadOnlyArray Attribute - public void MarkedOutAndReadOnly(int i, [ReadOnlyArray()] out int[] arr) { arr = new int[] { }; } - public void MarkedReadOnly_Valid(int i, [ReadOnlyArray()] int[] arr) { } - - // Valid WriteOnlyArray Tests - public void MarkedWriteOnly_Valid(int i, [WriteOnlyArray()] int[] arr) { } - public void MarkedOutAndWriteOnly_Valid(int i, [WriteOnlyArray()] out int[] arr) { arr = new int[] { }; } - public void MarkedOut_Valid(int i, out int[] arr) { arr = new int[] { }; } - - // param is array, and marked either InAttribute or OutAttribute - // must have ReadOnlyArray or WriteOnlyArray - public void ArrayMarkedIn(int i, [In] int[] arr) { } - public void ArrayMarkedOut(int i, [Out] int[] arr) { } - - // method has param marked with ReadOnlyArray / WriteOnlyArray - // but param isnt array - public void NonArrayMarkedReadOnly(int i, [ReadOnlyArray()] int arr) { } - public void NonArrayMarkedWriteOnly(int i, [WriteOnlyArray()] int arr) { } - - // param marked InAttribute or OutAttribute , disallowed in total - public void ParamMarkedIn(int i, [In] int arr) { } // hey! - public void ParamMarkedOut(int i, [Out] int arr) { } - - // array as param but not marked either way - public void ArrayNotMarked(int i, int[] arr) { } - } - - public sealed class TwoArrays - { - public void OneValidOneInvalid_1([WriteOnlyArray] int[] xs, [WriteOnlyArray()][ReadOnlyArray()] int[] ys) { } - public void OneValidOneInvalid_2([WriteOnlyArray][ReadOnlyArray()] int[] xs, [WriteOnlyArray()] int[] ys) { } - - // array marked `out` but marked with ReadOnlyArray Attribute - public void MarkedOutAndReadOnly([ReadOnlyArray()] int[] xs, [ReadOnlyArray()] out int[] arr) { arr = new int[] { }; } - public void MarkedReadOnly_Valid([ReadOnlyArray()] int[] xs, [ReadOnlyArray()] int[] arr) { } - - // Valid WriteOnlyArray Tests - public void MarkedWriteOnly_Valid([ReadOnlyArray()] int[] xs, [WriteOnlyArray()] int[] arr) { } - public void MarkedOutAndWriteOnly_Valid([ReadOnlyArray()] int[] xs, [WriteOnlyArray()] out int[] arr) { arr = new int[] { }; } - public void MarkedOut_Valid([WriteOnlyArray()] int[] xs, out int[] arr) { arr = new int[] { }; } - - // param is array, and marked either InAttribute or OutAttribute - // must have ReadOnlyArray or WriteOnlyArray - public void ArrayMarkedIn(int i, [In] int[] arr) { } - public void ArrayMarkedIn2([ReadOnlyArray()] int[] xs, [In] int[] arr) { } - public void ArrayMarkedOut([ReadOnlyArray()] int[] xs, [Out] int[] arr) { } - - // method has param marked with ReadOnlyArray / WriteOnlyArray but param isnt array - public void NonArrayMarkedReadOnly([ReadOnlyArray()] int[] xs, [ReadOnlyArray()] int i) { } - public void NonArrayMarkedWriteOnly([ReadOnlyArray()] int[] xs, [WriteOnlyArray()] int i) { } - public void NonArrayMarkedWriteOnly2([ReadOnlyArray()] int i, [WriteOnlyArray()] int[] arr) { } - - // param marked InAttribute or OutAttribute , disallowed in total - public void ParamMarkedIn([ReadOnlyArray()] int[] xs, [In] int arr) { } - public void ParamMarkedOut([ReadOnlyArray()] int[] xs, [Out] int arr) { } - public void ParamMarkedOut2([Out] int arr, [ReadOnlyArray()] int[] xs) { } - - // array as param but not marked either way - public void ArrayNotMarked([ReadOnlyArray()] int[] xs, int[] arr) { } - } - */ -} diff --git a/src/Authoring/TestDiagnostics/AsyncInterfaceTests.cs b/src/Authoring/TestDiagnostics/AsyncInterfaceTests.cs deleted file mode 100644 index e05d49ab4..000000000 --- a/src/Authoring/TestDiagnostics/AsyncInterfaceTests.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Windows.Foundation; - -namespace TestDiagnostics -{ - /* - public sealed class AsyAction : IAsyncAction, IAsyncActionWithProgress - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - - } - - public class ActionWithProgress : IAsyncActionWithProgress - { - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } - - public sealed class OpWithProgress : IAsyncOperationWithProgress - { - AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperationWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } - - public sealed class Op : IAsyncOperation - { - AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperation.GetResults() - { - throw new NotImplementedException(); - } - } - */ -} diff --git a/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs index 7466bf341..b24ebd032 100644 --- a/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs +++ b/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs @@ -6,6 +6,7 @@ namespace TestDiagnostics { + public interface IF { int id(int x); } /* * Valid tests */ @@ -51,12 +52,6 @@ public int[][][] J3_ReturnOnly() public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } } - public interface JaggedArrayTests_ValidInterface - { - int[] foo(); - bool bar([ReadOnlyArray()] int[] arr); - } - public sealed class J3PublicPrivate_Valid { private int[][][] D3_ReturnOnly() diff --git a/src/Authoring/TestDiagnostics/NamespaceTests.cs b/src/Authoring/TestDiagnostics/NamespaceTests.cs new file mode 100644 index 000000000..b3d792f14 --- /dev/null +++ b/src/Authoring/TestDiagnostics/NamespaceTests.cs @@ -0,0 +1,47 @@ +using System.Runtime.InteropServices; + +namespace TestDiagnostics +{ + namespace OtherNamespace_Valid + { + public sealed class Class1 + { + int x; + public Class1(int a) { x = a; } + } + } + + // WME1068 + public sealed class TestDiagnostics + { + bool b; + public TestDiagnostics(bool x) { b = x; } + } +} + +// WME1044 +namespace OtherNamespace +{ + public sealed class Class1 + { + int x; + + public Class1(int a) + { + x = a; + } + } +} + +// WME1067 +namespace Testdiagnostics +{ + namespace InnerNamespace + { + public sealed class Class1 + { + int x; + public Class1(int a) { x = a; } + } + } +} diff --git a/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs b/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs index 498473da9..6dbf1c1f6 100644 --- a/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs +++ b/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs @@ -1,76 +1,122 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace TestDiagnostics { - /* NZLB = non-zero lowerbound array */ + /* + * Invalid tests include public properties in public classes, public interface methods, + */ - /* - * Invalid tests include public properties in public classes, public interface methods, - */ - - /* - public sealed class NonZeroLowerBound_PublicProperty_Invalid + public sealed class ArrayInstanceProperty1 { public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } - public System.Array Arr2 + public sealed class ArrayInstanceProperty2 + { + public System.Array Arr { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } - public int[] Arr3 + public sealed class ArrayInstanceProperty3 + { + public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } - public System.Array Arr4 + public sealed class ArrayInstanceProperty4 + { + public System.Array Arr { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } } - public interface InterfaceWithNonZeroLowerBound_Invalid + public interface ArrayInstanceInterface1 { System.Array Id(System.Array arr); + } + public interface ArrayInstanceInterface2 + { void Method2(System.Array arr); + } + + public interface ArrayInstanceInterface3 + { System.Array Method3(); } - - public sealed class NZLBArraySignature_2D_Invalid - { - public System.Array Arr_2d { get; set; } - public System.Array Arr_3d { get; set; } - private System.Array PrivArr_2d { get; set; } - } + public sealed class SystemArrayProperty + { + public System.Array Arr { get; set; } + } + public sealed class SystemArrayProperty_Valid + { + private System.Array PrivArr { get; set; } + } - public sealed class NZLBPublicPublic_Invalid - { - public System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } - public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - } + public sealed class JustReturn + { + public System.Array SystemArrayMethod() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + + public sealed class UnaryAndReturn + { + public System.Array SystemArrayMethod(System.Array arr) { return arr; } + } + + public sealed class SecondInput + { + public bool SystemArrayMethod(bool a, System.Array arr) { return a; } + } + public sealed class SecondInput2 + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b) { return a; } + } + + public sealed class SecondInputAndReturnType + { + public System.Array SystemArrayMethod(bool a, System.Array arr) { return arr; } + } + + public sealed class SecondInputAndReturnType2 + { + public System.Array SystemArrayMethod(bool a, System.Array arr, bool b) { return arr; } + } + + public interface SystemArrayInReturnTypeInterface + { + public System.Array SystemArrayMethod(); + } + public interface UnaryAndReturnTypeInterface + { + public System.Array SystemArrayMethod(System.Array arr); + } + public interface SecondArgAndReturnTypeInterface + { + public System.Array SystemArrayMethod(bool a, System.Array arr); + } + public interface SecondArgInterface + { + public bool SystemArrayMethod(bool a, System.Array arr); + } + // pick up here public interface NZLBMemberOfInterface_Invalid - { - public System.Array NZLB_ReturnOnly(); - public System.Array NZLB_ReturnAndInput1(System.Array arr); - public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr); - public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr); + { public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b); + } + public interface NZLBMemberOfInterface_Invalid2 + { public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b); - } + } namespace SubNamespace { @@ -88,7 +134,9 @@ public interface SubNamespacInterface_NZLBMethods_Invalid /* * Valid tests - */ + */ + + /* public sealed class NonZeroLowerBound_PrivateProperty_Valid { private int[] PrivArr @@ -192,4 +240,5 @@ public sealed class NZLBPublicPrivate_Valid private bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } private bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } } + */ } diff --git a/src/Authoring/TestDiagnostics/Scenarios.cs b/src/Authoring/TestDiagnostics/Scenarios.cs deleted file mode 100644 index 92f5e6536..000000000 --- a/src/Authoring/TestDiagnostics/Scenarios.cs +++ /dev/null @@ -1,60 +0,0 @@ -using ABI.System.Numerics; -using ABI.Windows.ApplicationModel.Contacts; -using System; -using System.Runtime.ExceptionServices; -using Windows.Foundation; -using Windows.Foundation.Numerics; -using Windows.Security.Cryptography.Core; -using Windows.Web.Syndication; - -namespace TestDiagnostics -{ - /* - public interface IHaveAMethodWithRefParam - { - void foo(ref int i); - } - - public sealed class ClassWithMethodUsingRefParam - { - public void MethodWithRefParam(ref int i) { i++; } - } - - public sealed class ClassThatOverloadsOperator - { - public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) - { - return thing; - } - } - - public sealed class ParameterNamedDunderRetVal - { - public int Identity(int __retval) - { - return __retval; - } - } - - public sealed class SameArityConstructors - { - private int num; - private string word; - - public SameArityConstructors(int i) - { - num = i; - word = "dog"; - } - - public SameArityConstructors(string s) - { - num = 38; - word = s; - } - - // Can test that multiple constructors are allowed (has been verified already, too) - // as long as they have different arities by making one take none or 2 arguments - } - */ -} diff --git a/src/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs b/src/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs deleted file mode 100644 index 4674f117a..000000000 --- a/src/Authoring/TestDiagnostics/StructField_StructInNamespaceTests.cs +++ /dev/null @@ -1,118 +0,0 @@ -using ABI.System.Numerics; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace TestDiagnostics -{ - /* - public sealed class SillyClass - { - public double Identity(double d) - { - return d; - } - } - - public struct StructWithClass_Invalid - { - public SillyClass classField; - } - - public struct StructWithDelegate_Invalid - { - public delegate int ADelegate(int x); - } - - public struct StructWithEvent_Invalid - { - public event EventHandler EventField; - } - - public struct StructWithConstructor_Invalid - { - int X; - StructWithConstructor_Invalid(int x) - { - X = x; - } - } - - public struct StructWithIndexer_Invalid - { - int[] arr; - int this[int i] => arr[i]; - } - - public struct StructWithMethods_Invalid - { - int foo(int x) - { - return x; - } - } - - public struct StructWithConst_Invalid - { - const int five = 5; - private int six; - } - - public enum BasicEnum - { - First = 0, - Second = 1 - } - - public struct Posn_Invalid - { - BasicEnum enumField; - - public int x { get; } - public int y { get; } - } - - public struct StructWithPrivateField_Invalid - { - const int ci = 5; - private int x; - } - - public struct StructWithAllValidFields - { - bool boolean; - char character; - decimal dec; - double dbl; - float flt; - int i; - uint nat; - long lng; - ulong ulng; - short sh; - ushort us; - string str; - } - - public struct StructWithObjectField_Invalid - { - public object obj; - } - public struct StructWithDynamicField_Invalid - { - public dynamic dyn; - } - - public struct StructWithByteField_Valid - { - public byte b; - } - - public struct StructWithWinRTStructField - { - public Matrix3x2 matrix; - } - */ -} diff --git a/src/Authoring/TestDiagnostics/TestDiagnostics.csproj b/src/Authoring/TestDiagnostics/TestDiagnostics.csproj index 7376cb5f6..9c004596d 100644 --- a/src/Authoring/TestDiagnostics/TestDiagnostics.csproj +++ b/src/Authoring/TestDiagnostics/TestDiagnostics.csproj @@ -9,6 +9,7 @@ true true $([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)', '$(IntermediateOutputPath)', 'Generated Files')) + Library @@ -19,7 +20,7 @@ - + diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index d88c12221..5742f4758 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -2,13 +2,6 @@ namespace WinRT.SourceGenerator { - public class CheckEqual : System.Attribute - { - public CheckEqual(DiagnosticDescriptor d) - { - } - } - public class DiagnosticRules { /// diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index 245dc88ef..e35909e8f 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -137,21 +137,34 @@ private bool CheckOverloadAttributes(MethodDeclarationSyntax method, #region AsyncInterfaces /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ static string[] ProhibitedAsyncInterfaces = { - "Windows.Foundation.IAsyncAction", - "Windows.Foundation.IAsyncActionWithProgress`1", - "Windows.Foundation.IAsyncOperation`1", - "Windows.Foundation.IAsyncOperationWithProgress`2" + "IAsyncAction", + "IAsyncActionWithProgress`1", + "IAsyncOperation`1", + "IAsyncOperationWithProgress`2" }; - /// - /// uses the proper ISymbol equality check on the OriginalDefinition of the given symbols - /// - /// true iff the two types are equivalent - private bool SameAsyncInterface(INamedTypeSymbol interfaceA, INamedTypeSymbol interfaceB) + + private static bool ImplementsInterface(INamedTypeSymbol typeSymbol, string typeToCheck) { - /* Using OriginalDefinition b/c the generic field of the metadata type has the template name, e.g. `TProgress` - * and the actual interface will have a concrete type, e.g. `int` */ - return SymbolEqualityComparer.Default.Equals(interfaceA.OriginalDefinition, interfaceB.OriginalDefinition); + if (typeSymbol == null) + { + return false; + } + + if (typeSymbol.BaseType.MetadataName == typeToCheck) + { + return true; + } + + foreach (var implementedInterface in typeSymbol.AllInterfaces) + { + if (implementedInterface.MetadataName == typeToCheck) + { + return true; + } + } + + return false; } /// @@ -165,17 +178,13 @@ public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INam { foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) { - INamedTypeSymbol asyncInterface = context.Compilation.GetTypeByMetadataName(prohibitedInterface); - foreach (INamedTypeSymbol interfaceImplemented in classSymbol.AllInterfaces) + if (ImplementsInterface(classSymbol, prohibitedInterface)) { - if (SameAsyncInterface(interfaceImplemented, asyncInterface)) - { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.AsyncRule, classDeclaration.GetLocation(), classDeclaration.Identifier, interfaceImplemented)); - return true; - /* By exiting early, we only report diagnostic for first prohibited interface we see. - If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. - could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported */ - } + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.AsyncRule, classDeclaration.GetLocation(), classDeclaration.Identifier, prohibitedInterface)); + return true; + /* By exiting early, we only report diagnostic for first prohibited interface we see. + * If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. + * could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported */ } } return false; @@ -379,8 +388,8 @@ private bool CheckParamsForArrayAttributes(MethodDeclarationSyntax method, ref G foreach (ParameterSyntax param in method.ParameterList.Parameters) { var isArrayType = param.ChildNodes().OfType().Any(); - bool hasReadOnlyArray = ParamHasAttribute("ReadOnlyArray", param); - bool hasWriteOnlyArray = ParamHasAttribute("WriteOnlyArray", param); + bool hasReadOnlyArray = ParamHasAttribute("System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray", param); + bool hasWriteOnlyArray = ParamHasAttribute("System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray", param); bool isOutputParam = ParamMarkedOutput(param); // Nothing can be marked `ref` diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index 67eb96f63..67db4950a 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -57,7 +57,7 @@ private static string GetCsWinRTExe(GeneratorExecutionContext context) private string GetTempFolder(bool clearSourceFilesFromFolder = false) { - if(_tempFolder == null || !File.Exists(_tempFolder)) + if (_tempFolder == null || !File.Exists(_tempFolder)) { string outputDir = Path.Combine(Path.GetTempPath(), "CsWinRT", Path.GetRandomFileName()).TrimEnd('\\'); Directory.CreateDirectory(outputDir); @@ -105,7 +105,7 @@ private void GenerateSources(GeneratorExecutionContext context) Logger.Log(cswinrtProcess.StandardError.ReadToEnd()); cswinrtProcess.WaitForExit(); - foreach(var file in Directory.GetFiles(outputDir, "*.cs", SearchOption.TopDirectoryOnly)) + foreach (var file in Directory.GetFiles(outputDir, "*.cs", SearchOption.TopDirectoryOnly)) { Logger.Log("Adding " + file); context.AddSource(Path.GetFileNameWithoutExtension(file), SourceText.From(File.ReadAllText(file), Encoding.UTF8)); @@ -137,17 +137,17 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } - - private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) - { - bool found = false; - WinRTRules winrtRules = new WinRTRules(); - foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) + + private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) + { + bool found = false; + WinRTRules winrtRules = new WinRTRules(); + foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { - var model = context.Compilation.GetSemanticModel(tree); + var model = context.Compilation.GetSemanticModel(tree); var nodes = tree.GetRoot().DescendantNodes(); - - var classes = nodes.OfType().Where(winrtRules.ClassIsPublic); + + var classes = nodes.OfType().Where(winrtRules.ClassIsPublic); var interfaces = nodes.OfType().Where(winrtRules.InterfaceIsPublic); var structs = nodes.OfType(); @@ -163,14 +163,14 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) found |= winrtRules.CheckPropertiesForArrayTypes(ref context, classDeclaration); /* exposes an operator overload */ - found |= winrtRules.OverloadsOperator(ref context, classDeclaration); + found |= winrtRules.OverloadsOperator(ref context, classDeclaration); /* parameters named __retval*/ found |= winrtRules.ClassHasInvalidMethods(ref context, classDeclaration); /* multiple constructors of the same arity */ found |= winrtRules.HasMultipleConstructorsOfSameArity(ref context, classDeclaration); - + /* implementing async interfaces */ var classSymbol = model.GetDeclaredSymbol(classDeclaration); found |= winrtRules.ImplementsAsyncInterface(ref context, classSymbol, classDeclaration); @@ -202,15 +202,39 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) return found; } + private void AddArrayAttributes(ref GeneratorExecutionContext context) + { + context.AddSource("System.Runtime.InteropServices.WindowsRuntime", SourceText.From(@" +namespace System.Runtime.InteropServices.WindowsRuntime +{ + [global::System.AttributeUsage(System.AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] + internal sealed class ReadOnlyArrayAttribute : global::System.Attribute + { + } + [global::System.AttributeUsage(System.AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] + internal sealed class WriteOnlyArrayAttribute : global::System.Attribute + { + } +}", Encoding.UTF8)); + + + } + public void Execute(GeneratorExecutionContext context) { + /* Temporary workaround needed when unit testing -- need to specify + * this property on the unit test's source code's anlayzer config options + * ***** if (!IsCsWinRTComponent(context)) { return; } + */ Logger.Initialize(context); + AddArrayAttributes(ref context); + if (CatchWinRTDiagnostics(ref context)) { Logger.Log("Exiting early -- found errors in authored runtime component."); diff --git a/src/cswinrt.sln b/src/cswinrt.sln index 489f4c8e2..79f3983eb 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -94,6 +94,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_component_derived", "T {13333A6F-6A4A-48CD-865C-0F65135EB018} = {13333A6F-6A4A-48CD-865C-0F65135EB018} EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiagnosticTests", "Authoring\DiagnosticTests\DiagnosticTests.csproj", "{FC05C557-C974-4CB3-9DA7-BB5476710E91}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -460,6 +462,26 @@ Global {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Release|x64.Build.0 = Release|x64 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Release|x86.ActiveCfg = Release|Win32 {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E}.Release|x86.Build.0 = Release|Win32 + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|ARM.ActiveCfg = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|ARM.Build.0 = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|ARM64.Build.0 = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|x64.ActiveCfg = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|x64.Build.0 = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|x86.ActiveCfg = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Debug|x86.Build.0 = Debug|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|Any CPU.Build.0 = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|ARM.ActiveCfg = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|ARM.Build.0 = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|ARM64.ActiveCfg = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|ARM64.Build.0 = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|x64.ActiveCfg = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|x64.Build.0 = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|x86.ActiveCfg = Release|Any CPU + {FC05C557-C974-4CB3-9DA7-BB5476710E91}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 42e8b8752ed166b131ad98a9e3137d6cc8d1989b Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 15 Dec 2020 13:51:15 -0800 Subject: [PATCH 30/41] finish unittest migration --- src/Authoring/DiagnosticTests/NegativeData.cs | 1635 +++++++++++++++++ src/Authoring/DiagnosticTests/PositiveData.cs | 784 ++++++++ ...gnosticTests.Helpers.cs => TestHelpers.cs} | 28 +- .../DiagnosticTests/UnitTestDiagnostics.cs | 888 +++------ .../JaggedArraySignatureTests.cs | 167 -- .../TestDiagnostics/MethodOverloadTests.cs | 170 -- .../MultidimensionalArraySignatureTests.cs | 137 -- .../TestDiagnostics/NamespaceTests.cs | 47 - .../NonZeroLowerBoundArraySignatureTests.cs | 244 --- .../TestDiagnostics/TestDiagnostics.csproj | 5 +- 10 files changed, 2687 insertions(+), 1418 deletions(-) create mode 100644 src/Authoring/DiagnosticTests/NegativeData.cs create mode 100644 src/Authoring/DiagnosticTests/PositiveData.cs rename src/Authoring/DiagnosticTests/{DiagnosticTests.Helpers.cs => TestHelpers.cs} (63%) delete mode 100644 src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs delete mode 100644 src/Authoring/TestDiagnostics/MethodOverloadTests.cs delete mode 100644 src/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs delete mode 100644 src/Authoring/TestDiagnostics/NamespaceTests.cs delete mode 100644 src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs diff --git a/src/Authoring/DiagnosticTests/NegativeData.cs b/src/Authoring/DiagnosticTests/NegativeData.cs new file mode 100644 index 000000000..4b9546970 --- /dev/null +++ b/src/Authoring/DiagnosticTests/NegativeData.cs @@ -0,0 +1,1635 @@ +namespace DiagnosticTests +{ + public partial class TestDiagnostics + { + // namespace tests -- WIP + private const string _NamespaceTest1 = @" +namespace Test +{ + namespace OtherNamespace_Valid + { + public sealed class Class1 + { + int x; + public Class1(int a) { x = a; } + } + } + + // WME1068 + public sealed class TestDiagnostics + { + bool b; + public TestDiagnostics(bool x) { b = x; } + } +} +}"; + private const string _NamespaceTest2 = @" +namespace OtherNamespace +{ + +// WME1044 ? + public sealed class Class1 + { + int x; + + public Class1(int a) + { + x = a; + } + } +}"; + private const string _NamespaceTest3 = @" +namespace Test +{ +// WME1067 ?? + namespace InnerNamespace + { + public sealed class Class1 + { + int x; + public Class1(int a) { x = a; } + } + } +}"; + // multidim array + private const string MultiDim_2DProp = @" +namespace Test +{ + public sealed class MultiDim_2DProp + { + public int[,] Arr_2d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string MultiDim_3DProp = @" +namespace Test +{ + public sealed class MultiDim_3DProp + { + public int[,,] Arr_3d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + // 2d class + private const string MultiDim_2D_PublicClassPublicMethod1 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod1 + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod2 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod2 + { + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod3 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod4 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod5 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod6 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + } +}"; + // 3d class + private const string MultiDim_3D_PublicClassPublicMethod1 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod1 + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod2 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod3 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod4 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod5 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod6 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + // 2d iface + private const string MultiDim_2D_Interface1 = @" +namespace Test +{ + public interface MultiDim_2D_Interface1 + { + public int[,] D2_ReturnOnly(); + } +}"; + private const string MultiDim_2D_Interface2 = @" +namespace Test +{ + public interface MultiDim_2D_Interface2 + { + public int[,] D2_ReturnAndInput1(int[,] arr); + } +}"; + private const string MultiDim_2D_Interface3 = @" +namespace Test +{ + public interface MultiDim_2D_Interface3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + } +}"; + private const string MultiDim_2D_Interface4 = @" +namespace Test +{ + public interface MultiDim_2D_Interface4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + } +}"; + private const string MultiDim_2D_Interface5 = @" +namespace Test +{ + public interface MultiDim_2D_Interface5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + } +}"; + private const string MultiDim_2D_Interface6 = @" +namespace Test +{ + public interface MultiDim_2D_Interface6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + } +}"; + // 3d iface + private const string MultiDim_3D_Interface1 = @" +namespace Test +{ + public interface MultiDim_3D_Interface1 + { + public int[,,] D3_ReturnOnly(); + } +}"; + private const string MultiDim_3D_Interface2 = @" +namespace Test +{ + public interface MultiDim_3D_Interface2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface3 = @" +namespace Test +{ + public interface MultiDim_3D_Interface3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface4 = @" +namespace Test +{ + public interface MultiDim_3D_Interface4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + } +}"; + private const string MultiDim_3D_Interface5 = @" +namespace Test +{ + public interface MultiDim_3D_Interface5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface6 = @" +namespace Test +{ +public interface MultiDim_3D_Interface6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + +}"; + // subnamespace 2d iface + private const string SubNamespaceInterface_D2Method1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnOnly(); + } + } +}"; + private const string SubNamespaceInterface_D2Method2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput1(int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + } + } +}"; + private const string SubNamespaceInterface_D2Method5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + } + } +}"; + // subnamespace 3d iface + private const string SubNamespaceInterface_D3Method1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method1 + { + public int[,,] D3_ReturnOnly(); + } + } +}"; + private const string SubNamespaceInterface_D3Method2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + } +}"; + private const string SubNamespaceInterface_D3Method5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + } +}"; + // system array + private const string ArrayInstanceProperty1 = @" +namespace Test +{ + // this might be valid... + public sealed class ArrayInstanceProperty1 + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } +}"; + private const string ArrayInstanceProperty2 = @" +namespace Test +{ +public sealed class ArrayInstanceProperty2 + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } +}"; + private const string ArrayInstanceProperty3 = @" +namespace Test +{ + // this might be valid... + public sealed class ArrayInstanceProperty3 + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + +}"; + private const string ArrayInstanceProperty4 = @" +namespace Test +{ +public sealed class ArrayInstanceProperty4 + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } +}"; + private const string ArrayInstanceInterface1 = @" +namespace Test +{ + public interface ArrayInstanceInterface1 + { + System.Array Id(System.Array arr); + } +}"; + private const string ArrayInstanceInterface2 = @" +namespace Test +{ + public interface ArrayInstanceInterface2 + { + void Method2(System.Array arr); + } +}"; + private const string ArrayInstanceInterface3 = @" +namespace Test +{ + public interface ArrayInstanceInterface3 + { + System.Array Method3(); + } +}"; + private const string SystemArrayProperty5 = @" +namespace Test +{ + public sealed class SystemArrayProperty + { + public System.Array Arr { get; set; } + } +}"; + private const string SystemArrayJustReturn = @" +namespace Test +{ + public sealed class JustReturn + { + public System.Array SystemArrayMethod() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string SystemArrayUnaryAndReturn = @" +namespace Test +{ + public sealed class UnaryAndReturn + { + public System.Array SystemArrayMethod(System.Array arr) { return arr; } + } +}"; + private const string SystemArraySecondArgClass = @" +namespace Test +{ + public sealed class SecondArgClass + { + public bool SystemArrayMethod(bool a, System.Array arr) { return a; } + } +}"; + private const string SystemArraySecondArg2Class = @" +namespace Test +{ +public sealed class SecondArg2Class + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string SystemArraySecondArgAndReturnTypeClass = @" +namespace Test +{ + public sealed class SecondArgAndReturnType + { + public System.Array SystemArrayMethod(bool a, System.Array arr) { return arr; } + } +}"; + private const string SystemArraySecondArgAndReturnTypeClass2 = @" +namespace Test +{ + public sealed class SecondArgAndReturnTypeClass2 + { + public System.Array SystemArrayMethod(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string SystemArrayNilArgsButReturnTypeInterface = @" +namespace Test +{ +public interface NilArgsButReturnTypeInterface + { + public System.Array SystemArrayMethod(); + } +}"; + private const string SystemArrayUnaryAndReturnTypeInterface = @" +namespace Test +{ +public interface UnaryAndReturnTypeInterface + { + public System.Array SystemArrayMethod(System.Array arr); + } +}"; + private const string SystemArraySecondArgAndReturnTypeInterface = @" +namespace Test +{ +public interface SecondArgAndReturnTypeInterface + { + public System.Array SystemArrayMethod(bool a, System.Array arr); + } +}"; + private const string SystemArraySecondArgAndReturnTypeInterface2 = @" +namespace Test +{ + public interface SecondArgAndReturnTypeInterface2 + { + public System.Array SystemArrayMetho(bool a, System.Array arr, bool b); + } +}"; + private const string SystemArraySecondArgInterface = @" +namespace Test +{ + public interface SecondArgInterface + { + public bool SystemArrayMethod(bool a, System.Array arr); + } +}"; + private const string SystemArraySecondArgInterface2 = @" +namespace Test +{ +public interface SecondArgInterface2 + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b); + } +}"; + private const string SystemArraySubNamespace_ReturnOnly = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_ReturnOnly + { + public System.Array SystemArrayMethod(); + } +} +}"; + private const string SystemArraySubNamespace_ReturnAndInput1 = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_ReturnAndInput1 + { + public System.Array SystemArrayMethod(System.Array arr); + } +} +}"; + private const string SystemArraySubNamespace_ReturnAndInput2of2 = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_ReturnAndInput2of2 + { + public System.Array SystemArrayMethod(bool a, System.Array arr); + } +} +}"; + private const string SystemArraySubNamespace_ReturnAndInput2of3 = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_ReturnAndInput2of3 + { + public System.Array SystemArrayMethod(bool a, System.Array arr, bool b); + } +} +}"; + private const string SystemArraySubNamespace_NotReturnAndInput2of2 = @" +namespace Test +{ + namespace SubNamespace +{ + public interface SubNamespace_NotReturnAndInput2of2 + { + public bool SystemArrayMethod(bool a, System.Array arr); + } +} +}"; + private const string SystemArraySubNamespace_NotReturnAndInput2of3 = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_NotReturnAndInput2of3 + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b); + } +} +}"; + // struct + private const string StructWithByteField = @" +namespace Test +{ +public struct StructWithByteField_Valid + { + public byte b; + } +}"; + private const string StructWithConstructor = @" + namespace Test +{ + public struct StructWithConstructor_Invalid + { + int X; + StructWithConstructor_Invalid(int x) + { + X = x; + } + } +} "; + private const string StructWithClassField = @" +namespace Test +{ + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + + public SillyClass() { } + } + + public struct StructWithClass_Invalid + { + public SillyClass classField; + } +}"; + private const string StructWithDelegateField = @" +namespace Test { +public struct StructWithDelegate_Invalid + { + public delegate int ADelegate(int x); + } +}"; + // constructor of same arity + private const string ConstructorsOfSameArity = @" +namespace TestNamespace +{ +public sealed class SameArityConstructors +{ + private int num; + private string word; + + public SameArityConstructors(int i) + { + num = i; + word = ""dog""; + } + + public SameArityConstructors(string s) + { + num = 38; + word = s; + } +} +}"; + // async interfaces + private const string ImplementsIAsyncOperationWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperationWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ImplementsIAsyncActionWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ +public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ImplementsIAsyncOperation = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ImplementsIAsyncAction = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class AsyAction : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +}"; + // readonlyarray / writeonlyarray attribute + private const string TestArrayParamAttrUnary_1 = @" +public sealed class OnlyParam +{ + public void BothAttributes_Separate([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_2 = @" +public sealed class OnlyParam +{ + public void BothAttributes_Together([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_3 = @" +public sealed class OnlyParam +{ + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } +}"; + private const string TestArrayParamAttrUnary_4 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedIn([In] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_5 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedOut([Out] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_6 = @" +public sealed class OnlyParam +{ + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrUnary_7 = @" +public sealed class OnlyParam +{ + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrUnary_8 = @" +public sealed class OnlyParam +{ + public void ParamMarkedIn([In] int arr) { } +}"; + private const string TestArrayParamAttrUnary_9 = @" +public sealed class OnlyParam +{ + public void ParamMarkedOut([Out] int arr) { } +}"; + private const string TestArrayParamAttrUnary_10 = @" +public sealed class OnlyParam +{ + public void ArrayNotMarked(int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_1 = @" +public sealed class TwoParam +{ + public void BothAttributes_Separate(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_2 = @" +public sealed class TwoParam +{ + public void BothAttributes_Together(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_3 = @" +public sealed class TwoParam +{ + public void MarkedOutAndReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } +}"; + private const string TestArrayParamAttrBinary_4 = @" +public sealed class TwoParam +{ + public void ArrayMarkedIn(int i, [In] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_5 = @" +public sealed class TwoParam +{ + public void ArrayMarkedOut(int i, [Out] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_6 = @" +public sealed class TwoParam +{ + public void NonArrayMarkedReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrBinary_7 = @" +public sealed class TwoParam +{ + public void NonArrayMarkedWriteOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrBinary_8 = @" +public sealed class TwoParam +{ + public void ParamMarkedIn(int i, [In] int arr) { } +}"; + private const string TestArrayParamAttrBinary_9 = @" +public sealed class TwoParam +{ + public void ParamMarkedOut(int i, [Out] int arr) { } +}"; + private const string TestArrayParamAttrBinary_10 = @" +public sealed class TwoParam +{ + public void ArrayNotMarked(int i, int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_11 = @" +public sealed class TwoArray +{ + public void OneValidOneInvalid_1( +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] +[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] ys) { } +}"; + private const string TestArrayParamAttrBinary_12 = @" +public sealed class TwoArray +{ + public void OneValidOneInvalid_2( +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] +[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] ys) { } +}"; + private const string TestArrayParamAttrBinary_13 = @" +public sealed class TwoArray +{ + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } +}"; + private const string TestArrayParamAttrBinary_14 = @" +public sealed class TwoParam +{ + public void ArrayMarkedIn(int i, [In] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_15 = @" +public sealed class TwoArray +{ + public void ArrayMarkedIn2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_16 = @" +public sealed class TwoArray +{ + public void ArrayMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_17 = @" +public sealed class TwoArray +{ + public void ArrayNotMarked(int i, int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_18 = @" +public sealed class TwoArray +{ + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i) { } +}"; + private const string TestArrayParamAttrBinary_19 = @" +public sealed class TwoArray +{ + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int i) { } +}"; + private const string TestArrayParamAttrBinary_20 = @" +public sealed class TwoArray +{ + public void NonArrayMarkedWriteOnly2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_21 = @" +public sealed class TwoArray +{ + public void ParamMarkedIn([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int arr) { } +}"; + private const string TestArrayParamAttrBinary_22 = @" +public sealed class TwoArray +{ + public void ParamMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int arr) { } +}"; + private const string TestArrayParamAttrBinary_23 = @" +public sealed class TwoArray +{ + public void ParamMarkedOut2([Out] int arr, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs) { } +}"; + private const string TestArrayParamAttrBinary_24 = @" +public sealed class TwoArray +{ + public void ArrayNotMarked([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, int[] arr) { } +}"; + // ref param + private const string RefParam_InterfaceMethod = @" +public interface IHaveAMethodWithRefParam + { + void foo(ref int i); + } +"; + private const string RefParam_ClassMethod = @" +public sealed class ClassWithMethodUsingRefParam + { + public void MethodWithRefParam(ref int i) { i++; } + } +"; + // operator overload + private const string OperatorOverload_Class = @" + public sealed class ClassThatOverloadsOperator + { + public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) + { + return thing; + } + }"; + // param name conflict + private const string DunderRetValParam = @" +public sealed class ParameterNamedDunderRetVal + { + public int Identity(int __retval) + { + return __retval; + } + } +"; + // struct fields + private const string StructWithIndexer = @" +namespace Test +{ +public struct StructWithIndexer_Invalid + { + int[] arr; + int this[int i] => arr[i]; + } +}"; + private const string StructWithMethods = @" +namespace Test +{ +public struct StructWithMethods_Invalid + { + int foo(int x) + { + return x; + } + } +}"; + private const string StructWithConst = @" +namespace Test +{ + public struct StructWithConst_Invalid + { + const int five = 5; + private int six; + } +}"; + private const string StructWithProperty = @" +namespace Test +{ + public enum BasicEnum + { + First = 0, + Second = 1 + } + + public struct Posn_Invalid + { + BasicEnum enumField; + + public int x { get; } + public int y { get; } + } +}"; + private const string StructWithPrivateField = @" +namespace Test +{ +public struct StructWithPrivateField_Invalid + { + const int ci = 5; + private int x; + } +}"; + private const string StructWithObjectField = @" +namespace Test +{ +public struct StructWithObjectField_Invalid + { + public object obj; + } +}"; + private const string StructWithDynamicField = @" +namespace Test +{ +public struct StructWithDynamicField_Invalid + { + public dynamic dyn; + } +}"; + // DefaultOverload attribute tests + private const string TwoOverloads_NoAttribute = @" +namespace Test +{ + public sealed class TwoOverloads_NoAttribute + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInList = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInList + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_NoAttribute_OneIrrevAttr = @" +namespace Test +{ + public sealed class TwoOverloads_NoAttribute_OneIrrevAttr + { + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInList = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInList + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_TwoLists = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_TwoLists + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInSeparateList = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInSeparateList + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute + { + + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string ThreeOverloads_TwoAttributes = @" +namespace Test +{ + public sealed class ThreeOverloads_TwoAttributes + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } +}"; + // jagged 2d/3d prop + private const string Jagged2D_Property1 = @" +namespace Test +{ + public sealed class Jagged2D_Property1 + { + private int[][] ArrP { get; set; } + } +}"; + private const string Jagged2D_Property2 = @" +namespace Test +{ + public sealed class Jagged2D_Property2 + { + public int[][] Arr { get; set; } + } +}"; + private const string Jagged3D_Property1 = @" +namespace Test +{ + public sealed class Jagged3D_Property1 + { + public int[][][] Arr3 { get; set; } + } +}"; + private const string Jagged3D_Property2 = @" +namespace Test +{ + public sealed class Jagged3D_Property2 + { + private int[][][] Arr3P { get; set; } + } +}"; + // jagged 2d class method + private const string Jagged2D_ClassMethod1 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod1 + { + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + + } +}"; + private const string Jagged2D_ClassMethod2 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod2 + { + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + } +}"; + private const string Jagged2D_ClassMethod3 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + } +}"; + private const string Jagged2D_ClassMethod4 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + } +}"; + private const string Jagged2D_ClassMethod5 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + } +}"; + private const string Jagged2D_ClassMethod6 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } + } +}"; + // jagged 3d class method + private const string Jagged3D_ClassMethod1 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod1 + { + public int[][][] J3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + + } +}"; + private const string Jagged3D_ClassMethod2 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod1 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod3 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod4 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod5 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + } +}"; + private const string Jagged3D_ClassMethod6 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + // jagged 2d interface method + private const string Jagged2D_InterfaceMethod1 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod1 + { + public int[][] J2_ReturnOnly(); + } +}"; + private const string Jagged2D_InterfaceMethod2 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod2 + { + public int[][] J2_ReturnAndInput1(int[,] arr); + } +}"; + private const string Jagged2D_InterfaceMethod3 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + } +}"; + private const string Jagged2D_InterfaceMethod4 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + } +}"; + private const string Jagged2D_InterfaceMethod5 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + } +}"; + private const string Jagged2D_InterfaceMethod6 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); + } +}"; + // jagged 2d interface method + private const string Jagged3D_InterfaceMethod1 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod1 + { + public int[][][] J3_ReturnOnly(); + } +}"; + private const string Jagged3D_InterfaceMethod2 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod2 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod3 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod4 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + } +}"; + private const string Jagged3D_InterfaceMethod5 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod6 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } +}"; + // subnamespace jagged 2d iface + private const string SubNamespace_Jagged2DInterface1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface1 + { + public int[][] J2_ReturnOnly(); + } + } +}"; + private const string SubNamespace_Jagged2DInterface2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface2 + { + public int[][] J2_ReturnAndInput1(int[,] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + } + } +}"; + private const string SubNamespace_Jagged2DInterface6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); + } + } +}"; + // subnamespace jagged 3d iface + private const string SubNamespace_Jagged3DInterface1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface1 + { + public int[][][] J3_ReturnOnly(); + } + } +}"; + private const string SubNamespace_Jagged3DInterface2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface2 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + } +}"; + private const string SubNamespace_Jagged3DInterface5 = @" +namespace Test +{ + namespace SubNamespace + + { + public interface SubNamespace_Jagged3DInterface5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + } +}"; + } +} diff --git a/src/Authoring/DiagnosticTests/PositiveData.cs b/src/Authoring/DiagnosticTests/PositiveData.cs new file mode 100644 index 000000000..6f1a1c40e --- /dev/null +++ b/src/Authoring/DiagnosticTests/PositiveData.cs @@ -0,0 +1,784 @@ +namespace DiagnosticTests +{ + public partial class TestDiagnostics + { + // TODO: get the proper namespace for the Matrix3x2 type + private const string Valid_StructWithWinRTField = @" +using ABI.System.Numerics; +namespace Test +{ + public struct StructWithWinRTStructField + { + public Matrix3x2 matrix; + } +}"; + // ** DefaultOverload attribute + private const string Valid_TwoOverloads_DiffParamCount = @" +namespace Test +{ + public sealed class Valid_TwoOverloads_DiffParamCount + { + public string OverloadExample(string s) { return s; } + public int OverloadExample(int n, int m) { return n; } + } +}"; + private const string Valid_TwoOverloads_OneAttribute_OneInList = @" +namespace Test +{ +public sealed class Valid_TwoOverloads_OneAttribute_OneInList + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + +}"; + private const string Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute = @" +namespace Test +{ + public sealed class Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string Valid_TwoOverloads_OneAttribute_TwoLists = @" +namespace Test +{ + public sealed class Valid_TwoOverloads_OneAttribute_TwoLists + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string Valid_ThreeOverloads_OneAttribute = @" +namespace Test +{ + public sealed class Valid_ThreeOverloads_OneAttribute + { + + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + public bool OverloadExample(bool b) { return b; } + } +}"; + private const string Valid_ThreeOverloads_OneAttribute_2 = @" +namespace Test +{ + public sealed class Valid_ThreeOverloads_OneAttribute_2 + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } +}"; + private const string Valid_TwoOverloads_OneAttribute_3 = @" +namespace Test +{ + public sealed class Valid_TwoOverloads_OneAttribute_3 + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + // ** Jagged array + private const string Valid_JaggedMix_PrivateClassPublicProperty = @" +namespace Test +{ + internal sealed class Valid_JaggedArray_PrivateClassPublicProperty + { + private int[][] Arr { get; set; } + public int[][] ArrP { get; set; } + public int[][][] Arr3 { get; set; } + private int[][][] Arr3P { get; set; } + } +}"; + private const string Valid_Jagged2D_PrivateClassPublicMethods = @" +namespace Test +{ + internal sealed class Valid_JaggedArray_PrivateClassPublicMethods + { + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } + } +}"; + private const string Valid_Jagged3D_PrivateClassPublicMethods = @" +namespace Test +{ + internal sealed class Valid_Jagged3D_PrivateClassPublicMethods + { + public int[][][] J3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + private const string Valid_Jagged3D_PublicClassPrivateMethods = @" +namespace Test +{ +public sealed class Valid_Jagged3D_PublicClassPrivateMethods + { + private int[][][] D3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + private int[][][] D3_ReturnAndInput1(int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + // prop + private const string Valid_MultiDimArray_PrivateClassPublicProperty1 = @" +namespace Test +{ +internal class Valid_MultiDimArray_PrivateClassPublicProperty1 + { + public int[,] Arr_2d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PrivateClassPublicProperty2 = @" +namespace Test +{ + + internal class Valid_MultiDimArray_PrivateClassPublicProperty2 + { + public int[,,] Arr_3d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PrivateClassPublicProperty3 = @" +namespace Test +{ +internal class Valid_MultiDimArray_PrivateClassPublicProperty3 + { + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PrivateClassPublicProperty4 = @" +namespace Test +{ +internal class Valid_MultiDimArray_PrivateClassPublicProperty4 + { + private int[,,] PrivArr_3d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateProperty1 = @" +namespace Test +{ +public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 + { + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateProperty2 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 + { + private int[,,] PrivArr_3d { get; set; } + } +}"; + // 2d + private const string Valid_2D_PrivateClass_PublicMethod1 = @" +namespace Test +{ +internal sealed class Valid_2D_PrivateClass_PublicMethod1 + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod2 = @" +namespace Test +{ + internal sealed class Valid_2D_PrivateClass_PublicMethod2 + { + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod3 = @" +namespace Test +{ +internal sealed class Valid_2D_PrivateClass_PublicMethod3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod4 = @" +namespace Test +{ + internal sealed class Valid_2D_PrivateClass_PublicMethod4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod5 = @" +namespace Test +{ + internal sealed class Valid_2D_PrivateClass_PublicMethod5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod6 = @" +namespace Test +{ + internal sealed class Valid_2D_PrivateClass_PublicMethod6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + } +}"; + // 3d + private const string Valid_3D_PrivateClass_PublicMethod1 = @" +namespace Test +{ +internal sealed class Valid_3D_PrivateClass_PublicMethod1 + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod2 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod3 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod4 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod5 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod6 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + // methods + private const string Valid_MultiDimArray_PublicClassPrivateMethod1 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 + { + private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod2 = @" +namespace Test +{ +public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 + { + private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod3 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty3 + { + private int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod4 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty4 + { + private int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod5 = @" +namespace Test +{ +public sealed class Valid_MultiDimArray_PublicClassPrivateProperty5 + { + private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod6 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty6 + { + private bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + // ** System.Array + private const string Valid_SystemArray_Interface1 = @" +namespace Test +{ +internal interface Valid_SystemArray_Interface1 + { + System.Array Id(System.Array arr); + } +}"; + private const string Valid_SystemArray_Interface2 = @" +namespace Test +{ +internal interface Valid_SystemArray_Interface2 + { + void Method2(System.Array arr); + } +}"; + private const string Valid_SystemArray_Interface3 = @" +namespace Test +{ + internal interface Valid_SystemArray_Interface3 + { + System.Array Method3(); + } +}"; + private const string Valid_SystemArray_InternalClass1 = @" +namespace Test +{ +internal class Valid_SystemArray_InternalClass1 + { + public System.Array Arr_2d { get; set; } + } +}"; + private const string Valid_SystemArray_InternalClass2 = @" +namespace Test +{ +internal class Valid_SystemArray_InternalClass2 + { + + public System.Array Arr_3d { get; set; } + } +}"; + private const string Valid_SystemArray_InternalClass3 = @" +namespace Test +{ +internal class Valid_SystemArray_InternalClass3 + { + private System.Array PrivArr_2d { get; set; } + } +}"; + private const string Valid_SystemArray_InternalClass4 = @" +namespace Test +{ +internal class Valid_SystemArray_InternalClass4 + { + private System.Array PrivArr_3d { get; set; } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty1 = @" +namespace Test +{ +public sealed class Valid_SystemArray_PublicClassPrivateProperty1 + { + private System.Array PrivArr_2d { get; set; } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty2 = @" +using System; +namespace Test +{ +public sealed class Valid_SystemArray_PublicClassPrivateProperty2 + { + private Array PrivArr_3d { get; set; } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty3 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateProperty3 + { + private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty4 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateProperty4 + { + private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty5 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateProperty1 + { + private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty6 = @" +namespace Test +{ + public sealed class Valid_SystemArrayPublicClassPrivateProperty2 + { + private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods1 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods1 + { + public System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods2 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods2 + { + public System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods3 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods3 + { + public System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods4 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods4 + { + public bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods5 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods5 + { + public bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods6 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods6 + { + public System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty1 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty1 + { + public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty2 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty2 + { + public System.Array Arr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty3 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty3 + { + public int[] Arr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty4 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty4 + { + public System.Array Arr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty5 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty5 + { + private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty6 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty6 + { + private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty7 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty7 + { + private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty8 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty8 + { + private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod1 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod1 + { + private System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod2 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod2 + { + private System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod3 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod3 + { + private System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod4 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod4 + { + private System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod5 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod5 + { + private bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod6 = @" +namespace Test +{ + public sealed class Valid_SystemArrayPublicClassPrivateMethod6 + { + private bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string Valid_SystemArrayProperty = @" +namespace Test +{ + public sealed class SystemArrayProperty_Valid + { + private System.Array PrivArr { get; set; } + } +}"; + // ReadOnlyArray / WriteOnlyArray + private const string Valid_ArrayParamAttrUnary_1 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public int GetSum([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } +}"; + private const string Valid_ArrayParamAttrUnary_2 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrUnary_3 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrUnary_4 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrUnary_5 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void ArrayNotMarked_Valid(out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_1 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public int GetSum(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } +}"; + private const string Valid_ArrayParamAttrBinary_2 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void MarkedWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_3 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void MarkedOutAndWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_4 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void MarkedOutOnly_Valid(int i, out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_5 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void ArrayNotMarked_Valid(int i, out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_6 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedReadOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_7 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_8 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_9 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedOut_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, out int[] arr) { arr = new int[] { }; } + } +}"; + // Struct field + private const string Valid_StructWithPrimitiveTypes = @" +namespace Test +{ + public struct StructWithAllValidFields + { + bool boolean; + char character; + decimal dec; + double dbl; + float flt; + int i; + uint nat; + long lng; + ulong ulng; + short sh; + ushort us; + string str; + } +}"; + } +} diff --git a/src/Authoring/DiagnosticTests/DiagnosticTests.Helpers.cs b/src/Authoring/DiagnosticTests/TestHelpers.cs similarity index 63% rename from src/Authoring/DiagnosticTests/DiagnosticTests.Helpers.cs rename to src/Authoring/DiagnosticTests/TestHelpers.cs index d8239e58b..5aa1baa09 100644 --- a/src/Authoring/DiagnosticTests/DiagnosticTests.Helpers.cs +++ b/src/Authoring/DiagnosticTests/TestHelpers.cs @@ -1,7 +1,9 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.VisualBasic; using NUnit.Framework; using System.Collections.Immutable; +using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -14,27 +16,26 @@ public partial class TestDiagnostics /// /// string of source code /// - public static Compilation CreateCompilation(string source) + private Compilation CreateCompilation(string source) => CSharpCompilation.Create( assemblyName: "compilation", syntaxTrees: new[] { CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Preview)) }, references: new[] { MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location) }, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - /// /// CreateDriver makes a CSharpGeneratorDriver /// /// /// /// - public static GeneratorDriver CreateDriver(Compilation compilation, params ISourceGenerator[] generators) + private static GeneratorDriver CreateDriver(Compilation compilation, params ISourceGenerator[] generators) => CSharpGeneratorDriver.Create( generators: ImmutableArray.Create(generators), additionalTexts: ImmutableArray.Empty, parseOptions: (CSharpParseOptions)compilation.SyntaxTrees.First().Options, - optionsProvider: null); // todo: pass the CsWinRTComponent config option here so we don't have to comment out the check in the source generator - + optionsProvider: null); + // todo: pass the CsWinRTComponent config option here so we don't have to comment out the check in the source generator /// /// RunGenerators makes a driver and applies the given generators to the compilation, storing diagnostics in an out param @@ -43,10 +44,25 @@ public static GeneratorDriver CreateDriver(Compilation compilation, params ISour /// /// /// - public static Compilation RunGenerators(Compilation compilation, out ImmutableArray diagnostics, params ISourceGenerator[] generators) + private static Compilation RunGenerators(Compilation compilation, out ImmutableArray diagnostics, params ISourceGenerator[] generators) { CreateDriver(compilation, generators).RunGeneratorsAndUpdateCompilation(compilation, out var updatedCompilation, out diagnostics); return updatedCompilation; } + + /// + /// Create a HashSet of DiagnosticDescriptor from the Array of Diagnostic + /// + /// + /// + private HashSet MakeDiagnosticSet(ImmutableArray arr) + { + HashSet setSoFar = new HashSet(); + foreach (var d in arr) + { + setSoFar.Add(d.Descriptor); + } + return setSoFar; + } } } diff --git a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs index b321f3841..22e049a8f 100644 --- a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs +++ b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs @@ -7,22 +7,6 @@ namespace DiagnosticTests { - - /* - * todo fix the `using` statement, based on Mano's PR comment - * ******************** - - private const string StructWithWinRTField = @" -using Some.Namespace -namespace Test -{ -public struct StructWithWinRTStructField - { - public Matrix3x2 matrix; - } -}"; - */ - [TestFixture] public partial class TestDiagnostics { @@ -51,33 +35,148 @@ public void CheckNoDiagnostic(string source) /// CodeHasDiagnostic takes some source code (string) and a Diagnostic descriptor, /// it checks that a diagnostic with the same description was raised by the source generator /// - [Test, TestCaseSource(nameof(WinRTComponentCases))] - public void CodeHasDiagnostics(string testCode, params DiagnosticDescriptor[] rules) + [Test, TestCaseSource(nameof(InvalidCases))] + public void CodeHasDiagnostic(string testCode, DiagnosticDescriptor rule) { Compilation compilation = CreateCompilation(testCode); RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); - HashSet diagDescsFound = new HashSet(); - - foreach (var d in diagnosticsFound) - { - diagDescsFound.Add(d.Descriptor); - } - - foreach (var rule in rules) - { - Assert.That(diagDescsFound.Contains(rule)); - } + HashSet diagDescsFound = MakeDiagnosticSet(diagnosticsFound); + Assert.That(diagDescsFound.Contains(rule)); } - private static IEnumerable WinRTComponentCases + #region InvalidTests + private static IEnumerable InvalidCases { get { + // multi-dimensional array tests + yield return new TestCaseData(MultiDim_2DProp, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Array Property"); + yield return new TestCaseData(MultiDim_3DProp, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Array Property"); + + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 1"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 2"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 3"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 4"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 5"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 6"); + + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 1"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 2"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 3"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 4"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 5"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 6"); + + yield return new TestCaseData(MultiDim_2D_Interface1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 1"); + yield return new TestCaseData(MultiDim_2D_Interface2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 2"); + yield return new TestCaseData(MultiDim_2D_Interface3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 3"); + yield return new TestCaseData(MultiDim_2D_Interface4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 4"); + yield return new TestCaseData(MultiDim_2D_Interface5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 5"); + yield return new TestCaseData(MultiDim_2D_Interface6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 6"); + + yield return new TestCaseData(MultiDim_3D_Interface1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 1"); + yield return new TestCaseData(MultiDim_3D_Interface2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 2"); + yield return new TestCaseData(MultiDim_3D_Interface3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 3"); + yield return new TestCaseData(MultiDim_3D_Interface4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 4"); + yield return new TestCaseData(MultiDim_3D_Interface5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 5"); + yield return new TestCaseData(MultiDim_3D_Interface6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 6"); + yield return new TestCaseData(SubNamespaceInterface_D2Method1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 2D Subnamespace Interface Method 1"); + yield return new TestCaseData(SubNamespaceInterface_D2Method2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 2D Subnamespace Interface Method 2"); + yield return new TestCaseData(SubNamespaceInterface_D2Method3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 2D Subnamespace Interface Method 3"); + yield return new TestCaseData(SubNamespaceInterface_D2Method4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 2D Subnamespace Interface Method 4"); + yield return new TestCaseData(SubNamespaceInterface_D2Method5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 2D Subnamespace Interface Method 5"); + yield return new TestCaseData(SubNamespaceInterface_D2Method6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 2D Subnamespace Interface Method 6"); + yield return new TestCaseData(SubNamespaceInterface_D3Method1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 3D Subnamespace Interface Method 1"); + yield return new TestCaseData(SubNamespaceInterface_D3Method2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 3D Subnamespace Interface Method 2"); + yield return new TestCaseData(SubNamespaceInterface_D3Method3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 3D Subnamespace Interface Method 3"); + yield return new TestCaseData(SubNamespaceInterface_D3Method4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 3D Subnamespace Interface Method 4"); + yield return new TestCaseData(SubNamespaceInterface_D3Method5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 3D Subnamespace Interface Method 5"); + yield return new TestCaseData(SubNamespaceInterface_D3Method6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) + .SetName("MultiDim 3D Subnamespace Interface Method 6"); + + + // jagged array tests + yield return new TestCaseData(Jagged2D_Property1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Property 1"); + yield return new TestCaseData(Jagged2D_Property2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Property 2"); + yield return new TestCaseData(Jagged3D_Property1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Property 1"); + yield return new TestCaseData(Jagged3D_Property2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Property 2"); + yield return new TestCaseData(Jagged2D_ClassMethod1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 1"); + yield return new TestCaseData(Jagged2D_ClassMethod2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 2"); + yield return new TestCaseData(Jagged2D_ClassMethod3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 3"); + yield return new TestCaseData(Jagged2D_ClassMethod4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 4"); + yield return new TestCaseData(Jagged2D_ClassMethod5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 5"); + yield return new TestCaseData(Jagged2D_ClassMethod6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 6"); + yield return new TestCaseData(Jagged3D_ClassMethod1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 1"); + yield return new TestCaseData(Jagged3D_ClassMethod2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 2"); + yield return new TestCaseData(Jagged3D_ClassMethod3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 3"); + yield return new TestCaseData(Jagged3D_ClassMethod4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 4"); + yield return new TestCaseData(Jagged3D_ClassMethod5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 5"); + yield return new TestCaseData(Jagged3D_ClassMethod6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 6"); + yield return new TestCaseData(Jagged2D_InterfaceMethod1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 1"); + yield return new TestCaseData(Jagged2D_InterfaceMethod2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 2"); + yield return new TestCaseData(Jagged2D_InterfaceMethod3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 3"); + yield return new TestCaseData(Jagged2D_InterfaceMethod4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 4"); + yield return new TestCaseData(Jagged2D_InterfaceMethod5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 5"); + yield return new TestCaseData(Jagged2D_InterfaceMethod6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 6"); + yield return new TestCaseData(Jagged3D_InterfaceMethod1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 1"); + yield return new TestCaseData(Jagged3D_InterfaceMethod2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 2"); + yield return new TestCaseData(Jagged3D_InterfaceMethod3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 3"); + yield return new TestCaseData(Jagged3D_InterfaceMethod4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 4"); + yield return new TestCaseData(Jagged3D_InterfaceMethod5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 5"); + yield return new TestCaseData(Jagged3D_InterfaceMethod6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 6"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 1"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 2"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 3"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 4"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 5"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 6"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 1"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 2"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 3"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 4"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 5"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 6"); + + // overload attribute tests + yield return new TestCaseData(TwoOverloads_NoAttribute, DiagnosticRules.MethodOverload_NeedDefaultAttribute) + .SetName("DefaultOverload - Need Attribute 1"); + yield return new TestCaseData(TwoOverloads_NoAttribute_OneIrrevAttr, DiagnosticRules.MethodOverload_NeedDefaultAttribute) + .SetName("DefaultOverload - Need Attribute 2"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInList, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Multiple Attribute 1"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInList, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Multiple Attribute 2"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_TwoLists, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Multiple Attribute 3"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInSeparateList_OneNot, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Multiple Attribute 4"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInSeparateList, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Multiple Attribute 5"); + yield return new TestCaseData(TwoOverloads_TwoAttribute, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Multiple Attribute 6"); + yield return new TestCaseData(ThreeOverloads_TwoAttributes, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Multiple Attribute 7"); + + // ....................................................................................................................................... + // multiple class constructors of same arity yield return new TestCaseData(ConstructorsOfSameArity, DiagnosticRules.ClassConstructorRule).SetName("Multiple constructors of same arity"); + // implementing async interface yield return new TestCaseData(ImplementsIAsyncOperation, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperation"); yield return new TestCaseData(ImplementsIAsyncOperationWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperationWithProgress"); yield return new TestCaseData(ImplementsIAsyncAction, DiagnosticRules.AsyncRule).SetName("Implements IAsyncAction"); yield return new TestCaseData(ImplementsIAsyncActionWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncActionWithProgress"); + // readonly/writeonlyArray attribute yield return new TestCaseData(TestArrayParamAttrUnary_1, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrUnary_1"); yield return new TestCaseData(TestArrayParamAttrUnary_2, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrUnary_2"); yield return new TestCaseData(TestArrayParamAttrUnary_3, DiagnosticRules.ArrayOutputParamMarkedRead).SetName("TestArrayParamAttrUnary_3"); @@ -112,10 +211,14 @@ private static IEnumerable WinRTComponentCases yield return new TestCaseData(TestArrayParamAttrBinary_22, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_22"); yield return new TestCaseData(TestArrayParamAttrBinary_23, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_23"); yield return new TestCaseData(TestArrayParamAttrBinary_24, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrBinary_24"); + // name clash with params (__retval) yield return new TestCaseData(DunderRetValParam, DiagnosticRules.ParameterNamedValueRule).SetName("Test Parameter Name Conflict (__retval)"); + // operator overloading yield return new TestCaseData(OperatorOverload_Class, DiagnosticRules.OperatorOverloadedRule).SetName("Test Overload of Operator"); + // ref param yield return new TestCaseData(RefParam_ClassMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Class"); yield return new TestCaseData(RefParam_InterfaceMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Interface"); + // startuc field tests yield return new TestCaseData(StructWithClassField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Class Field"); yield return new TestCaseData(StructWithDelegateField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Delegate Field"); yield return new TestCaseData(StructWithIndexer, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Indexer Field"); @@ -127,15 +230,45 @@ private static IEnumerable WinRTComponentCases yield return new TestCaseData(StructWithDynamicField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Dynamic Field"); yield return new TestCaseData(StructWithByteField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Byte Field"); yield return new TestCaseData(StructWithConstructor, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Constructor Field"); + // system.array tests + yield return new TestCaseData(ArrayInstanceProperty1, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 1"); + yield return new TestCaseData(ArrayInstanceProperty2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 2"); + yield return new TestCaseData(ArrayInstanceProperty3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 3"); + yield return new TestCaseData(ArrayInstanceProperty4, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 4"); + yield return new TestCaseData(SystemArrayProperty5, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 5"); + yield return new TestCaseData(ArrayInstanceInterface1, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 1"); + yield return new TestCaseData(ArrayInstanceInterface2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 2"); + yield return new TestCaseData(ArrayInstanceInterface3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 3"); + yield return new TestCaseData(SystemArrayJustReturn, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Method - Return only"); + yield return new TestCaseData(SystemArrayUnaryAndReturn, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Method - Unary and return"); + yield return new TestCaseData(SystemArraySecondArgClass, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Method - Arg 2/2"); + yield return new TestCaseData(SystemArraySecondArg2Class, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Method - Arg 2/3"); + yield return new TestCaseData(SystemArraySecondArgAndReturnTypeClass, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Class 1"); + yield return new TestCaseData(SystemArraySecondArgAndReturnTypeClass2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Class 2"); + yield return new TestCaseData(SystemArrayNilArgsButReturnTypeInterface, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 4"); + yield return new TestCaseData(SystemArrayUnaryAndReturnTypeInterface, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 5"); + yield return new TestCaseData(SystemArraySecondArgAndReturnTypeInterface, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 6"); + yield return new TestCaseData(SystemArraySecondArgAndReturnTypeInterface2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 7"); + yield return new TestCaseData(SystemArraySecondArgInterface, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 8"); + yield return new TestCaseData(SystemArraySecondArgInterface2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 9"); + yield return new TestCaseData(SystemArraySubNamespace_ReturnOnly, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 1/6"); + yield return new TestCaseData(SystemArraySubNamespace_ReturnAndInput1, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 2/6"); + yield return new TestCaseData(SystemArraySubNamespace_ReturnAndInput2of2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 3/6"); + yield return new TestCaseData(SystemArraySubNamespace_ReturnAndInput2of3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 4/6"); + yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 5/6"); + yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 6/6"); } } + #endregion + #region ValidTests - + private static IEnumerable ValidCases { get { + // ReadOnlyArray / WriteOnlyArray Attribute yield return new TestCaseData(Valid_ArrayParamAttrUnary_1).SetName("Valid - ArrayParamAttrUnary_1"); yield return new TestCaseData(Valid_ArrayParamAttrUnary_2).SetName("Valid - ArrayParamAttrUnary_2"); yield return new TestCaseData(Valid_ArrayParamAttrUnary_3).SetName("Valid - ArrayParamAttrUnary_3"); @@ -150,624 +283,89 @@ private static IEnumerable ValidCases yield return new TestCaseData(Valid_ArrayParamAttrBinary_7).SetName("Valid - ArrayParamAttrBinary_7"); yield return new TestCaseData(Valid_ArrayParamAttrBinary_8).SetName("Valid - ArrayParamAttrBinary_8"); yield return new TestCaseData(Valid_ArrayParamAttrBinary_9).SetName("Valid - ArrayParamAttrBinary_9"); - yield return new TestCaseData(StructWithAllValidFields).SetName("Valid - Struct with only fields of basic types"); + // Struct field + yield return new TestCaseData(Valid_StructWithPrimitiveTypes).SetName("Valid - Struct with only fields of basic types"); + yield return new TestCaseData(Valid_StructWithWinRTField).SetName("(TODO - fix the namespace) Valid - Struct with struct field"); + // SystemArray + yield return new TestCaseData(Valid_SystemArrayProperty).SetName("Valid - System.Array private property"); + yield return new TestCaseData(Valid_SystemArray_Interface1).SetName("Valid - System.Array internal interface 1"); + yield return new TestCaseData(Valid_SystemArray_Interface2).SetName("Valid - System.Array internal interface 2"); + yield return new TestCaseData(Valid_SystemArray_Interface3).SetName("Valid - System.Array internal interface 3"); + yield return new TestCaseData(Valid_SystemArray_InternalClass1).SetName("Valid - System.Array internal class 1"); + yield return new TestCaseData(Valid_SystemArray_InternalClass2).SetName("Valid - System.Array internal class 2"); + yield return new TestCaseData(Valid_SystemArray_InternalClass3).SetName("Valid - System.Array internal class 3"); + yield return new TestCaseData(Valid_SystemArray_InternalClass4).SetName("Valid - System.Array internal class 4"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty1).SetName("Valid - System.Array public class / private property 1"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty2).SetName("Valid - System.Array public class / private property 2"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty3).SetName("Valid - System.Array public class / private property 3"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty4).SetName("Valid - System.Array public class / private property 4"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty5).SetName("Valid - System.Array public class / private property 5"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty6).SetName("Valid - System.Array public class / private property 6"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods1).SetName("Valid - System.Array internal class / public method 1"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods2).SetName("Valid - System.Array internal class / public method 2"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods3).SetName("Valid - System.Array internal class / public method 3"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods4).SetName("Valid - System.Array internal class / public method 4"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods5).SetName("Valid - System.Array internal class / public method 5"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods6).SetName("Valid - System.Array internal class / public method 6"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty1).SetName("Valid - System.Array internal class / public property 1"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty2).SetName("Valid - System.Array internal class / public property 2"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty3).SetName("Valid - System.Array internal class / public property 3"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty4).SetName("Valid - System.Array internal class / public property 4"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty5).SetName("Valid - System.Array internal class / public property 5"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty6).SetName("Valid - System.Array internal class / public property 6"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty7).SetName("Valid - System.Array internal class / public property 7"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty8).SetName("Valid - System.Array internal class / public property 8"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod1).SetName("Valid - System.Array public class / private method 1"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod2).SetName("Valid - System.Array public class / private method 2"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod3).SetName("Valid - System.Array public class / private method 3"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod4).SetName("Valid - System.Array public class / private method 4"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod5).SetName("Valid - System.Array public class / private method 5"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod6).SetName("Valid - System.Array public class / private method 6"); + // multi dim array tests + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod1).SetName("Valid - MultiDim public class / private method 1"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod2).SetName("Valid - MultiDim public class / private method 2"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod3).SetName("Valid - MultiDim public class / private method 3"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod4).SetName("Valid - MultiDim public class / private method 4"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod5).SetName("Valid - MultiDim public class / private method 5"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod6).SetName("Valid - MultiDim public class / private method 6"); + + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod1).SetName("Valid - MultiDim 3D private class / public method 1"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod2).SetName("Valid - MultiDim 3D private class / public method 2"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod3).SetName("Valid - MultiDim 3D private class / public method 3"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod4).SetName("Valid - MultiDim 3D private class / public method 4"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod5).SetName("Valid - MultiDim 3D private class / public method 5"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod6).SetName("Valid - MultiDim 3D private class / public method 6"); + + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod1).SetName("Valid - MultiDim 2D private class / public method 1"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod2).SetName("Valid - MultiDim 2D private class / public method 2"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod3).SetName("Valid - MultiDim 2D private class / public method 3"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod4).SetName("Valid - MultiDim 2D private class / public method 4"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod5).SetName("Valid - MultiDim 2D private class / public method 5"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod6).SetName("Valid - MultiDim 2D private class / public method 6"); + + yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty1).SetName("Valid - MultiDim 2D private class / public property 1"); + yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty2).SetName("Valid - MultiDim 2D private class / public property 2"); + yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty3).SetName("Valid - MultiDim 2D private class / public property 3"); + yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty4).SetName("Valid - MultiDim 2D private class / public property 4"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateProperty1).SetName("Valid - MultiDim 2D public class / private property 1"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateProperty2).SetName("Valid - MultiDim 2D public class / private property 2"); + // jagged array tests + yield return new TestCaseData(Valid_JaggedMix_PrivateClassPublicProperty).SetName("Valid - Jagged Array private class / private property"); + yield return new TestCaseData(Valid_Jagged2D_PrivateClassPublicMethods).SetName("Valid - Jagged Array private class / public method"); + yield return new TestCaseData(Valid_Jagged3D_PrivateClassPublicMethods).SetName("Valid - Jagged Array private class / public method"); + yield return new TestCaseData(Valid_Jagged3D_PublicClassPrivateMethods).SetName("Valid - Jagged Array public class / private method"); + // overload attributes + yield return new TestCaseData(Valid_TwoOverloads_DiffParamCount).SetName("Valid - DefaultOverload attribute 1"); + yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_OneInList).SetName("Valid - DefaultOverload attribute 2"); + yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute).SetName("Valid - DefaultOverload attribute 3"); + yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_TwoLists).SetName("Valid - DefaultOverload attribute 4"); + yield return new TestCaseData(Valid_ThreeOverloads_OneAttribute).SetName("Valid - DefaultOverload attribute 5"); + yield return new TestCaseData(Valid_ThreeOverloads_OneAttribute_2).SetName("Valid - DefaultOverload attribute 6"); + yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_3).SetName("Valid - DefaultOverload attribute 7"); } } - private const string Valid_ArrayParamAttrUnary_1 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public int GetSum([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } - } -}"; - private const string Valid_ArrayParamAttrUnary_2 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrUnary_3 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrUnary_4 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrUnary_5 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void ArrayNotMarked_Valid(out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_1 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public int GetSum(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } - } -}"; - private const string Valid_ArrayParamAttrBinary_2 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void MarkedWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrBinary_3 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void MarkedOutAndWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_4 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void MarkedOutOnly_Valid(int i, out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_5 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void ArrayNotMarked_Valid(int i, out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_6 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedReadOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrBinary_7 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrBinary_8 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_9 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedOut_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, out int[] arr) { arr = new int[] { }; } - } -}"; - private const string StructWithAllValidFields = @" -namespace Test -{ - public struct StructWithAllValidFields - { - bool boolean; - char character; - decimal dec; - double dbl; - float flt; - int i; - uint nat; - long lng; - ulong ulng; - short sh; - ushort us; - string str; - } -}"; - #endregion - #region DataTests - - private const string StructWithByteField = @" -namespace Test -{ -public struct StructWithByteField_Valid - { - public byte b; - } -}"; - private const string StructWithConstructor = @" - namespace Test -{ - public struct StructWithConstructor_Invalid - { - int X; - StructWithConstructor_Invalid(int x) - { - X = x; - } - } -} "; - private const string StructWithClassField = @" -namespace Test -{ - public sealed class SillyClass - { - public double Identity(double d) - { - return d; - } - - public SillyClass() { } - } - - public struct StructWithClass_Invalid - { - public SillyClass classField; - } -}"; - private const string StructWithDelegateField = @" -namespace Test { -public struct StructWithDelegate_Invalid - { - public delegate int ADelegate(int x); - } -}"; - private const string ConstructorsOfSameArity = @" -namespace TestNamespace -{ -public sealed class SameArityConstructors -{ - private int num; - private string word; - - public SameArityConstructors(int i) - { - num = i; - word = ""dog""; - } - - public SameArityConstructors(string s) - { - num = 38; - word = s; - } -} -}"; - private const string ImplementsIAsyncOperationWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class OpWithProgress : IAsyncOperationWithProgress - { - AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperationWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ImplementsIAsyncActionWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ -public class ActionWithProgress : IAsyncActionWithProgress - { - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ImplementsIAsyncOperation = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class Op : IAsyncOperation - { - AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperation.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ImplementsIAsyncAction = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class AsyAction : IAsyncAction - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string TestArrayParamAttrUnary_1 = @" -public sealed class OnlyParam -{ - public void BothAttributes_Separate([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_2 = @" -public sealed class OnlyParam -{ - public void BothAttributes_Together([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_3 = @" -public sealed class OnlyParam -{ - public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } -}"; - private const string TestArrayParamAttrUnary_4 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedIn([In] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_5 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedOut([Out] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_6 = @" -public sealed class OnlyParam -{ - public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrUnary_7 = @" -public sealed class OnlyParam -{ - public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrUnary_8 = @" -public sealed class OnlyParam -{ - public void ParamMarkedIn([In] int arr) { } -}"; - private const string TestArrayParamAttrUnary_9 = @" -public sealed class OnlyParam -{ - public void ParamMarkedOut([Out] int arr) { } -}"; - private const string TestArrayParamAttrUnary_10 = @" -public sealed class OnlyParam -{ - public void ArrayNotMarked(int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_1 = @" -public sealed class TwoParam -{ - public void BothAttributes_Separate(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_2 = @" -public sealed class TwoParam -{ - public void BothAttributes_Together(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_3 = @" -public sealed class TwoParam -{ - public void MarkedOutAndReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } -}"; - private const string TestArrayParamAttrBinary_4 = @" -public sealed class TwoParam -{ - public void ArrayMarkedIn(int i, [In] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_5 = @" -public sealed class TwoParam -{ - public void ArrayMarkedOut(int i, [Out] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_6 = @" -public sealed class TwoParam -{ - public void NonArrayMarkedReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrBinary_7 = @" -public sealed class TwoParam -{ - public void NonArrayMarkedWriteOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrBinary_8 = @" -public sealed class TwoParam -{ - public void ParamMarkedIn(int i, [In] int arr) { } -}"; - private const string TestArrayParamAttrBinary_9 = @" -public sealed class TwoParam -{ - public void ParamMarkedOut(int i, [Out] int arr) { } -}"; - private const string TestArrayParamAttrBinary_10 = @" -public sealed class TwoParam -{ - public void ArrayNotMarked(int i, int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_11 = @" -public sealed class TwoArray -{ - public void OneValidOneInvalid_1( -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] -[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] ys) { } -}"; - private const string TestArrayParamAttrBinary_12 = @" -public sealed class TwoArray -{ - public void OneValidOneInvalid_2( -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] -[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] ys) { } -}"; - private const string TestArrayParamAttrBinary_13 = @" -public sealed class TwoArray -{ - public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } -}"; - private const string TestArrayParamAttrBinary_14 = @" -public sealed class TwoParam -{ - public void ArrayMarkedIn(int i, [In] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_15 = @" -public sealed class TwoArray -{ - public void ArrayMarkedIn2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_16 = @" -public sealed class TwoArray -{ - public void ArrayMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_17 = @" -public sealed class TwoArray -{ - public void ArrayNotMarked(int i, int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_18 = @" -public sealed class TwoArray -{ - public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i) { } -}"; - private const string TestArrayParamAttrBinary_19 = @" -public sealed class TwoArray -{ - public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int i) { } -}"; - private const string TestArrayParamAttrBinary_20 = @" -public sealed class TwoArray -{ - public void NonArrayMarkedWriteOnly2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_21 = @" -public sealed class TwoArray -{ - public void ParamMarkedIn([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int arr) { } -}"; - private const string TestArrayParamAttrBinary_22 = @" -public sealed class TwoArray -{ - public void ParamMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int arr) { } -}"; - private const string TestArrayParamAttrBinary_23 = @" -public sealed class TwoArray -{ - public void ParamMarkedOut2([Out] int arr, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs) { } -}"; - private const string TestArrayParamAttrBinary_24 = @" -public sealed class TwoArray -{ - public void ArrayNotMarked([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, int[] arr) { } -}"; - private const string RefParam_InterfaceMethod = @" -public interface IHaveAMethodWithRefParam - { - void foo(ref int i); - } -"; - private const string RefParam_ClassMethod = @" -public sealed class ClassWithMethodUsingRefParam - { - public void MethodWithRefParam(ref int i) { i++; } - } -"; - private const string OperatorOverload_Class = @" - public sealed class ClassThatOverloadsOperator - { - public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) - { - return thing; - } - }"; - private const string DunderRetValParam = @" -public sealed class ParameterNamedDunderRetVal - { - public int Identity(int __retval) - { - return __retval; - } - } -"; - private const string StructWithIndexer = @" -namespace Test -{ -public struct StructWithIndexer_Invalid - { - int[] arr; - int this[int i] => arr[i]; - } -}"; - private const string StructWithMethods = @" -namespace Test -{ -public struct StructWithMethods_Invalid - { - int foo(int x) - { - return x; - } - } -}"; - private const string StructWithConst = @" -namespace Test -{ - public struct StructWithConst_Invalid - { - const int five = 5; - private int six; - } -}"; - private const string StructWithProperty = @" -namespace Test -{ - public enum BasicEnum - { - First = 0, - Second = 1 - } - - public struct Posn_Invalid - { - BasicEnum enumField; - - public int x { get; } - public int y { get; } - } -}"; - private const string StructWithPrivateField = @" -namespace Test -{ -public struct StructWithPrivateField_Invalid - { - const int ci = 5; - private int x; - } -}"; - private const string StructWithObjectField = @" -namespace Test -{ -public struct StructWithObjectField_Invalid - { - public object obj; - } -}"; - private const string StructWithDynamicField = @" -namespace Test -{ -public struct StructWithDynamicField_Invalid - { - public dynamic dyn; - } -}"; - - #endregion } } \ No newline at end of file diff --git a/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs b/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs deleted file mode 100644 index b24ebd032..000000000 --- a/src/Authoring/TestDiagnostics/JaggedArraySignatureTests.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace TestDiagnostics -{ - public interface IF { int id(int x); } - /* - * Valid tests - */ - internal sealed class JaggedArray_Properties_Valid - { - private int[][] Arr { get; set; } - public int[][] ArrP { get; set; } - public int[][][] Arr3 { get; set; } - private int[][][] Arr3P { get; set; } - } - - internal sealed class J2InternalPublic_Valid - { - public int[][] J2_ReturnOnly() - { - int[][] arr = new int[2][]; - arr[0] = new int[1] { 1 }; - arr[1] = new int[1] { 2 }; - return arr; - } - public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - } - internal sealed class J3InternalPublic_Valid - { - public int[][][] J3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } - - public sealed class J3PublicPrivate_Valid - { - private int[][][] D3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - private int[][][] D3_ReturnAndInput1(int[][][] arr) { return arr; } - private int[][][] D3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } - - /* - * Invalid tests - */ - - /* - public sealed class JaggedArray_Properties_Invalid - { - private int[][] ArrP { get; set; } - public int[][] Arr { get; set; } - public int[][][] Arr3 { get; set; } - private int[][][] Arr3P { get; set; } - } - - public sealed class J2PublicPublic_Invalid - { - public int[][] J2_ReturnOnly() - { - int[][] arr = new int[2][]; - arr[0] = new int[1] { 1 }; - arr[1] = new int[1] { 2 }; - return arr; - } - public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - } - - public sealed class J3PublicPublic_Invalid - { - public int[][][] J3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } - - public interface J2MemberOfInterface_Invalid - { - public int[][] J2_ReturnOnly(); - public int[][] J2_ReturnAndInput1(int[,] arr); - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); - } - - public interface J3MemberOfInterface_Invalid - { - public int[][][] J3_ReturnOnly(); - public int[][][] J3_ReturnAndInput1(int[][][] arr); - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); - } - - namespace SubNamespace - { - public interface SubNamespaceInterface_J2Methods_Invalid - { - public int[][] J2_ReturnOnly(); - public int[][] J2_ReturnAndInput1(int[,] arr); - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); - } - - /* - public interface SubNamespaceInterface_J3Methods_Invalid - { - public int[][][] J3_ReturnOnly(); - public int[][][] J3_ReturnAndInput1(int[][][] arr); - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); - } - } // end SubNamespace - */ -} - diff --git a/src/Authoring/TestDiagnostics/MethodOverloadTests.cs b/src/Authoring/TestDiagnostics/MethodOverloadTests.cs deleted file mode 100644 index fe2449c3a..000000000 --- a/src/Authoring/TestDiagnostics/MethodOverloadTests.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace TestDiagnostics -{ - public sealed class TwoOverloads_DiffParamCount_Valid - { - public string OverloadExample(string s) { return s; } - public int OverloadExample(int n, int m) { return n; } - } - - public sealed class TwoOverloads_OneAttribute_OneInList_Valid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_OneAttribute_OneIrrelevatAttribute_Valid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_OneAttribute_TwoLists_Valid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - - public sealed class ThreeOverloads_OneAttribute_Valid - { - - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - - public bool OverloadExample(bool b) { return b; } - } - - public sealed class ThreeOverloads_OneAttribute_2_Valid - { - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public bool OverloadExample(bool b) { return b; } - } - - public sealed class TwoOverloads_OneAttribute_3_Valid - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - /* - // invalid method overload tests - public sealed class TwoOverloads_NoAttribute_Invalid - { - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_OneInList_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_NoAttribute_OneIrrevAttr_Invalid - { - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_BothInList_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_TwoLists_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_BothInSeparateList_Invalid - { - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated("hu", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class TwoOverloads_TwoAttribute_Invalid - { - - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } - - public sealed class ThreeOverloads_TwoAttributes_Invalid - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public bool OverloadExample(bool b) { return b; } - } - */ -} diff --git a/src/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs b/src/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs deleted file mode 100644 index 8a573adf5..000000000 --- a/src/Authoring/TestDiagnostics/MultidimensionalArraySignatureTests.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace TestDiagnostics -{ - internal class MultidimensionalArraySignature_2D_PrivateClass_Valid - { - public int[,] Arr_2d { get; set; } - public int[,,] Arr_3d { get; set; } - private int[,] PrivArr_2d { get; set; } - private int[,,] PrivArr_3d { get; set; } - } - - public sealed class MultidimensionalArraySignature_3D_Valid - { - private int[,] PrivArr_2d { get; set; } - private int[,,] PrivArr_3d { get; set; } - } - - internal sealed class D2InternalPublic_Valid - { - public int[,] D2_ReturnOnly() { return new int[4, 2]; } - public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - - } - - internal sealed class D3InternalPublic_Valid - { - public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - - } - - public sealed class MultiDimPublicPrivate_Valid - { - private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - private int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - private int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - private bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - - } - - /* - * Invalid tests include public properties in public classes, public interface methods, - */ - - /* - public sealed class MultidimensionalArraySignature_2D_Invalid - { - public int[,] Arr_2d { get; set; } - public int[,,] Arr_3d { get; set; } - private int[,] PrivArr_2d { get; set; } - } - - public sealed class D2PublicPublic_Invalid - { - public int[,] D2_ReturnOnly() { return new int[4, 2]; } - public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - - } - - public sealed class D3PublicPublic_Invalid - { - public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } - - public struct D2FieldInStruct - { - public int[,,] D3Method(bool b) { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - } - - public interface D2MemberOfInterface_Invalid - { - public int[,] D2_ReturnOnly(); - public int[,] D2_ReturnAndInput1(int[,] arr); - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); - } - - public interface D3MemberOfInterface_Invalid - { - public int[,,] D3_ReturnOnly(); - public int[,,] D3_ReturnAndInput1(int[,,] arr); - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - - namespace SubNamespace - { - public interface SubNamespacInterface_D2Methods_Invalid - { - public int[,] D2_ReturnOnly(); - public int[,] D2_ReturnAndInput1(int[,] arr); - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); - } - - public interface SubNamespaceInterface_D3Methods_Invalid - { - public int[,,] D3_ReturnOnly(); - public int[,,] D3_ReturnAndInput1(int[,,] arr); - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - } - */ -} diff --git a/src/Authoring/TestDiagnostics/NamespaceTests.cs b/src/Authoring/TestDiagnostics/NamespaceTests.cs deleted file mode 100644 index b3d792f14..000000000 --- a/src/Authoring/TestDiagnostics/NamespaceTests.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Runtime.InteropServices; - -namespace TestDiagnostics -{ - namespace OtherNamespace_Valid - { - public sealed class Class1 - { - int x; - public Class1(int a) { x = a; } - } - } - - // WME1068 - public sealed class TestDiagnostics - { - bool b; - public TestDiagnostics(bool x) { b = x; } - } -} - -// WME1044 -namespace OtherNamespace -{ - public sealed class Class1 - { - int x; - - public Class1(int a) - { - x = a; - } - } -} - -// WME1067 -namespace Testdiagnostics -{ - namespace InnerNamespace - { - public sealed class Class1 - { - int x; - public Class1(int a) { x = a; } - } - } -} diff --git a/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs b/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs deleted file mode 100644 index 6dbf1c1f6..000000000 --- a/src/Authoring/TestDiagnostics/NonZeroLowerBoundArraySignatureTests.cs +++ /dev/null @@ -1,244 +0,0 @@ -using System; - -namespace TestDiagnostics -{ - - /* - * Invalid tests include public properties in public classes, public interface methods, - */ - - public sealed class ArrayInstanceProperty1 - { - public int[] Arr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - } - - public sealed class ArrayInstanceProperty2 - { - public System.Array Arr - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - } - - public sealed class ArrayInstanceProperty3 - { - public int[] Arr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } - - public sealed class ArrayInstanceProperty4 - { - public System.Array Arr - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } - - public interface ArrayInstanceInterface1 - { - System.Array Id(System.Array arr); - } - public interface ArrayInstanceInterface2 - { - void Method2(System.Array arr); - } - - public interface ArrayInstanceInterface3 - { - System.Array Method3(); - } - - public sealed class SystemArrayProperty - { - public System.Array Arr { get; set; } - } - public sealed class SystemArrayProperty_Valid - { - private System.Array PrivArr { get; set; } - } - - public sealed class JustReturn - { - public System.Array SystemArrayMethod() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - - public sealed class UnaryAndReturn - { - public System.Array SystemArrayMethod(System.Array arr) { return arr; } - } - - public sealed class SecondInput - { - public bool SystemArrayMethod(bool a, System.Array arr) { return a; } - } - - public sealed class SecondInput2 - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b) { return a; } - } - - public sealed class SecondInputAndReturnType - { - public System.Array SystemArrayMethod(bool a, System.Array arr) { return arr; } - } - - public sealed class SecondInputAndReturnType2 - { - public System.Array SystemArrayMethod(bool a, System.Array arr, bool b) { return arr; } - } - - public interface SystemArrayInReturnTypeInterface - { - public System.Array SystemArrayMethod(); - } - public interface UnaryAndReturnTypeInterface - { - public System.Array SystemArrayMethod(System.Array arr); - } - public interface SecondArgAndReturnTypeInterface - { - public System.Array SystemArrayMethod(bool a, System.Array arr); - } - public interface SecondArgInterface - { - public bool SystemArrayMethod(bool a, System.Array arr); - } - // pick up here - public interface NZLBMemberOfInterface_Invalid - { - public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b); - } - public interface NZLBMemberOfInterface_Invalid2 - { - public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b); - } - - namespace SubNamespace - { - public interface SubNamespacInterface_NZLBMethods_Invalid - { - public System.Array D2_ReturnOnly(); - public System.Array D2_ReturnAndInput1(System.Array arr); - public System.Array D2_ReturnAndInput2of2(bool a, System.Array arr); - public System.Array D2_ReturnAndInput2of3(bool a, System.Array arr, bool b); - public bool D2_NotReturnAndInput2of2(bool a, System.Array arr); - public bool D2_NotReturnAndInput2of3(bool a, System.Array arr, bool b); - } - } - */ - - /* - * Valid tests - */ - - /* - public sealed class NonZeroLowerBound_PrivateProperty_Valid - { - private int[] PrivArr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - private System.Array PrivArr2 - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - private int[] PrivArr3 - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - private System.Array PrivArr4 - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } - - internal sealed class NonZeroLowerBound_PrivateClass_Valid - { - public int[] Arr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - - public System.Array Arr2 - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - - public int[] Arr3 - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - public System.Array Arr4 - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - - private int[] PrivArr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - - private System.Array PrivArr2 - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - - private int[] PrivArr3 - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - - private System.Array PrivArr4 - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } - - internal interface InterfaceWithNonZeroLowerBound_Valid - { - System.Array Id(System.Array arr); - void Method2(System.Array arr); - System.Array Method3(); - } - - internal class NZLBArraySignature_2D_PrivateClass_Valid - { - public System.Array Arr_2d { get; set; } - public System.Array Arr_3d { get; set; } - private System.Array PrivArr_2d { get; set; } - private System.Array PrivArr_3d { get; set; } - } - public sealed class NZLBArraySignature_3D_Valid - { - private System.Array PrivArr_2d { get; set; } - - private Array PrivArr_3d { get; set; } - } - internal sealed class NZLBInternalPublic_Valid - { - public System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - public System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } - public System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - public bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - public bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - public System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - } - - // tests return type and paramteter cases for 3-dimensional arrays - // we expect normal compilation since the methods are private - public sealed class NZLBPublicPrivate_Valid - { - private System.Array NZLB_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - private System.Array NZLB_ReturnAndInput1(System.Array arr) { return arr; } - private System.Array NZLB_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - private System.Array NZLB_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - private bool NZLB_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - private bool NZLB_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - } - */ -} diff --git a/src/Authoring/TestDiagnostics/TestDiagnostics.csproj b/src/Authoring/TestDiagnostics/TestDiagnostics.csproj index 9c004596d..548027368 100644 --- a/src/Authoring/TestDiagnostics/TestDiagnostics.csproj +++ b/src/Authoring/TestDiagnostics/TestDiagnostics.csproj @@ -6,7 +6,8 @@ preview 1.0.0.0 true - true + + false true $([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)', '$(IntermediateOutputPath)', 'Generated Files')) Library @@ -20,7 +21,7 @@ - + From 37316ae0f7bed48bc957bee59b34ecd017b77039 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 15 Dec 2020 14:23:06 -0800 Subject: [PATCH 31/41] all unit tests passing --- src/Authoring/DiagnosticTests/NegativeData.cs | 35 ++++++++------- src/Authoring/DiagnosticTests/PositiveData.cs | 43 +++++++++++++------ .../DiagnosticTests/UnitTestDiagnostics.cs | 32 +++++++------- src/cswinrt.sln | 25 +---------- 4 files changed, 69 insertions(+), 66 deletions(-) diff --git a/src/Authoring/DiagnosticTests/NegativeData.cs b/src/Authoring/DiagnosticTests/NegativeData.cs index 4b9546970..2ae838b66 100644 --- a/src/Authoring/DiagnosticTests/NegativeData.cs +++ b/src/Authoring/DiagnosticTests/NegativeData.cs @@ -688,6 +688,25 @@ public struct StructWithDelegate_Invalid { public delegate int ADelegate(int x); } +}"; + private const string StructWithPrimitiveTypesMissingPublicKeyword = @" +namespace Test +{ + public struct StructWithAllValidFields + { + bool boolean; + char character; + decimal dec; + double dbl; + float flt; + int i; + uint nat; + long lng; + ulong ulng; + short sh; + ushort us; + string str; + } }"; // constructor of same arity private const string ConstructorsOfSameArity = @" @@ -1251,14 +1270,6 @@ public sealed class ThreeOverloads_TwoAttributes } }"; // jagged 2d/3d prop - private const string Jagged2D_Property1 = @" -namespace Test -{ - public sealed class Jagged2D_Property1 - { - private int[][] ArrP { get; set; } - } -}"; private const string Jagged2D_Property2 = @" namespace Test { @@ -1274,14 +1285,6 @@ public sealed class Jagged3D_Property1 { public int[][][] Arr3 { get; set; } } -}"; - private const string Jagged3D_Property2 = @" -namespace Test -{ - public sealed class Jagged3D_Property2 - { - private int[][][] Arr3P { get; set; } - } }"; // jagged 2d class method private const string Jagged2D_ClassMethod1 = @" diff --git a/src/Authoring/DiagnosticTests/PositiveData.cs b/src/Authoring/DiagnosticTests/PositiveData.cs index 6f1a1c40e..8b834d846 100644 --- a/src/Authoring/DiagnosticTests/PositiveData.cs +++ b/src/Authoring/DiagnosticTests/PositiveData.cs @@ -174,6 +174,22 @@ private int[][][] D3_ReturnOnly() private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } } +}"; + private const string Valid_Jagged2D_Property = @" +namespace Test +{ + public sealed class Jagged2D_Property1 + { + private int[][] ArrP { get; set; } + } +}"; + private const string Valid_Jagged3D_Property = @" +namespace Test +{ + public sealed class Jagged3D_Property2 + { + private int[][][] Arr3P { get; set; } + } }"; // prop private const string Valid_MultiDimArray_PrivateClassPublicProperty1 = @" @@ -766,19 +782,22 @@ namespace Test { public struct StructWithAllValidFields { - bool boolean; - char character; - decimal dec; - double dbl; - float flt; - int i; - uint nat; - long lng; - ulong ulng; - short sh; - ushort us; - string str; + public bool boolean; + public char character; + public decimal dec; + public double dbl; + public float flt; + public int i; + public uint nat; + public long lng; + public ulong ulng; + public short sh; + public ushort us; + public string str; } }"; + + + } } diff --git a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs index 22e049a8f..d73a7ff32 100644 --- a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs +++ b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs @@ -27,8 +27,9 @@ public partial class TestDiagnostics public void CheckNoDiagnostic(string source) { Compilation compilation = CreateCompilation(source); - RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); - Assert.That(diagnosticsFound.IsEmpty); + RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); + var WinRTDiagnostics = diagnosticsFound.Where(diag => diag.Id.StartsWith("WME")); + Assert.That(!WinRTDiagnostics.Any()); } /// @@ -107,10 +108,8 @@ private static IEnumerable InvalidCases // jagged array tests - yield return new TestCaseData(Jagged2D_Property1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Property 1"); yield return new TestCaseData(Jagged2D_Property2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Property 2"); yield return new TestCaseData(Jagged3D_Property1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Property 1"); - yield return new TestCaseData(Jagged3D_Property2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Property 2"); yield return new TestCaseData(Jagged2D_ClassMethod1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 1"); yield return new TestCaseData(Jagged2D_ClassMethod2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 2"); yield return new TestCaseData(Jagged2D_ClassMethod3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 3"); @@ -220,16 +219,17 @@ private static IEnumerable InvalidCases yield return new TestCaseData(RefParam_InterfaceMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Interface"); // startuc field tests yield return new TestCaseData(StructWithClassField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Class Field"); - yield return new TestCaseData(StructWithDelegateField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Delegate Field"); - yield return new TestCaseData(StructWithIndexer, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Indexer Field"); - yield return new TestCaseData(StructWithMethods, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Method Field"); - yield return new TestCaseData(StructWithConst, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Const Field"); - yield return new TestCaseData(StructWithProperty, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Property Field"); - yield return new TestCaseData(StructWithPrivateField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Private Field"); + yield return new TestCaseData(StructWithDelegateField, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Delegate Field"); + yield return new TestCaseData(StructWithIndexer, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Indexer Field"); + yield return new TestCaseData(StructWithMethods, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Method Field"); + yield return new TestCaseData(StructWithConst, DiagnosticRules.StructHasConstFieldRule).SetName("Struct with Const Field"); + yield return new TestCaseData(StructWithProperty, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Property Field"); + yield return new TestCaseData(StructWithPrivateField, DiagnosticRules.StructHasPrivateFieldRule).SetName("Struct with Private Field"); yield return new TestCaseData(StructWithObjectField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Object Field"); yield return new TestCaseData(StructWithDynamicField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Dynamic Field"); - yield return new TestCaseData(StructWithByteField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Byte Field"); - yield return new TestCaseData(StructWithConstructor, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Constructor Field"); + // bytes are valid in structs I think? yield return new TestCaseData(StructWithByteField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Byte Field"); + yield return new TestCaseData(StructWithConstructor, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Constructor Field"); + yield return new TestCaseData(StructWithPrimitiveTypesMissingPublicKeyword, DiagnosticRules.StructHasPrivateFieldRule).SetName("Struct with Constructor Field"); // system.array tests yield return new TestCaseData(ArrayInstanceProperty1, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 1"); yield return new TestCaseData(ArrayInstanceProperty2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 2"); @@ -269,9 +269,9 @@ private static IEnumerable ValidCases get { // ReadOnlyArray / WriteOnlyArray Attribute - yield return new TestCaseData(Valid_ArrayParamAttrUnary_1).SetName("Valid - ArrayParamAttrUnary_1"); - yield return new TestCaseData(Valid_ArrayParamAttrUnary_2).SetName("Valid - ArrayParamAttrUnary_2"); - yield return new TestCaseData(Valid_ArrayParamAttrUnary_3).SetName("Valid - ArrayParamAttrUnary_3"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_1).SetName("Valid - Unary - Array marked read only"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_2).SetName("Valid - Unary - Array marked write only"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_3).SetName("Valid - Unary - Array marked out and write only"); yield return new TestCaseData(Valid_ArrayParamAttrUnary_4).SetName("Valid - ArrayParamAttrUnary_4"); yield return new TestCaseData(Valid_ArrayParamAttrUnary_5).SetName("Valid - ArrayParamAttrUnary_5"); yield return new TestCaseData(Valid_ArrayParamAttrBinary_1).SetName("Valid - ArrayParamAttrBinary_1"); @@ -354,6 +354,8 @@ private static IEnumerable ValidCases yield return new TestCaseData(Valid_Jagged2D_PrivateClassPublicMethods).SetName("Valid - Jagged Array private class / public method"); yield return new TestCaseData(Valid_Jagged3D_PrivateClassPublicMethods).SetName("Valid - Jagged Array private class / public method"); yield return new TestCaseData(Valid_Jagged3D_PublicClassPrivateMethods).SetName("Valid - Jagged Array public class / private method"); + yield return new TestCaseData(Valid_Jagged2D_Property).SetName("Valid - Jagged 2D Array public property"); + yield return new TestCaseData(Valid_Jagged3D_Property).SetName("Valid - Jagged 3D Array public property"); // overload attributes yield return new TestCaseData(Valid_TwoOverloads_DiffParamCount).SetName("Valid - DefaultOverload attribute 1"); yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_OneInList).SetName("Valid - DefaultOverload attribute 2"); diff --git a/src/cswinrt.sln b/src/cswinrt.sln index ba0119d64..983665fc2 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -79,8 +79,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AuthoringSample", "Authorin EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringConsumptionTest", "Authoring\AuthoringConsumptionTest\AuthoringConsumptionTest.vcxproj", "{0212A7C5-8D3F-443C-9EBC-1F28091FDF88}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestDiagnostics", "Authoring\TestDiagnostics\TestDiagnostics.csproj", "{9D94052B-137A-40EE-957C-8B9E355FA15C}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{6DA854DB-57BF-4FDD-AFF6-F70C965F48F6}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{CFB651EC-DAA4-4A11-ABCD-C77F90602EB5}" @@ -94,7 +92,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_component_derived", "T {13333A6F-6A4A-48CD-865C-0F65135EB018} = {13333A6F-6A4A-48CD-865C-0F65135EB018} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiagnosticTests", "Authoring\DiagnosticTests\DiagnosticTests.csproj", "{FC05C557-C974-4CB3-9DA7-BB5476710E91}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiagnosticTests", "Authoring\DiagnosticTests\DiagnosticTests.csproj", "{FC05C557-C974-4CB3-9DA7-BB5476710E91}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -406,26 +404,6 @@ Global {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x64.Build.0 = Release|x64 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x86.ActiveCfg = Release|Win32 {0212A7C5-8D3F-443C-9EBC-1F28091FDF88}.Release|x86.Build.0 = Release|Win32 - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|ARM.ActiveCfg = Debug|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|ARM.Build.0 = Debug|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|ARM64.Build.0 = Debug|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|x64.ActiveCfg = Debug|x64 - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|x64.Build.0 = Debug|x64 - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|x86.ActiveCfg = Debug|x86 - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Debug|x86.Build.0 = Debug|x86 - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|Any CPU.Build.0 = Release|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|ARM.ActiveCfg = Release|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|ARM.Build.0 = Release|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|ARM64.ActiveCfg = Release|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|ARM64.Build.0 = Release|Any CPU - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|x64.ActiveCfg = Release|x64 - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|x64.Build.0 = Release|x64 - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|x86.ActiveCfg = Release|x86 - {9D94052B-137A-40EE-957C-8B9E355FA15C}.Release|x86.Build.0 = Release|x86 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Debug|Any CPU.ActiveCfg = Debug|Win32 {13333A6F-6A4A-48CD-865C-0F65135EB018}.Debug|ARM.ActiveCfg = Debug|ARM {13333A6F-6A4A-48CD-865C-0F65135EB018}.Debug|ARM.Build.0 = Debug|ARM @@ -504,6 +482,7 @@ Global {0212A7C5-8D3F-443C-9EBC-1F28091FDF88} = {DA5AE0BA-E43D-4282-BC80-807DDE0C22C0} {13333A6F-6A4A-48CD-865C-0F65135EB018} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} + {FC05C557-C974-4CB3-9DA7-BB5476710E91} = {DA5AE0BA-E43D-4282-BC80-807DDE0C22C0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5AE8C9D7-2613-4E1A-A4F2-579BAC28D0A2} From d2fc46ed1dacbb4c3c4a6efd97bc30b375bb90d8 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 15 Dec 2020 14:55:53 -0800 Subject: [PATCH 32/41] PR feedback 1 of 2 --- src/Authoring/DiagnosticTests/NegativeData.cs | 20 ++++++++++ src/Authoring/DiagnosticTests/PositiveData.cs | 3 +- .../DiagnosticTests/UnitTestDiagnostics.cs | 4 ++ .../WinRT.SourceGenerator/DiagnosticUtils.cs | 37 ++++++++----------- .../WinRT.SourceGenerator/Generator.cs | 6 +-- 5 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/Authoring/DiagnosticTests/NegativeData.cs b/src/Authoring/DiagnosticTests/NegativeData.cs index 2ae838b66..cbf7580cf 100644 --- a/src/Authoring/DiagnosticTests/NegativeData.cs +++ b/src/Authoring/DiagnosticTests/NegativeData.cs @@ -916,6 +916,26 @@ public void ParamMarkedOut([Out] int arr) { } public sealed class OnlyParam { public void ArrayNotMarked(int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_11 = @" +public sealed class OnlyParam +{ + public void ParamMarkedIn([System.Runtime.InteropServices.In] int arr) { } +}"; + private const string TestArrayParamAttrUnary_12 = @" +public sealed class OnlyParam +{ + public void ParamMarkedOut([System.Runtime.InteropServices.Out] int arr) { } +}"; + private const string TestArrayParamAttrUnary_13 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedIn([System.Runtime.InteropServices.In] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_14 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedOut([System.Runtime.InteropServices.Out] int[] arr) { } }"; private const string TestArrayParamAttrBinary_1 = @" public sealed class TwoParam diff --git a/src/Authoring/DiagnosticTests/PositiveData.cs b/src/Authoring/DiagnosticTests/PositiveData.cs index 8b834d846..84374f411 100644 --- a/src/Authoring/DiagnosticTests/PositiveData.cs +++ b/src/Authoring/DiagnosticTests/PositiveData.cs @@ -2,9 +2,8 @@ namespace DiagnosticTests { public partial class TestDiagnostics { - // TODO: get the proper namespace for the Matrix3x2 type private const string Valid_StructWithWinRTField = @" -using ABI.System.Numerics; +using System.Numerics; namespace Test { public struct StructWithWinRTStructField diff --git a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs index d73a7ff32..b637efc99 100644 --- a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs +++ b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs @@ -186,6 +186,10 @@ private static IEnumerable InvalidCases yield return new TestCaseData(TestArrayParamAttrUnary_8, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_8"); yield return new TestCaseData(TestArrayParamAttrUnary_9, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_9"); yield return new TestCaseData(TestArrayParamAttrUnary_10, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrUnary_10"); + yield return new TestCaseData(TestArrayParamAttrUnary_11, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_11"); + yield return new TestCaseData(TestArrayParamAttrUnary_12, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_12"); + yield return new TestCaseData(TestArrayParamAttrUnary_13, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_13"); + yield return new TestCaseData(TestArrayParamAttrUnary_14, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_14"); yield return new TestCaseData(TestArrayParamAttrBinary_1, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_1"); yield return new TestCaseData(TestArrayParamAttrBinary_2, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_2"); yield return new TestCaseData(TestArrayParamAttrBinary_3, DiagnosticRules.ArrayOutputParamMarkedRead).SetName("TestArrayParamAttrBinary_3"); diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index e35909e8f..ce511360a 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -14,17 +14,13 @@ public class WinRTRules private bool ModifiersContains(SyntaxTokenList modifiers, string str) { - foreach (var modifier in modifiers) - { - if (SyntaxTokenIs(modifier, str)) { return true; } - } - return false; + return modifiers.Any(modifier => modifier.ValueText == str); } - private bool PropertyIsPublic(PropertyDeclarationSyntax p) { return ModifiersContains(p.Modifiers, "public"); } - private bool MethodIsPublic(MethodDeclarationSyntax m) { return ModifiersContains(m.Modifiers, "public"); } - public bool ClassIsPublic(ClassDeclarationSyntax c) { return ModifiersContains(c.Modifiers, "public"); } - public bool InterfaceIsPublic(InterfaceDeclarationSyntax i) { return ModifiersContains(i.Modifiers, "public"); } + public bool IsPublic(T p) where T : MemberDeclarationSyntax + { + return ModifiersContains(p.Modifiers, "public"); + } #endregion @@ -200,22 +196,21 @@ public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INam /// True if multiple constructors of the same arity exist for the given class public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { - IEnumerable constructors = classDeclaration.ChildNodes().OfType(); + IEnumerable constructors = classDeclaration.ChildNodes().OfType().Where(IsPublic); - // A true entry means a constructor of that arity has been seen - Dictionary aritiesSeenSoFar = new Dictionary(); + HashSet aritiesSeenSoFar = new HashSet(); foreach (ConstructorDeclarationSyntax constructor in constructors) { int arity = constructor.ParameterList.Parameters.Count; - if (aritiesSeenSoFar.ContainsKey(arity)) + if (aritiesSeenSoFar.Contains(arity)) { context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity)); return true; } else { - aritiesSeenSoFar[arity] = true; + aritiesSeenSoFar.Add(arity); } } return false; @@ -264,12 +259,12 @@ private bool SignatureContainsTypeName(ref GeneratorExecutionContext context, public bool OverloadsOperator(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { var operatorDeclarations = classDeclaration.DescendantNodes().OfType(); + foreach (var op in operatorDeclarations) { context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.OperatorOverloadedRule, op.GetLocation(), op.OperatorToken)); - return true; } - return false; + return operatorDeclarations.Count() != 0; } #region ArraySignatureChecking @@ -283,7 +278,7 @@ public bool OverloadsOperator(ref GeneratorExecutionContext context, ClassDeclar public bool CheckPropertiesForArrayTypes(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { bool found = false; - var props = classDeclaration.DescendantNodes().OfType().Where(PropertyIsPublic); + var props = classDeclaration.DescendantNodes().OfType().Where(IsPublic); foreach (var prop in props) { var loc = prop.GetLocation(); @@ -336,8 +331,8 @@ private bool ArrayIsntOneDim(IEnumerable arrTypes, ref Generato private bool ParamHasInOrOutAttribute(ParameterSyntax param) { - string baseString = ""; //"System.Runtime.InteropServices."; - return ParamHasAttribute(baseString + "In", param) || ParamHasAttribute(baseString + "Out", param); + string[] ls = new string[] { "In", "Out", "System.Runtime.InteropServices.In", "System.Runtime.InteropServices.Out" }; + return ls.Where(str => ParamHasAttribute(str, param)).Any(); } /// @@ -471,7 +466,7 @@ public bool ClassHasInvalidMethods(ref GeneratorExecutionContext context, ClassD * we check the elements of the map to raise diagnostics for those that didn't get attributed */ Dictionary overloadsWithoutAttributeMap = new Dictionary(); - foreach (MethodDeclarationSyntax method in methods.Where(MethodIsPublic)) + foreach (MethodDeclarationSyntax method in methods.Where(IsPublic)) { found |= CheckParamsForArrayAttributes(method, ref context); @@ -591,7 +586,7 @@ public bool StructHasFieldOfInvalidType(ref GeneratorExecutionContext context, bool found = false; /* No private fields allowed in Windows Runtime components */ - if (!ModifiersContains(field.Modifiers, "public")) + if (!IsPublic(field)) { context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); found |= true; diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index 67db4950a..8746e0508 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -111,7 +111,7 @@ private void GenerateSources(GeneratorExecutionContext context) context.AddSource(Path.GetFileNameWithoutExtension(file), SourceText.From(File.ReadAllText(file), Encoding.UTF8)); } - // Directory.Delete(outputDir, true); + Directory.Delete(outputDir, true); } private string GetWinmdOutputFile(GeneratorExecutionContext context) @@ -147,8 +147,8 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) var model = context.Compilation.GetSemanticModel(tree); var nodes = tree.GetRoot().DescendantNodes(); - var classes = nodes.OfType().Where(winrtRules.ClassIsPublic); - var interfaces = nodes.OfType().Where(winrtRules.InterfaceIsPublic); + var classes = nodes.OfType().Where(winrtRules.IsPublic); + var interfaces = nodes.OfType().Where(winrtRules.IsPublic); var structs = nodes.OfType(); // Used in the checking of structure fields From 33fff3286dd5b85c20d7d5215368b20ff5922b81 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 15 Dec 2020 14:59:31 -0800 Subject: [PATCH 33/41] remove old test project --- .../TestDiagnostics/Directory.Build.props | 9 ------ .../TestDiagnostics/Directory.Build.targets | 9 ------ .../TestDiagnostics/TestDiagnostics.csproj | 30 ------------------- 3 files changed, 48 deletions(-) delete mode 100644 src/Authoring/TestDiagnostics/Directory.Build.props delete mode 100644 src/Authoring/TestDiagnostics/Directory.Build.targets delete mode 100644 src/Authoring/TestDiagnostics/TestDiagnostics.csproj diff --git a/src/Authoring/TestDiagnostics/Directory.Build.props b/src/Authoring/TestDiagnostics/Directory.Build.props deleted file mode 100644 index 4cf186e3d..000000000 --- a/src/Authoring/TestDiagnostics/Directory.Build.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - true - - - - - diff --git a/src/Authoring/TestDiagnostics/Directory.Build.targets b/src/Authoring/TestDiagnostics/Directory.Build.targets deleted file mode 100644 index cee38e58e..000000000 --- a/src/Authoring/TestDiagnostics/Directory.Build.targets +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/Authoring/TestDiagnostics/TestDiagnostics.csproj b/src/Authoring/TestDiagnostics/TestDiagnostics.csproj deleted file mode 100644 index 548027368..000000000 --- a/src/Authoring/TestDiagnostics/TestDiagnostics.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - net5.0 - x64;x86 - preview - 1.0.0.0 - true - - false - true - $([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)', '$(IntermediateOutputPath)', 'Generated Files')) - Library - - - - - - - - - - - - - - - - - From 6a5b4df1f9a784c2aa20e256083e2a120cda4fc0 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 15 Dec 2020 15:39:47 -0800 Subject: [PATCH 34/41] working on new class name issue for struct fields --- src/Authoring/DiagnosticTests/NegativeData.cs | 22 +++++++++++++++++++ .../DiagnosticTests/UnitTestDiagnostics.cs | 1 + .../WinRT.SourceGenerator/Generator.cs | 7 +++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Authoring/DiagnosticTests/NegativeData.cs b/src/Authoring/DiagnosticTests/NegativeData.cs index cbf7580cf..f685adf50 100644 --- a/src/Authoring/DiagnosticTests/NegativeData.cs +++ b/src/Authoring/DiagnosticTests/NegativeData.cs @@ -682,6 +682,28 @@ public struct StructWithClass_Invalid public SillyClass classField; } }"; + private const string StructWithClassField2 = @" +namespace Test +{ + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + + public SillyClass() { } + } +} + +namespace Prod +{ + public struct StructWithClass_Invalid + { + public Test.SillyClass classField; + } +}"; + private const string StructWithDelegateField = @" namespace Test { public struct StructWithDelegate_Invalid diff --git a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs index b637efc99..d44dae3d8 100644 --- a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs +++ b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs @@ -223,6 +223,7 @@ private static IEnumerable InvalidCases yield return new TestCaseData(RefParam_InterfaceMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Interface"); // startuc field tests yield return new TestCaseData(StructWithClassField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Class Field"); + yield return new TestCaseData(StructWithClassField2, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Class Field2"); yield return new TestCaseData(StructWithDelegateField, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Delegate Field"); yield return new TestCaseData(StructWithIndexer, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Indexer Field"); yield return new TestCaseData(StructWithMethods, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Method Field"); diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index 8746e0508..93bd16b23 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -137,6 +137,11 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } + private string BuildClassName(ClassDeclarationSyntax classDeclaration) + { + NamespaceDeclarationSyntax @namespace = (NamespaceDeclarationSyntax)classDeclaration.Parent; + return @namespace.Name + "." + classDeclaration.Identifier.ToString(); + } private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) { @@ -157,7 +162,7 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) /* Check all classes */ foreach (ClassDeclarationSyntax classDeclaration in classes) { - classNames.Add(classDeclaration.Identifier.ToString()); + classNames.Add(BuildClassName(classDeclaration)); /* exports multidimensional array */ found |= winrtRules.CheckPropertiesForArrayTypes(ref context, classDeclaration); From 1b1ecb0a5ff35a4d48eea0b5d1994690531c1423 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Thu, 17 Dec 2020 12:11:42 -0800 Subject: [PATCH 35/41] Address feedback + missing some tests (#641) * more tests * cleanup * PR feedback --- src/Authoring/DiagnosticTests/NegativeData.cs | 3676 +++++++++-------- src/Authoring/DiagnosticTests/PositiveData.cs | 1625 ++++---- .../DiagnosticTests/UnitTestDiagnostics.cs | 80 +- .../WinRT.SourceGenerator/DiagnosticRules.cs | 11 +- .../WinRT.SourceGenerator/DiagnosticUtils.cs | 493 +-- .../WinRT.SourceGenerator/Generator.cs | 74 +- 6 files changed, 3138 insertions(+), 2821 deletions(-) diff --git a/src/Authoring/DiagnosticTests/NegativeData.cs b/src/Authoring/DiagnosticTests/NegativeData.cs index cbf7580cf..8ce049662 100644 --- a/src/Authoring/DiagnosticTests/NegativeData.cs +++ b/src/Authoring/DiagnosticTests/NegativeData.cs @@ -1,1658 +1,2018 @@ -namespace DiagnosticTests -{ - public partial class TestDiagnostics - { - // namespace tests -- WIP - private const string _NamespaceTest1 = @" -namespace Test -{ - namespace OtherNamespace_Valid - { - public sealed class Class1 - { - int x; - public Class1(int a) { x = a; } - } - } - - // WME1068 - public sealed class TestDiagnostics - { - bool b; - public TestDiagnostics(bool x) { b = x; } - } -} -}"; - private const string _NamespaceTest2 = @" -namespace OtherNamespace -{ - -// WME1044 ? - public sealed class Class1 - { - int x; - - public Class1(int a) - { - x = a; - } - } -}"; - private const string _NamespaceTest3 = @" -namespace Test -{ -// WME1067 ?? - namespace InnerNamespace - { - public sealed class Class1 - { - int x; - public Class1(int a) { x = a; } - } - } -}"; - // multidim array - private const string MultiDim_2DProp = @" -namespace Test -{ - public sealed class MultiDim_2DProp - { - public int[,] Arr_2d { get; set; } - private int[,] PrivArr_2d { get; set; } - } -}"; - private const string MultiDim_3DProp = @" -namespace Test -{ - public sealed class MultiDim_3DProp - { - public int[,,] Arr_3d { get; set; } - private int[,] PrivArr_2d { get; set; } - } -}"; - // 2d class - private const string MultiDim_2D_PublicClassPublicMethod1 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod1 - { - public int[,] D2_ReturnOnly() { return new int[4, 2]; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod2 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod2 - { - public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod3 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod3 - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod4 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod4 - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod5 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod5 - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod6 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod6 - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - } -}"; - // 3d class - private const string MultiDim_3D_PublicClassPublicMethod1 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod1 - { - public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod2 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod3 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod4 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod5 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod6 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } -}"; - // 2d iface - private const string MultiDim_2D_Interface1 = @" -namespace Test -{ - public interface MultiDim_2D_Interface1 - { - public int[,] D2_ReturnOnly(); - } -}"; - private const string MultiDim_2D_Interface2 = @" -namespace Test -{ - public interface MultiDim_2D_Interface2 - { - public int[,] D2_ReturnAndInput1(int[,] arr); - } -}"; - private const string MultiDim_2D_Interface3 = @" -namespace Test -{ - public interface MultiDim_2D_Interface3 - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); - } -}"; - private const string MultiDim_2D_Interface4 = @" -namespace Test -{ - public interface MultiDim_2D_Interface4 - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); - } -}"; - private const string MultiDim_2D_Interface5 = @" -namespace Test -{ - public interface MultiDim_2D_Interface5 - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); - } -}"; - private const string MultiDim_2D_Interface6 = @" -namespace Test -{ - public interface MultiDim_2D_Interface6 - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); - } -}"; - // 3d iface - private const string MultiDim_3D_Interface1 = @" -namespace Test -{ - public interface MultiDim_3D_Interface1 - { - public int[,,] D3_ReturnOnly(); - } -}"; - private const string MultiDim_3D_Interface2 = @" -namespace Test -{ - public interface MultiDim_3D_Interface2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr); - } -}"; - private const string MultiDim_3D_Interface3 = @" -namespace Test -{ - public interface MultiDim_3D_Interface3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); - } -}"; - private const string MultiDim_3D_Interface4 = @" -namespace Test -{ - public interface MultiDim_3D_Interface4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); - } -}"; - private const string MultiDim_3D_Interface5 = @" -namespace Test -{ - public interface MultiDim_3D_Interface5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); - } -}"; - private const string MultiDim_3D_Interface6 = @" -namespace Test -{ -public interface MultiDim_3D_Interface6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - -}"; - // subnamespace 2d iface - private const string SubNamespaceInterface_D2Method1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnOnly(); - } - } -}"; - private const string SubNamespaceInterface_D2Method2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnAndInput1(int[,] arr); - } - } -}"; - private const string SubNamespaceInterface_D2Method3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); - } - } -}"; - private const string SubNamespaceInterface_D2Method4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); - } - } -}"; - private const string SubNamespaceInterface_D2Method5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); - } - } -}"; - private const string SubNamespaceInterface_D2Method6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); - } - } -}"; - // subnamespace 3d iface - private const string SubNamespaceInterface_D3Method1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method1 - { - public int[,,] D3_ReturnOnly(); - } - } -}"; - private const string SubNamespaceInterface_D3Method2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr); - } - } -}"; - private const string SubNamespaceInterface_D3Method3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); - } - } -}"; - private const string SubNamespaceInterface_D3Method4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - } -}"; - private const string SubNamespaceInterface_D3Method5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); - } - } -}"; - private const string SubNamespaceInterface_D3Method6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - } -}"; - // system array - private const string ArrayInstanceProperty1 = @" -namespace Test -{ - // this might be valid... - public sealed class ArrayInstanceProperty1 - { - public int[] Arr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - } -}"; - private const string ArrayInstanceProperty2 = @" -namespace Test -{ -public sealed class ArrayInstanceProperty2 - { - public System.Array Arr - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - } -}"; - private const string ArrayInstanceProperty3 = @" -namespace Test -{ - // this might be valid... - public sealed class ArrayInstanceProperty3 - { - public int[] Arr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } - -}"; - private const string ArrayInstanceProperty4 = @" -namespace Test -{ -public sealed class ArrayInstanceProperty4 - { - public System.Array Arr - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } -}"; - private const string ArrayInstanceInterface1 = @" -namespace Test -{ - public interface ArrayInstanceInterface1 - { - System.Array Id(System.Array arr); - } -}"; - private const string ArrayInstanceInterface2 = @" -namespace Test -{ - public interface ArrayInstanceInterface2 - { - void Method2(System.Array arr); - } -}"; - private const string ArrayInstanceInterface3 = @" -namespace Test -{ - public interface ArrayInstanceInterface3 - { - System.Array Method3(); - } -}"; - private const string SystemArrayProperty5 = @" -namespace Test -{ - public sealed class SystemArrayProperty - { - public System.Array Arr { get; set; } - } -}"; - private const string SystemArrayJustReturn = @" -namespace Test -{ - public sealed class JustReturn - { - public System.Array SystemArrayMethod() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } -}"; - private const string SystemArrayUnaryAndReturn = @" -namespace Test -{ - public sealed class UnaryAndReturn - { - public System.Array SystemArrayMethod(System.Array arr) { return arr; } - } -}"; - private const string SystemArraySecondArgClass = @" -namespace Test -{ - public sealed class SecondArgClass - { - public bool SystemArrayMethod(bool a, System.Array arr) { return a; } - } -}"; - private const string SystemArraySecondArg2Class = @" -namespace Test -{ -public sealed class SecondArg2Class - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b) { return a; } - } -}"; - private const string SystemArraySecondArgAndReturnTypeClass = @" -namespace Test -{ - public sealed class SecondArgAndReturnType - { - public System.Array SystemArrayMethod(bool a, System.Array arr) { return arr; } - } -}"; - private const string SystemArraySecondArgAndReturnTypeClass2 = @" -namespace Test -{ - public sealed class SecondArgAndReturnTypeClass2 - { - public System.Array SystemArrayMethod(bool a, System.Array arr, bool b) { return arr; } - } -}"; - private const string SystemArrayNilArgsButReturnTypeInterface = @" -namespace Test -{ -public interface NilArgsButReturnTypeInterface - { - public System.Array SystemArrayMethod(); - } -}"; - private const string SystemArrayUnaryAndReturnTypeInterface = @" -namespace Test -{ -public interface UnaryAndReturnTypeInterface - { - public System.Array SystemArrayMethod(System.Array arr); - } -}"; - private const string SystemArraySecondArgAndReturnTypeInterface = @" -namespace Test -{ -public interface SecondArgAndReturnTypeInterface - { - public System.Array SystemArrayMethod(bool a, System.Array arr); - } -}"; - private const string SystemArraySecondArgAndReturnTypeInterface2 = @" -namespace Test -{ - public interface SecondArgAndReturnTypeInterface2 - { - public System.Array SystemArrayMetho(bool a, System.Array arr, bool b); - } -}"; - private const string SystemArraySecondArgInterface = @" -namespace Test -{ - public interface SecondArgInterface - { - public bool SystemArrayMethod(bool a, System.Array arr); - } -}"; - private const string SystemArraySecondArgInterface2 = @" -namespace Test -{ -public interface SecondArgInterface2 - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b); - } -}"; - private const string SystemArraySubNamespace_ReturnOnly = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_ReturnOnly - { - public System.Array SystemArrayMethod(); - } -} -}"; - private const string SystemArraySubNamespace_ReturnAndInput1 = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_ReturnAndInput1 - { - public System.Array SystemArrayMethod(System.Array arr); - } -} -}"; - private const string SystemArraySubNamespace_ReturnAndInput2of2 = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_ReturnAndInput2of2 - { - public System.Array SystemArrayMethod(bool a, System.Array arr); - } -} -}"; - private const string SystemArraySubNamespace_ReturnAndInput2of3 = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_ReturnAndInput2of3 - { - public System.Array SystemArrayMethod(bool a, System.Array arr, bool b); - } -} -}"; - private const string SystemArraySubNamespace_NotReturnAndInput2of2 = @" -namespace Test -{ - namespace SubNamespace -{ - public interface SubNamespace_NotReturnAndInput2of2 - { - public bool SystemArrayMethod(bool a, System.Array arr); - } -} -}"; - private const string SystemArraySubNamespace_NotReturnAndInput2of3 = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_NotReturnAndInput2of3 - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b); - } -} -}"; - // struct - private const string StructWithByteField = @" -namespace Test -{ -public struct StructWithByteField_Valid - { - public byte b; - } -}"; - private const string StructWithConstructor = @" - namespace Test -{ - public struct StructWithConstructor_Invalid - { - int X; - StructWithConstructor_Invalid(int x) - { - X = x; - } - } -} "; - private const string StructWithClassField = @" -namespace Test -{ - public sealed class SillyClass - { - public double Identity(double d) - { - return d; - } - - public SillyClass() { } - } - - public struct StructWithClass_Invalid - { - public SillyClass classField; - } -}"; - private const string StructWithDelegateField = @" -namespace Test { -public struct StructWithDelegate_Invalid - { - public delegate int ADelegate(int x); - } -}"; - private const string StructWithPrimitiveTypesMissingPublicKeyword = @" -namespace Test -{ - public struct StructWithAllValidFields - { - bool boolean; - char character; - decimal dec; - double dbl; - float flt; - int i; - uint nat; - long lng; - ulong ulng; - short sh; - ushort us; - string str; - } -}"; - // constructor of same arity - private const string ConstructorsOfSameArity = @" -namespace TestNamespace -{ -public sealed class SameArityConstructors -{ - private int num; - private string word; - - public SameArityConstructors(int i) - { - num = i; - word = ""dog""; - } - - public SameArityConstructors(string s) - { - num = 38; - word = s; - } -} -}"; - // async interfaces - private const string ImplementsIAsyncOperationWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class OpWithProgress : IAsyncOperationWithProgress - { - AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperationWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ImplementsIAsyncActionWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ -public class ActionWithProgress : IAsyncActionWithProgress - { - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ImplementsIAsyncOperation = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class Op : IAsyncOperation - { - AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperation.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ImplementsIAsyncAction = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class AsyAction : IAsyncAction - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - } -}"; - // readonlyarray / writeonlyarray attribute - private const string TestArrayParamAttrUnary_1 = @" -public sealed class OnlyParam -{ - public void BothAttributes_Separate([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_2 = @" -public sealed class OnlyParam -{ - public void BothAttributes_Together([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_3 = @" -public sealed class OnlyParam -{ - public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } -}"; - private const string TestArrayParamAttrUnary_4 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedIn([In] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_5 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedOut([Out] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_6 = @" -public sealed class OnlyParam -{ - public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrUnary_7 = @" -public sealed class OnlyParam -{ - public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrUnary_8 = @" -public sealed class OnlyParam -{ - public void ParamMarkedIn([In] int arr) { } -}"; - private const string TestArrayParamAttrUnary_9 = @" -public sealed class OnlyParam -{ - public void ParamMarkedOut([Out] int arr) { } -}"; - private const string TestArrayParamAttrUnary_10 = @" -public sealed class OnlyParam -{ - public void ArrayNotMarked(int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_11 = @" -public sealed class OnlyParam -{ - public void ParamMarkedIn([System.Runtime.InteropServices.In] int arr) { } -}"; - private const string TestArrayParamAttrUnary_12 = @" -public sealed class OnlyParam -{ - public void ParamMarkedOut([System.Runtime.InteropServices.Out] int arr) { } -}"; - private const string TestArrayParamAttrUnary_13 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedIn([System.Runtime.InteropServices.In] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_14 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedOut([System.Runtime.InteropServices.Out] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_1 = @" -public sealed class TwoParam -{ - public void BothAttributes_Separate(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_2 = @" -public sealed class TwoParam -{ - public void BothAttributes_Together(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_3 = @" -public sealed class TwoParam -{ - public void MarkedOutAndReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } -}"; - private const string TestArrayParamAttrBinary_4 = @" -public sealed class TwoParam -{ - public void ArrayMarkedIn(int i, [In] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_5 = @" -public sealed class TwoParam -{ - public void ArrayMarkedOut(int i, [Out] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_6 = @" -public sealed class TwoParam -{ - public void NonArrayMarkedReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrBinary_7 = @" -public sealed class TwoParam -{ - public void NonArrayMarkedWriteOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrBinary_8 = @" -public sealed class TwoParam -{ - public void ParamMarkedIn(int i, [In] int arr) { } -}"; - private const string TestArrayParamAttrBinary_9 = @" -public sealed class TwoParam -{ - public void ParamMarkedOut(int i, [Out] int arr) { } -}"; - private const string TestArrayParamAttrBinary_10 = @" -public sealed class TwoParam -{ - public void ArrayNotMarked(int i, int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_11 = @" -public sealed class TwoArray -{ - public void OneValidOneInvalid_1( -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] -[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] ys) { } -}"; - private const string TestArrayParamAttrBinary_12 = @" -public sealed class TwoArray -{ - public void OneValidOneInvalid_2( -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] -[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] ys) { } -}"; - private const string TestArrayParamAttrBinary_13 = @" -public sealed class TwoArray -{ - public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } -}"; - private const string TestArrayParamAttrBinary_14 = @" -public sealed class TwoParam -{ - public void ArrayMarkedIn(int i, [In] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_15 = @" -public sealed class TwoArray -{ - public void ArrayMarkedIn2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_16 = @" -public sealed class TwoArray -{ - public void ArrayMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_17 = @" -public sealed class TwoArray -{ - public void ArrayNotMarked(int i, int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_18 = @" -public sealed class TwoArray -{ - public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i) { } -}"; - private const string TestArrayParamAttrBinary_19 = @" -public sealed class TwoArray -{ - public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int i) { } -}"; - private const string TestArrayParamAttrBinary_20 = @" -public sealed class TwoArray -{ - public void NonArrayMarkedWriteOnly2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_21 = @" -public sealed class TwoArray -{ - public void ParamMarkedIn([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int arr) { } -}"; - private const string TestArrayParamAttrBinary_22 = @" -public sealed class TwoArray -{ - public void ParamMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int arr) { } -}"; - private const string TestArrayParamAttrBinary_23 = @" -public sealed class TwoArray -{ - public void ParamMarkedOut2([Out] int arr, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs) { } -}"; - private const string TestArrayParamAttrBinary_24 = @" -public sealed class TwoArray -{ - public void ArrayNotMarked([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, int[] arr) { } -}"; - // ref param - private const string RefParam_InterfaceMethod = @" -public interface IHaveAMethodWithRefParam - { - void foo(ref int i); - } -"; - private const string RefParam_ClassMethod = @" -public sealed class ClassWithMethodUsingRefParam - { - public void MethodWithRefParam(ref int i) { i++; } - } -"; - // operator overload - private const string OperatorOverload_Class = @" - public sealed class ClassThatOverloadsOperator - { - public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) - { - return thing; - } - }"; - // param name conflict - private const string DunderRetValParam = @" -public sealed class ParameterNamedDunderRetVal - { - public int Identity(int __retval) - { - return __retval; - } - } -"; - // struct fields - private const string StructWithIndexer = @" -namespace Test -{ -public struct StructWithIndexer_Invalid - { - int[] arr; - int this[int i] => arr[i]; - } -}"; - private const string StructWithMethods = @" -namespace Test -{ -public struct StructWithMethods_Invalid - { - int foo(int x) - { - return x; - } - } -}"; - private const string StructWithConst = @" -namespace Test -{ - public struct StructWithConst_Invalid - { - const int five = 5; - private int six; - } -}"; - private const string StructWithProperty = @" -namespace Test -{ - public enum BasicEnum - { - First = 0, - Second = 1 - } - - public struct Posn_Invalid - { - BasicEnum enumField; - - public int x { get; } - public int y { get; } - } -}"; - private const string StructWithPrivateField = @" -namespace Test -{ -public struct StructWithPrivateField_Invalid - { - const int ci = 5; - private int x; - } -}"; - private const string StructWithObjectField = @" -namespace Test -{ -public struct StructWithObjectField_Invalid - { - public object obj; - } -}"; - private const string StructWithDynamicField = @" -namespace Test -{ -public struct StructWithDynamicField_Invalid - { - public dynamic dyn; - } -}"; - // DefaultOverload attribute tests - private const string TwoOverloads_NoAttribute = @" -namespace Test -{ - public sealed class TwoOverloads_NoAttribute - { - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_OneInList = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInList - { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_NoAttribute_OneIrrevAttr = @" -namespace Test -{ - public sealed class TwoOverloads_NoAttribute_OneIrrevAttr - { - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInList = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInList - { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_TwoLists = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_TwoLists - { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot - { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInSeparateList = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInSeparateList - { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute - { - - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string ThreeOverloads_TwoAttributes = @" -namespace Test -{ - public sealed class ThreeOverloads_TwoAttributes - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public bool OverloadExample(bool b) { return b; } - } -}"; - // jagged 2d/3d prop - private const string Jagged2D_Property2 = @" -namespace Test -{ - public sealed class Jagged2D_Property2 - { - public int[][] Arr { get; set; } - } -}"; - private const string Jagged3D_Property1 = @" -namespace Test -{ - public sealed class Jagged3D_Property1 - { - public int[][][] Arr3 { get; set; } - } -}"; - // jagged 2d class method - private const string Jagged2D_ClassMethod1 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod1 - { - public int[][] J2_ReturnOnly() - { - int[][] arr = new int[2][]; - arr[0] = new int[1] { 1 }; - arr[1] = new int[1] { 2 }; - return arr; - } - - } -}"; - private const string Jagged2D_ClassMethod2 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod2 - { - public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } - } -}"; - private const string Jagged2D_ClassMethod3 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod3 - { - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } - } -}"; - private const string Jagged2D_ClassMethod4 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod4 - { - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } - } -}"; - private const string Jagged2D_ClassMethod5 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod5 - { - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } - } -}"; - private const string Jagged2D_ClassMethod6 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod6 - { - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - } -}"; - // jagged 3d class method - private const string Jagged3D_ClassMethod1 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod1 - { - public int[][][] J3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - - } -}"; - private const string Jagged3D_ClassMethod2 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod1 - { - public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } - } -}"; - private const string Jagged3D_ClassMethod3 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod3 - { - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - } -}"; - private const string Jagged3D_ClassMethod4 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod4 - { - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - } -}"; - private const string Jagged3D_ClassMethod5 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod5 - { - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - } -}"; - private const string Jagged3D_ClassMethod6 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod6 - { - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } -}"; - // jagged 2d interface method - private const string Jagged2D_InterfaceMethod1 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod1 - { - public int[][] J2_ReturnOnly(); - } -}"; - private const string Jagged2D_InterfaceMethod2 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod2 - { - public int[][] J2_ReturnAndInput1(int[,] arr); - } -}"; - private const string Jagged2D_InterfaceMethod3 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod3 - { - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); - } -}"; - private const string Jagged2D_InterfaceMethod4 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod4 - { - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); - } -}"; - private const string Jagged2D_InterfaceMethod5 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod5 - { - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); - } -}"; - private const string Jagged2D_InterfaceMethod6 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod6 - { - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); - } -}"; - // jagged 2d interface method - private const string Jagged3D_InterfaceMethod1 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod1 - { - public int[][][] J3_ReturnOnly(); - } -}"; - private const string Jagged3D_InterfaceMethod2 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod2 - { - public int[][][] J3_ReturnAndInput1(int[][][] arr); - } -}"; - private const string Jagged3D_InterfaceMethod3 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod3 - { - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); - } -}"; - private const string Jagged3D_InterfaceMethod4 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod4 - { - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); - } -}"; - private const string Jagged3D_InterfaceMethod5 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod5 - { - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); - } -}"; - private const string Jagged3D_InterfaceMethod6 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod6 - { - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); - } -}"; - // subnamespace jagged 2d iface - private const string SubNamespace_Jagged2DInterface1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface1 - { - public int[][] J2_ReturnOnly(); - } - } -}"; - private const string SubNamespace_Jagged2DInterface2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface2 - { - public int[][] J2_ReturnAndInput1(int[,] arr); - } - } -}"; - private const string SubNamespace_Jagged2DInterface3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface3 - { - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); - } - } -}"; - private const string SubNamespace_Jagged2DInterface4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface4 - { - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); - } - } -}"; - private const string SubNamespace_Jagged2DInterface5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface5 - { - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); - } - } -}"; - private const string SubNamespace_Jagged2DInterface6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface6 - { - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); - } - } -}"; - // subnamespace jagged 3d iface - private const string SubNamespace_Jagged3DInterface1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface1 - { - public int[][][] J3_ReturnOnly(); - } - } -}"; - private const string SubNamespace_Jagged3DInterface2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface2 - { - public int[][][] J3_ReturnAndInput1(int[][][] arr); - } - } -}"; - private const string SubNamespace_Jagged3DInterface3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface3 - { - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); - } - } -}"; - private const string SubNamespace_Jagged3DInterface4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface4 - { - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); - } - } -}"; - private const string SubNamespace_Jagged3DInterface5 = @" -namespace Test -{ - namespace SubNamespace - - { - public interface SubNamespace_Jagged3DInterface5 - { - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); - } - } -}"; - private const string SubNamespace_Jagged3DInterface6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface6 - { - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); - } - } -}"; - } -} +namespace DiagnosticTests +{ + public partial class TestDiagnostics + { + + // Cases to add -- WIP + private const string StructWithInterfaceField = @" +namespace Test +{ + public interface Foo + { + int Id(int i); + } + + public struct StructWithIface_Invalid + { + public Foo ifaceField; + } +}"; + + private const string UnsealedClass = @" +namespace Test +{ + public class UnsealedClass + { + public UnsealedClass() {} + } +}"; + private const string UnsealedClass2 = @" +namespace Test +{ + public class UnsealedClass + { + private UnsealedClass() {} + } +}"; + + private const string GenericClass = @" +namespace Test +{ + public sealed class GenericClass + { + public UnsealedClass() {} + } +}"; + private const string GenericInterface = @" +namespace Test +{ + public interface GenIface + { + int Foo(T input); + } +}"; + + private const string InterfaceInheritsException = @" +namespace Test +{ + public interface IfaceWithExceptions : System.Exception + { + int Foo(T input); + } +}"; + private const string ClassInheritsException = @" +namespace Test +{ + public sealed class ClassWithExceptions : System.Exception + { + public ClassWithExceptions() {} + } +}"; + + // namespace tests -- WIP + private const string _NamespaceTest1 = @" +namespace Test +{ + namespace OtherNamespace_Valid + { + public sealed class Class1 + { + int x; + public Class1(int a) { x = a; } + } + } + + // WME1068 + public sealed class TestDiagnostics + { + bool b; + public TestDiagnostics(bool x) { b = x; } + } +} +}"; + private const string _NamespaceTest2 = @" +namespace OtherNamespace +{ + +// WME1044 ? + public sealed class Class1 + { + int x; + + public Class1(int a) + { + x = a; + } + } +}"; + private const string _NamespaceTest3 = @" +namespace Test +{ +// WME1067 ?? + namespace InnerNamespace + { + public sealed class Class1 + { + int x; + public Class1(int a) { x = a; } + } + } +}"; + // multidim array + private const string MultiDim_2DProp = @" +namespace Test +{ + public sealed class MultiDim_2DProp + { + public int[,] Arr_2d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string MultiDim_3DProp = @" +namespace Test +{ + public sealed class MultiDim_3DProp + { + public int[,,] Arr_3d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string MultiDim_3DProp_Whitespace = @" +namespace Test +{ + public sealed class MultiDim_3DProp + { + public int[ , , ] Arr_3d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + // 2d class + private const string MultiDim_2D_PublicClassPublicMethod1 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod1 + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod2 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod2 + { + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod3 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod4 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod5 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod6 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + } +}"; + // 3d class + private const string MultiDim_3D_PublicClassPublicMethod1 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod1 + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod2 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod3 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod4 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod5 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod6 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + // 2d iface + private const string MultiDim_2D_Interface1 = @" +namespace Test +{ + public interface MultiDim_2D_Interface1 + { + public int[,] D2_ReturnOnly(); + } +}"; + private const string MultiDim_2D_Interface2 = @" +namespace Test +{ + public interface MultiDim_2D_Interface2 + { + public int[,] D2_ReturnAndInput1(int[,] arr); + } +}"; + private const string MultiDim_2D_Interface3 = @" +namespace Test +{ + public interface MultiDim_2D_Interface3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + } +}"; + private const string MultiDim_2D_Interface4 = @" +namespace Test +{ + public interface MultiDim_2D_Interface4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + } +}"; + private const string MultiDim_2D_Interface5 = @" +namespace Test +{ + public interface MultiDim_2D_Interface5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + } +}"; + private const string MultiDim_2D_Interface6 = @" +namespace Test +{ + public interface MultiDim_2D_Interface6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + } +}"; + // 3d iface + private const string MultiDim_3D_Interface1 = @" +namespace Test +{ + public interface MultiDim_3D_Interface1 + { + public int[,,] D3_ReturnOnly(); + } +}"; + private const string MultiDim_3D_Interface2 = @" +namespace Test +{ + public interface MultiDim_3D_Interface2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface3 = @" +namespace Test +{ + public interface MultiDim_3D_Interface3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface4 = @" +namespace Test +{ + public interface MultiDim_3D_Interface4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + } +}"; + private const string MultiDim_3D_Interface5 = @" +namespace Test +{ + public interface MultiDim_3D_Interface5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface6 = @" +namespace Test +{ +public interface MultiDim_3D_Interface6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + +}"; + // subnamespace 2d iface + private const string SubNamespaceInterface_D2Method1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnOnly(); + } + } +}"; + private const string SubNamespaceInterface_D2Method2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput1(int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + } + } +}"; + private const string SubNamespaceInterface_D2Method5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + } + } +}"; + // subnamespace 3d iface + private const string SubNamespaceInterface_D3Method1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method1 + { + public int[,,] D3_ReturnOnly(); + } + } +}"; + private const string SubNamespaceInterface_D3Method2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + } +}"; + private const string SubNamespaceInterface_D3Method5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + } +}"; + // system array + private const string ArrayInstanceProperty1 = @" +namespace Test +{ + // this might be valid... + public sealed class ArrayInstanceProperty1 + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } +}"; + private const string ArrayInstanceProperty2 = @" +namespace Test +{ +public sealed class ArrayInstanceProperty2 + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } +}"; + private const string ArrayInstanceProperty3 = @" +namespace Test +{ + // this might be valid... + public sealed class ArrayInstanceProperty3 + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + +}"; + private const string ArrayInstanceProperty4 = @" +namespace Test +{ +public sealed class ArrayInstanceProperty4 + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } +}"; + private const string ArrayInstanceInterface1 = @" +namespace Test +{ + public interface ArrayInstanceInterface1 + { + System.Array Id(System.Array arr); + } +}"; + private const string ArrayInstanceInterface2 = @" +namespace Test +{ + public interface ArrayInstanceInterface2 + { + void Method2(System.Array arr); + } +}"; + private const string ArrayInstanceInterface3 = @" +namespace Test +{ + public interface ArrayInstanceInterface3 + { + System.Array Method3(); + } +}"; + private const string SystemArrayProperty5 = @" +namespace Test +{ + public sealed class SystemArrayProperty + { + public System.Array Arr { get; set; } + } +}"; + private const string SystemArrayJustReturn = @" +namespace Test +{ + public sealed class JustReturn + { + public System.Array SystemArrayMethod() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string SystemArrayUnaryAndReturn = @" +namespace Test +{ + public sealed class UnaryAndReturn + { + public System.Array SystemArrayMethod(System.Array arr) { return arr; } + } +}"; + private const string SystemArraySecondArgClass = @" +namespace Test +{ + public sealed class SecondArgClass + { + public bool SystemArrayMethod(bool a, System.Array arr) { return a; } + } +}"; + private const string SystemArraySecondArg2Class = @" +namespace Test +{ +public sealed class SecondArg2Class + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string SystemArraySecondArgAndReturnTypeClass = @" +namespace Test +{ + public sealed class SecondArgAndReturnType + { + public System.Array SystemArrayMethod(bool a, System.Array arr) { return arr; } + } +}"; + private const string SystemArraySecondArgAndReturnTypeClass2 = @" +namespace Test +{ + public sealed class SecondArgAndReturnTypeClass2 + { + public System.Array SystemArrayMethod(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string SystemArrayNilArgsButReturnTypeInterface = @" +namespace Test +{ +public interface NilArgsButReturnTypeInterface + { + public System.Array SystemArrayMethod(); + } +}"; + private const string SystemArrayUnaryAndReturnTypeInterface = @" +namespace Test +{ +public interface UnaryAndReturnTypeInterface + { + public System.Array SystemArrayMethod(System.Array arr); + } +}"; + private const string SystemArraySecondArgAndReturnTypeInterface = @" +namespace Test +{ +public interface SecondArgAndReturnTypeInterface + { + public System.Array SystemArrayMethod(bool a, System.Array arr); + } +}"; + private const string SystemArraySecondArgAndReturnTypeInterface2 = @" +namespace Test +{ + public interface SecondArgAndReturnTypeInterface2 + { + public System.Array SystemArrayMetho(bool a, System.Array arr, bool b); + } +}"; + private const string SystemArraySecondArgInterface = @" +namespace Test +{ + public interface SecondArgInterface + { + public bool SystemArrayMethod(bool a, System.Array arr); + } +}"; + private const string SystemArraySecondArgInterface2 = @" +namespace Test +{ +public interface SecondArgInterface2 + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b); + } +}"; + private const string SystemArraySubNamespace_ReturnOnly = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_ReturnOnly + { + public System.Array SystemArrayMethod(); + } +} +}"; + private const string SystemArraySubNamespace_ReturnAndInput1 = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_ReturnAndInput1 + { + public System.Array SystemArrayMethod(System.Array arr); + } +} +}"; + private const string SystemArraySubNamespace_ReturnAndInput2of2 = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_ReturnAndInput2of2 + { + public System.Array SystemArrayMethod(bool a, System.Array arr); + } +} +}"; + private const string SystemArraySubNamespace_ReturnAndInput2of3 = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_ReturnAndInput2of3 + { + public System.Array SystemArrayMethod(bool a, System.Array arr, bool b); + } +} +}"; + private const string SystemArraySubNamespace_NotReturnAndInput2of2 = @" +namespace Test +{ + namespace SubNamespace +{ + public interface SubNamespace_NotReturnAndInput2of2 + { + public bool SystemArrayMethod(bool a, System.Array arr); + } +} +}"; + private const string SystemArraySubNamespace_NotReturnAndInput2of3 = @" +namespace Test +{ + namespace SubNamespace +{ +public interface SubNamespace_NotReturnAndInput2of3 + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b); + } +} +}"; + // constructor of same arity + private const string ConstructorsOfSameArity = @" +namespace TestNamespace +{ + public sealed class SameArityConstructors + { + private int num; + private string word; + + public SameArityConstructors(int i) + { + num = i; + word = ""dog""; + } + + public SameArityConstructors(string s) + { + num = 38; + word = s; + } + } +}"; + // async interfaces + private const string ClassImplementsIAsyncOperationWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperationWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncActionWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncOperation = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncAction = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class AsyAction : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string InterfaceImplementsIAsyncOperationWithProgress = @" +using Windows.Foundation; using System; +namespace TestNamespace +{ + public interface OpWithProgress : IAsyncOperationWithProgress {} +}"; + private const string InterfaceImplementsIAsyncActionWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public class ActionWithProgress : IAsyncActionWithProgress {} +}"; + private const string InterfaceImplementsIAsyncOperation = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public interface IAsyncOperation : IAsyncOperation {} +}"; + private const string InterfaceImplementsIAsyncAction = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public interface AsyAction : IAsyncAction {} +}"; + private const string InterfaceImplementsIAsyncOperationWithProgress2 = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public interface OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + void IAsyncInfo.Close(); + int IAsyncOperationWithProgress.GetResults(); + } +}"; + private const string InterfaceImplementsIAsyncActionWithProgress2 = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string InterfaceImplementsIAsyncOperation2 = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string InterfaceImplementsIAsyncAction2 = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class AsyAction : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +}"; + + // readonlyarray / writeonlyarray attribute + private const string TestArrayParamAttrUnary_1 = @" +public sealed class OnlyParam +{ + public void BothAttributes_Separate([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_2 = @" +public sealed class OnlyParam +{ + public void BothAttributes_Together([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_3 = @" +public sealed class OnlyParam +{ + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } +}"; + private const string TestArrayParamAttrUnary_4 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedIn([In] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_5 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedOut([Out] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_6 = @" +public sealed class OnlyParam +{ + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrUnary_7 = @" +public sealed class OnlyParam +{ + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrUnary_8 = @" +public sealed class OnlyParam +{ + public void ParamMarkedIn([In] int arr) { } +}"; + private const string TestArrayParamAttrUnary_9 = @" +public sealed class OnlyParam +{ + public void ParamMarkedOut([Out] int arr) { } +}"; + private const string TestArrayParamAttrUnary_10 = @" +public sealed class OnlyParam +{ + public void ArrayNotMarked(int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_11 = @" +public sealed class OnlyParam +{ + public void ParamMarkedIn([System.Runtime.InteropServices.In] int arr) { } +}"; + private const string TestArrayParamAttrUnary_12 = @" +public sealed class OnlyParam +{ + public void ParamMarkedOut([System.Runtime.InteropServices.Out] int arr) { } +}"; + private const string TestArrayParamAttrUnary_13 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedIn([System.Runtime.InteropServices.In] int[] arr) { } +}"; + private const string TestArrayParamAttrUnary_14 = @" +public sealed class OnlyParam +{ + public void ArrayMarkedOut([System.Runtime.InteropServices.Out] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_1 = @" +public sealed class TwoParam +{ + public void BothAttributes_Separate(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_2 = @" +public sealed class TwoParam +{ + public void BothAttributes_Together(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_3 = @" +public sealed class TwoParam +{ + public void MarkedOutAndReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } +}"; + private const string TestArrayParamAttrBinary_4 = @" +public sealed class TwoParam +{ + public void ArrayMarkedIn(int i, [In] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_5 = @" +public sealed class TwoParam +{ + public void ArrayMarkedOut(int i, [Out] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_6 = @" +public sealed class TwoParam +{ + public void NonArrayMarkedReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrBinary_7 = @" +public sealed class TwoParam +{ + public void NonArrayMarkedWriteOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } +}"; + private const string TestArrayParamAttrBinary_8 = @" +public sealed class TwoParam +{ + public void ParamMarkedIn(int i, [In] int arr) { } +}"; + private const string TestArrayParamAttrBinary_9 = @" +public sealed class TwoParam +{ + public void ParamMarkedOut(int i, [Out] int arr) { } +}"; + private const string TestArrayParamAttrBinary_10 = @" +public sealed class TwoParam +{ + public void ArrayNotMarked(int i, int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_11 = @" +public sealed class TwoArray +{ + public void OneValidOneInvalid_1( +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] +[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] ys) { } +}"; + private const string TestArrayParamAttrBinary_12 = @" +public sealed class TwoArray +{ + public void OneValidOneInvalid_2( +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] +[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, +[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] ys) { } +}"; + private const string TestArrayParamAttrBinary_13 = @" +public sealed class TwoArray +{ + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } +}"; + private const string TestArrayParamAttrBinary_14 = @" +public sealed class TwoParam +{ + public void ArrayMarkedIn(int i, [In] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_15 = @" +public sealed class TwoArray +{ + public void ArrayMarkedIn2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_16 = @" +public sealed class TwoArray +{ + public void ArrayMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_17 = @" +public sealed class TwoArray +{ + public void ArrayNotMarked(int i, int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_18 = @" +public sealed class TwoArray +{ + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i) { } +}"; + private const string TestArrayParamAttrBinary_19 = @" +public sealed class TwoArray +{ + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int i) { } +}"; + private const string TestArrayParamAttrBinary_20 = @" +public sealed class TwoArray +{ + public void NonArrayMarkedWriteOnly2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } +}"; + private const string TestArrayParamAttrBinary_21 = @" +public sealed class TwoArray +{ + public void ParamMarkedIn([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int arr) { } +}"; + private const string TestArrayParamAttrBinary_22 = @" +public sealed class TwoArray +{ + public void ParamMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int arr) { } +}"; + private const string TestArrayParamAttrBinary_23 = @" +public sealed class TwoArray +{ + public void ParamMarkedOut2([Out] int arr, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs) { } +}"; + private const string TestArrayParamAttrBinary_24 = @" +public sealed class TwoArray +{ + public void ArrayNotMarked([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, int[] arr) { } +}"; + // ref param + private const string RefParam_InterfaceMethod = @" +public interface IHaveAMethodWithRefParam + { + void foo(ref int i); + } +"; + private const string RefParam_ClassMethod = @" +public sealed class ClassWithMethodUsingRefParam + { + public void MethodWithRefParam(ref int i) { i++; } + } +"; + // operator overload + private const string OperatorOverload_Class = @" + public sealed class ClassThatOverloadsOperator + { + public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) + { + return thing; + } + }"; + // param name conflict + private const string DunderRetValParam = @" +public sealed class ParameterNamedDunderRetVal + { + public int Identity(int __retval) + { + return __retval; + } + } +"; + // struct fields + private const string StructWithConstructor = @" + namespace Test +{ + public struct StructWithConstructor_Invalid + { + int X; + StructWithConstructor_Invalid(int x) + { + X = x; + } + } +} "; + private const string StructWithClassField = @" +namespace Test +{ + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + + public SillyClass() { } + } + + public struct StructWithClass_Invalid + { + public SillyClass classField; + } +}"; + private const string StructWithClassField2 = @" +namespace Test +{ + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + + public SillyClass() { } + } +} + +namespace Prod +{ + public struct StructWithClass_Invalid + { + public Test.SillyClass classField; + } +}"; + private const string StructWithDelegateField = @" +namespace Test { +public struct StructWithDelegate_Invalid + { + public delegate int ADelegate(int x); + } +}"; + private const string StructWithPrimitiveTypesMissingPublicKeyword = @" +namespace Test +{ + public struct StructWithAllValidFields + { + bool boolean; + char character; + decimal dec; + double dbl; + float flt; + int i; + uint nat; + long lng; + ulong ulng; + short sh; + ushort us; + string str; + } +}"; + private const string EmptyStruct = @" +namespace Test +{ + public struct Mt {} +}"; + private const string StructWithIndexer = @" +namespace Test +{ +public struct StructWithIndexer_Invalid + { + int[] arr; + int this[int i] => arr[i]; + } +}"; + private const string StructWithMethods = @" +namespace Test +{ +public struct StructWithMethods_Invalid + { + int foo(int x) + { + return x; + } + } +}"; + private const string StructWithConst = @" +namespace Test +{ + public struct StructWithConst_Invalid + { + const int five = 5; + } +}"; + private const string StructWithProperty = @" +namespace Test +{ + public enum BasicEnum + { + First = 0, + Second = 1 + } + + public struct Posn_Invalid + { + BasicEnum enumField; + + public int x { get; } + public int y { get; } + } +}"; + private const string StructWithPrivateField = @" +namespace Test +{ +public struct StructWithPrivateField_Invalid + { + private int x; + } +}"; + private const string StructWithObjectField = @" +namespace Test +{ +public struct StructWithObjectField_Invalid + { + public object obj; + } +}"; + private const string StructWithDynamicField = @" +namespace Test +{ +public struct StructWithDynamicField_Invalid + { + public dynamic dyn; + } +}"; + private const string TwoOverloads_NoAttribute_NamesHaveNumber = @" +namespace Test +{ + public sealed class TwoOverloads_NoAttribute_WithNum + { + public string OverloadExample1(string s) { return s; } + + public int OverloadExample1(int n) { return n; } + } +}"; + // DefaultOverload attribute tests + private const string TwoOverloads_TwoAttribute_OneInList_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload] + public string OverloadExample(string s) { return s; } + + [DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInList_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_TwoLists_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_TwoLists + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInSeparateList_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInSeparateList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute + { + + [DefaultOverload] + public string OverloadExample(string s) { return s; } + + [DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string ThreeOverloads_TwoAttributes_Unqualified= @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class ThreeOverloads_TwoAttributes + { + public string OverloadExample(string s) { return s; } + + [DefaultOverload] + public int OverloadExample(int n) { return n; } + + [DefaultOverload] + public bool OverloadExample(bool b) { return b; } + } +}"; + private const string TwoOverloads_NoAttribute = @" +namespace Test +{ + public sealed class TwoOverloads_NoAttribute + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInList = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_NoAttribute_OneIrrevAttr = @" +namespace Test +{ + public sealed class TwoOverloads_NoAttribute_OneIrrevAttr + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInList = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_TwoLists = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_TwoLists + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInSeparateList = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInSeparateList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute + { + + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string ThreeOverloads_TwoAttributes = @" +namespace Test +{ + public sealed class ThreeOverloads_TwoAttributes + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } +}"; + // jagged 2d/3d prop + private const string Jagged2D_Property2 = @" +namespace Test +{ + public sealed class Jagged2D_Property2 + { + public int[][] Arr { get; set; } + } +}"; + private const string Jagged3D_Property1 = @" +namespace Test +{ + public sealed class Jagged3D_Property1 + { + public int[][][] Arr3 { get; set; } + } +}"; + // jagged 2d class method + private const string Jagged2D_ClassMethod1 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod1 + { + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + + } +}"; + private const string Jagged2D_ClassMethod2 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod2 + { + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + } +}"; + private const string Jagged2D_ClassMethod3 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + } +}"; + private const string Jagged2D_ClassMethod4 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + } +}"; + private const string Jagged2D_ClassMethod5 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + } +}"; + private const string Jagged2D_ClassMethod6 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } + } +}"; + // jagged 3d class method + private const string Jagged3D_ClassMethod1 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod1 + { + public int[][][] J3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + + } +}"; + private const string Jagged3D_ClassMethod2 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod1 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod3 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod4 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod5 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + } +}"; + private const string Jagged3D_ClassMethod6 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + // jagged 2d interface method + private const string Jagged2D_InterfaceMethod1 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod1 + { + public int[][] J2_ReturnOnly(); + } +}"; + private const string Jagged2D_InterfaceMethod2 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod2 + { + public int[][] J2_ReturnAndInput1(int[,] arr); + } +}"; + private const string Jagged2D_InterfaceMethod3 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + } +}"; + private const string Jagged2D_InterfaceMethod4 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + } +}"; + private const string Jagged2D_InterfaceMethod5 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + } +}"; + private const string Jagged2D_InterfaceMethod6 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); + } +}"; + // jagged 2d interface method + private const string Jagged3D_InterfaceMethod1 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod1 + { + public int[][][] J3_ReturnOnly(); + } +}"; + private const string Jagged3D_InterfaceMethod2 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod2 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod3 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod4 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + } +}"; + private const string Jagged3D_InterfaceMethod5 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod6 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } +}"; + // subnamespace jagged 2d iface + private const string SubNamespace_Jagged2DInterface1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface1 + { + public int[][] J2_ReturnOnly(); + } + } +}"; + private const string SubNamespace_Jagged2DInterface2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface2 + { + public int[][] J2_ReturnAndInput1(int[,] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + } + } +}"; + private const string SubNamespace_Jagged2DInterface6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); + } + } +}"; + // subnamespace jagged 3d iface + private const string SubNamespace_Jagged3DInterface1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface1 + { + public int[][][] J3_ReturnOnly(); + } + } +}"; + private const string SubNamespace_Jagged3DInterface2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface2 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + } +}"; + private const string SubNamespace_Jagged3DInterface5 = @" +namespace Test +{ + namespace SubNamespace + + { + public interface SubNamespace_Jagged3DInterface5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + } +}"; + } +} diff --git a/src/Authoring/DiagnosticTests/PositiveData.cs b/src/Authoring/DiagnosticTests/PositiveData.cs index 84374f411..e3e389222 100644 --- a/src/Authoring/DiagnosticTests/PositiveData.cs +++ b/src/Authoring/DiagnosticTests/PositiveData.cs @@ -1,802 +1,829 @@ namespace DiagnosticTests { - public partial class TestDiagnostics - { - private const string Valid_StructWithWinRTField = @" -using System.Numerics; -namespace Test -{ - public struct StructWithWinRTStructField - { - public Matrix3x2 matrix; - } -}"; - // ** DefaultOverload attribute - private const string Valid_TwoOverloads_DiffParamCount = @" -namespace Test -{ - public sealed class Valid_TwoOverloads_DiffParamCount - { - public string OverloadExample(string s) { return s; } - public int OverloadExample(int n, int m) { return n; } - } -}"; - private const string Valid_TwoOverloads_OneAttribute_OneInList = @" -namespace Test -{ -public sealed class Valid_TwoOverloads_OneAttribute_OneInList - { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - -}"; - private const string Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute = @" -namespace Test -{ - public sealed class Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute - { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string Valid_TwoOverloads_OneAttribute_TwoLists = @" -namespace Test -{ - public sealed class Valid_TwoOverloads_OneAttribute_TwoLists - { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } -}"; - private const string Valid_ThreeOverloads_OneAttribute = @" -namespace Test -{ - public sealed class Valid_ThreeOverloads_OneAttribute - { - - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - - public bool OverloadExample(bool b) { return b; } - } -}"; - private const string Valid_ThreeOverloads_OneAttribute_2 = @" -namespace Test -{ - public sealed class Valid_ThreeOverloads_OneAttribute_2 - { - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public bool OverloadExample(bool b) { return b; } - } -}"; - private const string Valid_TwoOverloads_OneAttribute_3 = @" -namespace Test -{ - public sealed class Valid_TwoOverloads_OneAttribute_3 - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - // ** Jagged array - private const string Valid_JaggedMix_PrivateClassPublicProperty = @" -namespace Test -{ - internal sealed class Valid_JaggedArray_PrivateClassPublicProperty - { - private int[][] Arr { get; set; } - public int[][] ArrP { get; set; } - public int[][][] Arr3 { get; set; } - private int[][][] Arr3P { get; set; } - } -}"; - private const string Valid_Jagged2D_PrivateClassPublicMethods = @" -namespace Test -{ - internal sealed class Valid_JaggedArray_PrivateClassPublicMethods - { - public int[][] J2_ReturnOnly() - { - int[][] arr = new int[2][]; - arr[0] = new int[1] { 1 }; - arr[1] = new int[1] { 2 }; - return arr; - } - public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - } -}"; - private const string Valid_Jagged3D_PrivateClassPublicMethods = @" -namespace Test -{ - internal sealed class Valid_Jagged3D_PrivateClassPublicMethods - { - public int[][][] J3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } -}"; - private const string Valid_Jagged3D_PublicClassPrivateMethods = @" -namespace Test -{ -public sealed class Valid_Jagged3D_PublicClassPrivateMethods - { - private int[][][] D3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - private int[][][] D3_ReturnAndInput1(int[][][] arr) { return arr; } - private int[][][] D3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } -}"; - private const string Valid_Jagged2D_Property = @" -namespace Test -{ - public sealed class Jagged2D_Property1 - { - private int[][] ArrP { get; set; } - } -}"; - private const string Valid_Jagged3D_Property = @" -namespace Test -{ - public sealed class Jagged3D_Property2 - { - private int[][][] Arr3P { get; set; } - } -}"; - // prop - private const string Valid_MultiDimArray_PrivateClassPublicProperty1 = @" -namespace Test -{ -internal class Valid_MultiDimArray_PrivateClassPublicProperty1 - { - public int[,] Arr_2d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PrivateClassPublicProperty2 = @" -namespace Test -{ - - internal class Valid_MultiDimArray_PrivateClassPublicProperty2 - { - public int[,,] Arr_3d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PrivateClassPublicProperty3 = @" -namespace Test -{ -internal class Valid_MultiDimArray_PrivateClassPublicProperty3 - { - private int[,] PrivArr_2d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PrivateClassPublicProperty4 = @" -namespace Test -{ -internal class Valid_MultiDimArray_PrivateClassPublicProperty4 - { - private int[,,] PrivArr_3d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateProperty1 = @" -namespace Test -{ -public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 - { - private int[,] PrivArr_2d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateProperty2 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 - { - private int[,,] PrivArr_3d { get; set; } - } -}"; - // 2d - private const string Valid_2D_PrivateClass_PublicMethod1 = @" -namespace Test -{ -internal sealed class Valid_2D_PrivateClass_PublicMethod1 - { - public int[,] D2_ReturnOnly() { return new int[4, 2]; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod2 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod2 - { - public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod3 = @" -namespace Test -{ -internal sealed class Valid_2D_PrivateClass_PublicMethod3 - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod4 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod4 - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod5 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod5 - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod6 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod6 - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - } -}"; - // 3d - private const string Valid_3D_PrivateClass_PublicMethod1 = @" -namespace Test -{ -internal sealed class Valid_3D_PrivateClass_PublicMethod1 - { - public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod2 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod3 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod4 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod5 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod6 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } -}"; - // methods - private const string Valid_MultiDimArray_PublicClassPrivateMethod1 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 - { - private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod2 = @" -namespace Test -{ -public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 - { - private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod3 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty3 - { - private int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod4 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty4 - { - private int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod5 = @" -namespace Test -{ -public sealed class Valid_MultiDimArray_PublicClassPrivateProperty5 - { - private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod6 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty6 - { - private bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } -}"; - // ** System.Array - private const string Valid_SystemArray_Interface1 = @" -namespace Test -{ -internal interface Valid_SystemArray_Interface1 - { - System.Array Id(System.Array arr); - } -}"; - private const string Valid_SystemArray_Interface2 = @" -namespace Test -{ -internal interface Valid_SystemArray_Interface2 - { - void Method2(System.Array arr); - } -}"; - private const string Valid_SystemArray_Interface3 = @" -namespace Test -{ - internal interface Valid_SystemArray_Interface3 - { - System.Array Method3(); - } -}"; - private const string Valid_SystemArray_InternalClass1 = @" -namespace Test -{ -internal class Valid_SystemArray_InternalClass1 - { - public System.Array Arr_2d { get; set; } - } -}"; - private const string Valid_SystemArray_InternalClass2 = @" -namespace Test -{ -internal class Valid_SystemArray_InternalClass2 - { - - public System.Array Arr_3d { get; set; } - } -}"; - private const string Valid_SystemArray_InternalClass3 = @" -namespace Test -{ -internal class Valid_SystemArray_InternalClass3 - { - private System.Array PrivArr_2d { get; set; } - } -}"; - private const string Valid_SystemArray_InternalClass4 = @" -namespace Test -{ -internal class Valid_SystemArray_InternalClass4 - { - private System.Array PrivArr_3d { get; set; } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty1 = @" -namespace Test -{ -public sealed class Valid_SystemArray_PublicClassPrivateProperty1 - { - private System.Array PrivArr_2d { get; set; } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty2 = @" -using System; -namespace Test -{ -public sealed class Valid_SystemArray_PublicClassPrivateProperty2 - { - private Array PrivArr_3d { get; set; } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty3 = @" -namespace Test -{ -public sealed class Valid_SystemArrayPublicClassPrivateProperty3 - { - private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty4 = @" -namespace Test -{ -public sealed class Valid_SystemArrayPublicClassPrivateProperty4 - { - private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty5 = @" -namespace Test -{ -public sealed class Valid_SystemArrayPublicClassPrivateProperty1 - { - private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty6 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateProperty2 - { - private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods1 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_InternalClassPublicMethods1 - { - public System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods2 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_InternalClassPublicMethods2 - { - public System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods3 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_InternalClassPublicMethods3 - { - public System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods4 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_InternalClassPublicMethods4 - { - public bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods5 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_InternalClassPublicMethods5 - { - public bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods6 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_InternalClassPublicMethods6 - { - public System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty1 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_PrivateClassPublicProperty1 - { - public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty2 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_PrivateClassPublicProperty2 - { - public System.Array Arr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty3 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_PrivateClassPublicProperty3 - { - public int[] Arr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty4 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_PrivateClassPublicProperty4 - { - public System.Array Arr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty5 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_PrivateClassPublicProperty5 - { - private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty6 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_PrivateClassPublicProperty6 - { - private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty7 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_PrivateClassPublicProperty7 - { - private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty8 = @" -namespace Test -{ -internal sealed class Valid_SystemArray_PrivateClassPublicProperty8 - { - private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod1 = @" -namespace Test -{ -public sealed class Valid_SystemArrayPublicClassPrivateMethod1 - { - private System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod2 = @" -namespace Test -{ -public sealed class Valid_SystemArrayPublicClassPrivateMethod2 - { - private System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod3 = @" -namespace Test -{ -public sealed class Valid_SystemArrayPublicClassPrivateMethod3 - { - private System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod4 = @" -namespace Test -{ -public sealed class Valid_SystemArrayPublicClassPrivateMethod4 - { - private System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod5 = @" -namespace Test -{ -public sealed class Valid_SystemArrayPublicClassPrivateMethod5 - { - private bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod6 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateMethod6 - { - private bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - } -}"; - private const string Valid_SystemArrayProperty = @" -namespace Test -{ - public sealed class SystemArrayProperty_Valid - { - private System.Array PrivArr { get; set; } - } -}"; - // ReadOnlyArray / WriteOnlyArray - private const string Valid_ArrayParamAttrUnary_1 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public int GetSum([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } - } -}"; - private const string Valid_ArrayParamAttrUnary_2 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrUnary_3 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrUnary_4 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrUnary_5 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void ArrayNotMarked_Valid(out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_1 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public int GetSum(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } - } -}"; - private const string Valid_ArrayParamAttrBinary_2 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void MarkedWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrBinary_3 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void MarkedOutAndWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_4 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void MarkedOutOnly_Valid(int i, out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_5 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void ArrayNotMarked_Valid(int i, out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_6 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedReadOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrBinary_7 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrBinary_8 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_9 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedOut_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, out int[] arr) { arr = new int[] { }; } - } -}"; - // Struct field - private const string Valid_StructWithPrimitiveTypes = @" -namespace Test -{ - public struct StructWithAllValidFields - { - public bool boolean; - public char character; - public decimal dec; - public double dbl; - public float flt; - public int i; - public uint nat; - public long lng; - public ulong ulng; - public short sh; - public ushort us; - public string str; - } -}"; - - - - } + public partial class TestDiagnostics + { + // WIP + private const string Valid_NamespaceUse1 = @" +namespace My.WindowsComponent +{ + public sealed Class1 { public int X { get; set; } } + + namespace InnerComponent + { + public sealed class Class2 { public int Y { get; } } + } +} +"; + + //// DefaultOverload attribute + private const string Valid_TwoOverloads_DiffParamCount = @" +namespace Test +{ + public sealed class Valid_TwoOverloads_DiffParamCount + { + public string OverloadExample(string s) { return s; } + public int OverloadExample(int n, int m) { return n; } + } +}"; + private const string Valid_TwoOverloads_OneAttribute_OneInList = @" +namespace Test +{ +public sealed class Valid_TwoOverloads_OneAttribute_OneInList + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + +}"; + private const string Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute = @" +namespace Test +{ + public sealed class Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string Valid_TwoOverloads_OneAttribute_TwoLists = @" +namespace Test +{ + public sealed class Valid_TwoOverloads_OneAttribute_TwoLists + { + + [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string Valid_ThreeOverloads_OneAttribute = @" +namespace Test +{ + public sealed class Valid_ThreeOverloads_OneAttribute + { + + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + public bool OverloadExample(bool b) { return b; } + } +}"; + private const string Valid_ThreeOverloads_OneAttribute_2 = @" +namespace Test +{ + public sealed class Valid_ThreeOverloads_OneAttribute_2 + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } +}"; + private const string Valid_TwoOverloads_OneAttribute_3 = @" +namespace Test +{ + public sealed class Valid_TwoOverloads_OneAttribute_3 + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + //// Jagged array + private const string Valid_JaggedMix_PrivateClassPublicProperty = @" +namespace Test +{ + internal sealed class Valid_JaggedArray_PrivateClassPublicProperty + { + private int[][] Arr { get; set; } + public int[][] ArrP { get; set; } + public int[][][] Arr3 { get; set; } + private int[][][] Arr3P { get; set; } + } +}"; + private const string Valid_Jagged2D_PrivateClassPublicMethods = @" +namespace Test +{ + internal sealed class Valid_JaggedArray_PrivateClassPublicMethods + { + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } + } +}"; + private const string Valid_Jagged3D_PrivateClassPublicMethods = @" +namespace Test +{ + internal sealed class Valid_Jagged3D_PrivateClassPublicMethods + { + public int[][][] J3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + private const string Valid_Jagged3D_PublicClassPrivateMethods = @" +namespace Test +{ +public sealed class Valid_Jagged3D_PublicClassPrivateMethods + { + private int[][][] D3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + private int[][][] D3_ReturnAndInput1(int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + private const string Valid_Jagged2D_Property = @" +namespace Test +{ + public sealed class Jagged2D_Property1 + { + private int[][] ArrP { get; set; } + } +}"; + private const string Valid_Jagged3D_Property = @" +namespace Test +{ + public sealed class Jagged3D_Property2 + { + private int[][][] Arr3P { get; set; } + } +}"; + // prop + private const string Valid_MultiDimArray_PrivateClassPublicProperty1 = @" +namespace Test +{ +internal class Valid_MultiDimArray_PrivateClassPublicProperty1 + { + public int[,] Arr_2d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PrivateClassPublicProperty2 = @" +namespace Test +{ + + internal class Valid_MultiDimArray_PrivateClassPublicProperty2 + { + public int[,,] Arr_3d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PrivateClassPublicProperty3 = @" +namespace Test +{ +internal class Valid_MultiDimArray_PrivateClassPublicProperty3 + { + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PrivateClassPublicProperty4 = @" +namespace Test +{ +internal class Valid_MultiDimArray_PrivateClassPublicProperty4 + { + private int[,,] PrivArr_3d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateProperty1 = @" +namespace Test +{ +public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 + { + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateProperty2 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 + { + private int[,,] PrivArr_3d { get; set; } + } +}"; + // 2d + private const string Valid_2D_PrivateClass_PublicMethod1 = @" +namespace Test +{ +internal sealed class Valid_2D_PrivateClass_PublicMethod1 + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod2 = @" +namespace Test +{ + internal sealed class Valid_2D_PrivateClass_PublicMethod2 + { + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod3 = @" +namespace Test +{ +internal sealed class Valid_2D_PrivateClass_PublicMethod3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod4 = @" +namespace Test +{ + internal sealed class Valid_2D_PrivateClass_PublicMethod4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod5 = @" +namespace Test +{ + internal sealed class Valid_2D_PrivateClass_PublicMethod5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod6 = @" +namespace Test +{ + internal sealed class Valid_2D_PrivateClass_PublicMethod6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + } +}"; + // 3d + private const string Valid_3D_PrivateClass_PublicMethod1 = @" +namespace Test +{ +internal sealed class Valid_3D_PrivateClass_PublicMethod1 + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod2 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod3 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod4 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod5 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod6 = @" +namespace Test +{ + internal sealed class Valid_3D_PrivateClass_PublicMethod6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + // methods + private const string Valid_MultiDimArray_PublicClassPrivateMethod1 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 + { + private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod2 = @" +namespace Test +{ +public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 + { + private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod3 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty3 + { + private int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod4 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty4 + { + private int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod5 = @" +namespace Test +{ +public sealed class Valid_MultiDimArray_PublicClassPrivateProperty5 + { + private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod6 = @" +namespace Test +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty6 + { + private bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + //// System.Array + private const string Valid_SystemArray_Interface1 = @" +namespace Test +{ +internal interface Valid_SystemArray_Interface1 + { + System.Array Id(System.Array arr); + } +}"; + private const string Valid_SystemArray_Interface2 = @" +namespace Test +{ +internal interface Valid_SystemArray_Interface2 + { + void Method2(System.Array arr); + } +}"; + private const string Valid_SystemArray_Interface3 = @" +namespace Test +{ + internal interface Valid_SystemArray_Interface3 + { + System.Array Method3(); + } +}"; + private const string Valid_SystemArray_InternalClass1 = @" +namespace Test +{ +internal class Valid_SystemArray_InternalClass1 + { + public System.Array Arr_2d { get; set; } + } +}"; + private const string Valid_SystemArray_InternalClass2 = @" +namespace Test +{ +internal class Valid_SystemArray_InternalClass2 + { + + public System.Array Arr_3d { get; set; } + } +}"; + private const string Valid_SystemArray_InternalClass3 = @" +namespace Test +{ +internal class Valid_SystemArray_InternalClass3 + { + private System.Array PrivArr_2d { get; set; } + } +}"; + private const string Valid_SystemArray_InternalClass4 = @" +namespace Test +{ +internal class Valid_SystemArray_InternalClass4 + { + private System.Array PrivArr_3d { get; set; } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty1 = @" +namespace Test +{ +public sealed class Valid_SystemArray_PublicClassPrivateProperty1 + { + private System.Array PrivArr_2d { get; set; } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty2 = @" +using System; +namespace Test +{ +public sealed class Valid_SystemArray_PublicClassPrivateProperty2 + { + private Array PrivArr_3d { get; set; } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty3 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateProperty3 + { + private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty4 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateProperty4 + { + private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty5 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateProperty1 + { + private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty6 = @" +namespace Test +{ + public sealed class Valid_SystemArrayPublicClassPrivateProperty2 + { + private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods1 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods1 + { + public System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods2 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods2 + { + public System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods3 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods3 + { + public System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods4 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods4 + { + public bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods5 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods5 + { + public bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods6 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_InternalClassPublicMethods6 + { + public System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty1 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty1 + { + public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty2 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty2 + { + public System.Array Arr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty3 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty3 + { + public int[] Arr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty4 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty4 + { + public System.Array Arr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty5 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty5 + { + private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty6 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty6 + { + private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty7 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty7 + { + private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty8 = @" +namespace Test +{ +internal sealed class Valid_SystemArray_PrivateClassPublicProperty8 + { + private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod1 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod1 + { + private System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod2 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod2 + { + private System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod3 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod3 + { + private System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod4 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod4 + { + private System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod5 = @" +namespace Test +{ +public sealed class Valid_SystemArrayPublicClassPrivateMethod5 + { + private bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod6 = @" +namespace Test +{ + public sealed class Valid_SystemArrayPublicClassPrivateMethod6 + { + private bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string Valid_SystemArrayProperty = @" +namespace Test +{ + public sealed class SystemArrayProperty_Valid + { + private System.Array PrivArr { get; set; } + } +}"; + //// ReadOnlyArray / WriteOnlyArray + private const string Valid_ArrayParamAttrUnary_1 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public int GetSum([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } +}"; + private const string Valid_ArrayParamAttrUnary_2 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrUnary_3 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrUnary_4 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrUnary_5 = @" +namespace TestNamespace +{ + public sealed class OnlyParam + { + public void ArrayNotMarked_Valid(out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_1 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public int GetSum(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } +}"; + private const string Valid_ArrayParamAttrBinary_2 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void MarkedWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_3 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void MarkedOutAndWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_4 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void MarkedOutOnly_Valid(int i, out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_5 = @" +namespace TestNamespace +{ + public sealed class TwoParam + { + public void ArrayNotMarked_Valid(int i, out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_6 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedReadOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_7 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_8 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_9 = @" +namespace TestNamespace +{ + public sealed class TwoArray + { + public void MarkedOut_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, out int[] arr) { arr = new int[] { }; } + } +}"; + //// Struct field + private const string Valid_StructWithByteField = @" +namespace Test +{ +public struct StructWithByteField_Valid + { + public byte b; + } +}"; + private const string Valid_StructWithImportedStruct = @" +using System.Numerics; +namespace Test +{ + public struct StructWithWinRTStructField + { + public Matrix3x2 matrix; + } +}"; + private const string Valid_StructWithImportedStructQualified = @" +using System.Numerics; +namespace Test +{ + public struct StructWithWinRTStructField + { + public System.Numerics.Matrix3x2 matrix; + } +}"; + private const string Valid_StructWithPrimitiveTypes = @" +namespace Test +{ + public struct StructWithAllValidFields + { + public bool boolean; + public char character; + public decimal dec; + public double dbl; + public float flt; + public int i; + public uint nat; + public long lng; + public ulong ulng; + public short sh; + public ushort us; + public string str; + } +}"; + } } diff --git a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs index b637efc99..eaee3b3f5 100644 --- a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs +++ b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs @@ -9,25 +9,24 @@ namespace DiagnosticTests { [TestFixture] public partial class TestDiagnostics - { - - /// - /// CheckNoDiagnostic asserts that no diagnostics are raised on the - /// compilation produced from the cswinrt source generator based on the given source code - /// + { /// Add unit tests by creating a source code like this: /// private const string MyNewTest = @"namespace Test { ... }"; /// /// And have a DiagnosticDescriptor for the one to check for, they live in WinRT.SourceGenerator.DiagnosticRules /// - /// Then go to the DiagnosticValidData class here and add an entry for it - /// + /// Then go to the ValidCases/InvalidCases property here and add an entry for it + + + /// + /// CheckNoDiagnostic asserts that no diagnostics are raised on the + /// compilation produced from the cswinrt source generator based on the given source code /// /// [Test, TestCaseSource(nameof(ValidCases))] public void CheckNoDiagnostic(string source) { Compilation compilation = CreateCompilation(source); - RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); + RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); var WinRTDiagnostics = diagnosticsFound.Where(diag => diag.Id.StartsWith("WME")); Assert.That(!WinRTDiagnostics.Any()); } @@ -43,8 +42,8 @@ public void CodeHasDiagnostic(string testCode, DiagnosticDescriptor rule) RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); HashSet diagDescsFound = MakeDiagnosticSet(diagnosticsFound); Assert.That(diagDescsFound.Contains(rule)); - } - + } + #region InvalidTests private static IEnumerable InvalidCases { @@ -53,6 +52,7 @@ private static IEnumerable InvalidCases // multi-dimensional array tests yield return new TestCaseData(MultiDim_2DProp, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Array Property"); yield return new TestCaseData(MultiDim_3DProp, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Array Property"); + yield return new TestCaseData(MultiDim_3DProp_Whitespace, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Array Property With whitespace"); yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 1"); yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 2"); @@ -148,6 +148,27 @@ private static IEnumerable InvalidCases yield return new TestCaseData(SubNamespace_Jagged3DInterface6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 6"); // overload attribute tests + yield return new TestCaseData(TwoOverloads_NoAttribute_NamesHaveNumber, DiagnosticRules.MethodOverload_NeedDefaultAttribute) + .SetName("DefaultOverload - Need Attribute 1 - Name has number"); + yield return new TestCaseData(TwoOverloads_NoAttribute, DiagnosticRules.MethodOverload_NeedDefaultAttribute) + .SetName("DefaultOverload - Need Attribute 1"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInList_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Two Overloads, Two Attributes, One in list - Unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInList_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Two Overloads, Two Attributes, Both in list - Unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_TwoLists_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Two Overloads, Two Attributes, Two lists - Unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Two Overloads, One in separate list, one not - Unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInSeparateList_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Two Overlodas, Two Attributes, Both in separate list - Unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Two Overloads, Two Attributes - Unqualified"); + yield return new TestCaseData(ThreeOverloads_TwoAttributes_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) + .SetName("DefaultOverload - Three Overloads, Two Attributes - Unqualified"); + + yield return new TestCaseData(TwoOverloads_NoAttribute_NamesHaveNumber, DiagnosticRules.MethodOverload_NeedDefaultAttribute) + .SetName("DefaultOverload - Need Attribute 1 - Name has number"); yield return new TestCaseData(TwoOverloads_NoAttribute, DiagnosticRules.MethodOverload_NeedDefaultAttribute) .SetName("DefaultOverload - Need Attribute 1"); yield return new TestCaseData(TwoOverloads_NoAttribute_OneIrrevAttr, DiagnosticRules.MethodOverload_NeedDefaultAttribute) @@ -171,10 +192,21 @@ private static IEnumerable InvalidCases // multiple class constructors of same arity yield return new TestCaseData(ConstructorsOfSameArity, DiagnosticRules.ClassConstructorRule).SetName("Multiple constructors of same arity"); // implementing async interface - yield return new TestCaseData(ImplementsIAsyncOperation, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperation"); - yield return new TestCaseData(ImplementsIAsyncOperationWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperationWithProgress"); - yield return new TestCaseData(ImplementsIAsyncAction, DiagnosticRules.AsyncRule).SetName("Implements IAsyncAction"); - yield return new TestCaseData(ImplementsIAsyncActionWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncActionWithProgress"); + + yield return new TestCaseData(InterfaceImplementsIAsyncOperation, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncOperation"); + yield return new TestCaseData(InterfaceImplementsIAsyncOperationWithProgress, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncOperationWithProgress"); + yield return new TestCaseData(InterfaceImplementsIAsyncAction, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncAction"); + yield return new TestCaseData(InterfaceImplementsIAsyncActionWithProgress, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncActionWithProgress"); + + yield return new TestCaseData(InterfaceImplementsIAsyncOperation2, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncOperation in full"); + yield return new TestCaseData(InterfaceImplementsIAsyncOperationWithProgress2, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncOperationWithProgress in full"); + yield return new TestCaseData(InterfaceImplementsIAsyncAction2, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncAction in full"); + yield return new TestCaseData(InterfaceImplementsIAsyncActionWithProgress2, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncActionWithProgress in full"); + + yield return new TestCaseData(ClassImplementsIAsyncOperation, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperation"); + yield return new TestCaseData(ClassImplementsIAsyncOperationWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperationWithProgress"); + yield return new TestCaseData(ClassImplementsIAsyncAction, DiagnosticRules.AsyncRule).SetName("Implements IAsyncAction"); + yield return new TestCaseData(ClassImplementsIAsyncActionWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncActionWithProgress"); // readonly/writeonlyArray attribute yield return new TestCaseData(TestArrayParamAttrUnary_1, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrUnary_1"); yield return new TestCaseData(TestArrayParamAttrUnary_2, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrUnary_2"); @@ -221,8 +253,10 @@ private static IEnumerable InvalidCases // ref param yield return new TestCaseData(RefParam_ClassMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Class"); yield return new TestCaseData(RefParam_InterfaceMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Interface"); - // startuc field tests + // struct field tests + yield return new TestCaseData(EmptyStruct, DiagnosticRules.StructWithNoFieldsRule).SetName("Empty struct"); yield return new TestCaseData(StructWithClassField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Class Field"); + yield return new TestCaseData(StructWithClassField2, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Class Field2"); yield return new TestCaseData(StructWithDelegateField, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Delegate Field"); yield return new TestCaseData(StructWithIndexer, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Indexer Field"); yield return new TestCaseData(StructWithMethods, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Method Field"); @@ -231,9 +265,8 @@ private static IEnumerable InvalidCases yield return new TestCaseData(StructWithPrivateField, DiagnosticRules.StructHasPrivateFieldRule).SetName("Struct with Private Field"); yield return new TestCaseData(StructWithObjectField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Object Field"); yield return new TestCaseData(StructWithDynamicField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Dynamic Field"); - // bytes are valid in structs I think? yield return new TestCaseData(StructWithByteField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Byte Field"); yield return new TestCaseData(StructWithConstructor, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Constructor Field"); - yield return new TestCaseData(StructWithPrimitiveTypesMissingPublicKeyword, DiagnosticRules.StructHasPrivateFieldRule).SetName("Struct with Constructor Field"); + yield return new TestCaseData(StructWithPrimitiveTypesMissingPublicKeyword, DiagnosticRules.StructHasPrivateFieldRule).SetName("Struct with missing public field"); // system.array tests yield return new TestCaseData(ArrayInstanceProperty1, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 1"); yield return new TestCaseData(ArrayInstanceProperty2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 2"); @@ -262,12 +295,12 @@ private static IEnumerable InvalidCases yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 5/6"); yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 6/6"); } - } - + } + #endregion - + #region ValidTests - + private static IEnumerable ValidCases { get @@ -289,7 +322,8 @@ private static IEnumerable ValidCases yield return new TestCaseData(Valid_ArrayParamAttrBinary_9).SetName("Valid - ArrayParamAttrBinary_9"); // Struct field yield return new TestCaseData(Valid_StructWithPrimitiveTypes).SetName("Valid - Struct with only fields of basic types"); - yield return new TestCaseData(Valid_StructWithWinRTField).SetName("(TODO - fix the namespace) Valid - Struct with struct field"); + yield return new TestCaseData(Valid_StructWithImportedStruct).SetName("Valid - Struct with struct field"); + yield return new TestCaseData(Valid_StructWithImportedStructQualified).SetName("Valid - Struct with qualified struct field"); // SystemArray yield return new TestCaseData(Valid_SystemArrayProperty).SetName("Valid - System.Array private property"); yield return new TestCaseData(Valid_SystemArray_Interface1).SetName("Valid - System.Array internal interface 1"); diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index 5742f4758..f37ef44cb 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -25,6 +25,11 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes helpLinkUri: "https://docs.microsoft.com/en-us/previous-versions/hh977010(v=vs.110)"); } + public static DiagnosticDescriptor StructWithNoFieldsRule = MakeRule( + "WME1060", + "Empty struct rule", + "Structure {0} contains no public fields. Windows Runtime structures must contain at least one public field."); + public static DiagnosticDescriptor AsyncRule = MakeRule( "WME1084", "Async Interfaces Rule", @@ -79,8 +84,8 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor MethodOverload_NeedDefaultAttribute = MakeRule( "WME1085", "Multiple overloads seen, one needs a default", // todo better msg - //"The {0}-parameter overloads of {1}.{2} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); - // + //"The {0}-parameter overloads of {1}.{2} must have exactly one method specified as the default overload + // by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); "In class {2}: The {0}-parameter overloads of {1} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); public static DiagnosticDescriptor ArraySignature_JaggedArrayRule = MakeRule( @@ -98,7 +103,7 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor ArraySignature_SystemArrayRule = MakeRule( "WME10??", "Array signature found with System.Array instance, which is not a valid WinRT type", // todo better msg - // // + // // "In type {0}: the method {1} has signature that contains a System.Array instance; use a different type like List"); // "Method {0} has a multi-dimensional array of type {1} in its signature. Arrays in Windows Runtime must be one dimensional" diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index ce511360a..339194518 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -8,32 +8,48 @@ namespace Generator { public class WinRTRules { + private void Report(ref GeneratorExecutionContext context, DiagnosticDescriptor d, Location loc, params object[] args) + { + context.ReportDiagnostic(Diagnostic.Create(d, loc, args)); + } - #region ModifierHelpers - private bool SyntaxTokenIs(SyntaxToken stx, string str) { return stx.Value.Equals(str); } - - private bool ModifiersContains(SyntaxTokenList modifiers, string str) + private bool SymbolSetHasString(HashSet typeNames, string typeStr) { - return modifiers.Any(modifier => modifier.ValueText == str); + return typeNames.Where(sym => sym.ToString().Contains(typeStr)).Any(); } - public bool IsPublic(T p) where T : MemberDeclarationSyntax - { - return ModifiersContains(p.Modifiers, "public"); - } + private bool SyntaxTokenIs(SyntaxToken stx, string str) { return stx.Value.Equals(str); } + + private bool ModifiersContains(SyntaxTokenList modifiers, string str) { return modifiers.Any(modifier => modifier.ValueText == str); } + + public bool IsPublic(T p) where T : MemberDeclarationSyntax { return ModifiersContains(p.Modifiers, "public"); } - #endregion + private static bool ImplementsInterface(INamedTypeSymbol typeSymbol, string typeToCheck) + { + if (typeSymbol == null) + { + return false; + } - #region AttributeHelpers + if (typeSymbol.BaseType != null && typeSymbol.BaseType.MetadataName == typeToCheck) + { + return true; + } + + foreach (var implementedInterface in typeSymbol.AllInterfaces) + { + if (implementedInterface.MetadataName == typeToCheck) + { + return true; + } + } + return false; + } /// /// Attributes can come in one list or many, e.g. [A()][B()] vs. [A(),B()] - /// look at all possible attributes and see if any match the given string - /// - /// - /// attribute names need to be fully qualified, - /// e.g. DefaultOverload is really Windows.Foundation.Metadata.DefaultOverload - /// + /// look at all possible attributes and see if any match the given string + /// attribute names need to be fully qualified, e.g. DefaultOverload is really Windows.Foundation.Metadata.DefaultOverload /// all the syntax nodes that correspond to an attribute list /// true iff the given attribute is in the list private bool MatchesAnyAttribute(string attrName, SyntaxList ls) @@ -51,14 +67,6 @@ private bool MatchesAnyAttribute(string attrName, SyntaxList - /// Looks at all possible attributes on a given method declaration - /// - /// - /// returns true iff any are (string) equal to the given attribute name - /// - private bool MethodHasAttribute(string attrName, MethodDeclarationSyntax method) { return MatchesAnyAttribute(attrName, method.AttributeLists); } - /// /// Looks at all possible attributes on a given parameter declaration /// @@ -67,33 +75,68 @@ private bool MatchesAnyAttribute(string attrName, SyntaxList private bool ParamHasAttribute(string attrName, ParameterSyntax param) { return MatchesAnyAttribute(attrName, param.AttributeLists); } + private static readonly string[] InAndOutAttributeNames = { "In", "Out", "System.Runtime.InteropServices.In", "System.Runtime.InteropServices.Out" }; + private static readonly string[] OverloadAttributeNames = { "Windows.Foundation.Metadata.DefaultOverload", "DefaultOverload" }; + + private bool ParamHasInOrOutAttribute(ParameterSyntax param) + { + return InAndOutAttributeNames.Where(str => ParamHasAttribute(str, param)).Any(); + } + + private bool MethodHasDefaultOverloadAttribute(MethodDeclarationSyntax method) + { + return OverloadAttributeNames.Where(str => MatchesAnyAttribute(str, method.AttributeLists)).Any(); + } + + /// e.g. `int foo(out int i) { ... }` /// + /// True if the parameter has the `ref` modifier + private bool ParamMarkedOutput(ParameterSyntax param) { return ModifiersContains(param.Modifiers, "out"); } + + /// e.g. `int foo(ref int i) { ... }` + /// the parameter to look for the ref keyword on + /// True if the parameter has the `ref` modifier + private bool ParamMarkedRef(ParameterSyntax param) { return ModifiersContains(param.Modifiers, "ref"); } + + /* SimplifySyntaxTypeString + * returns the more common term for the given kind of syntax; used when creating a diagnostic for an invalid field in a struct */ + private string SimplifySyntaxTypeString(string syntaxType) + { + switch (syntaxType) + { + case "EventFieldDeclarationSyntax": return "event"; + case "ConstructorDeclarationSyntax": return "constructor"; + case "DelegateDeclarationSyntax": return "delegate"; + case "IndexerDeclarationSyntax": return "indexer"; + case "MethodDeclarationSyntax": return "method"; + case "OperatorDeclarationSyntax": return "operator"; + case "PropertyDeclarationSyntax": return "property"; + default: return "unknown syntax type: " + syntaxType; + } + } + /// - /// Keeps track of repeated declarations of a method (overloads) and raises diagnostics according to the rule that exactly one overload should be attributed the default - /// - /// - /// The method to check attributes for + /// Keeps track of repeated declarations of a method (overloads) and raises diagnostics according to the rule that exactly one overload should be attributed the default + /// Look for overloads of this method, checking the attributes as well attributes for /// - /// Keeps track of the method (via name + arity) and whether it was declared with the DefaultOverload attribute + /// Keeps track of the method (via qualified name + arity) and whether it was declared with the DefaultOverload attribute + /// this variable is ref because we are mutating this map with each method, so we only look at a method a second time if it has an overload but no attribute /// /// Keeps track of the methods that are overloads but don't have the DefaultOverload attribute (yet) - /// Used after this function executes, hence the reference parameter - /// + /// Used after this function executes, hence the reference parameter /// The class the method lives in -- used for creating the diagnostic - /// The SourceGenerator context the code lives in /// True iff multiple overloads of a method are found, where more than one has been designated as the default overload - private bool CheckOverloadAttributes(MethodDeclarationSyntax method, + private bool CheckOverloadAttributes(ref GeneratorExecutionContext context, + MethodDeclarationSyntax method, ref Dictionary methodHasAttributeMap, ref Dictionary overloadsWithoutAttributeMap, - SyntaxToken classId, - ref GeneratorExecutionContext context) + SyntaxToken classId) { bool found = false; int methodArity = method.ParameterList.Parameters.Count; string methodNameWithArity = method.Identifier.Text + methodArity.ToString(); // look at all the attributes on this method and see if any of them is the DefaultOverload attribute - bool hasDefaultOverloadAttribute = MethodHasAttribute("Windows.Foundation.Metadata.DefaultOverload", method); - + bool hasDefaultOverloadAttribute = MethodHasDefaultOverloadAttribute(method); bool seenMethodBefore = methodHasAttributeMap.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); // Do we have an overload ? @@ -108,15 +151,13 @@ private bool CheckOverloadAttributes(MethodDeclarationSyntax method, else if (hasDefaultOverloadAttribute && methodHasAttrAlready) { // raise the "can't have multiple default attributes" diagnostic - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.MethodOverload_MultipleDefaultAttribute, method.GetLocation(), - methodArity, method.Identifier, classId)); + Report(ref context, DiagnosticRules.MethodOverload_MultipleDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classId); found |= true; } else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) { // we could see this method later with the attribute, so hold onto the diagnostic for it until we know it doesn't have the attribute - Diagnostic diagnostic = Diagnostic.Create(DiagnosticRules.MethodOverload_NeedDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classId); - overloadsWithoutAttributeMap[methodNameWithArity] = diagnostic; + overloadsWithoutAttributeMap[methodNameWithArity] = Diagnostic.Create(DiagnosticRules.MethodOverload_NeedDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classId); } } else @@ -128,71 +169,35 @@ private bool CheckOverloadAttributes(MethodDeclarationSyntax method, return found; } - #endregion - - #region AsyncInterfaces - /* The full metadata name of Async interfaces that should not be implemented by Windows Runtime components */ - static string[] ProhibitedAsyncInterfaces = { + private static readonly string[] ProhibitedAsyncInterfaces = { "IAsyncAction", "IAsyncActionWithProgress`1", "IAsyncOperation`1", "IAsyncOperationWithProgress`2" }; - - private static bool ImplementsInterface(INamedTypeSymbol typeSymbol, string typeToCheck) - { - if (typeSymbol == null) - { - return false; - } - - if (typeSymbol.BaseType.MetadataName == typeToCheck) - { - return true; - } - - foreach (var implementedInterface in typeSymbol.AllInterfaces) - { - if (implementedInterface.MetadataName == typeToCheck) - { - return true; - } - } - - return false; - } - /// - /// returns true if the class represented by the symbol implements any of the interfaces defined in ProhibitedAsyncInterfaces - /// - /// - /// - /// + /// Returns true if the class represented by the symbol + /// implements any of the interfaces defined in ProhibitedAsyncInterfaces (e.g., IAsyncAction, ...) /// + /// /// True iff the given class implements any of the IAsync interfaces that are not valid in Windows Runtime - public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INamedTypeSymbol classSymbol, ClassDeclarationSyntax classDeclaration) + public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INamedTypeSymbol typeSymbol, T typeDeclaration) + where T : TypeDeclarationSyntax { foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) { - if (ImplementsInterface(classSymbol, prohibitedInterface)) + if (ImplementsInterface(typeSymbol, prohibitedInterface)) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.AsyncRule, classDeclaration.GetLocation(), classDeclaration.Identifier, prohibitedInterface)); + Report(ref context, DiagnosticRules.AsyncRule, typeDeclaration.GetLocation(), typeDeclaration.Identifier, prohibitedInterface); return true; - /* By exiting early, we only report diagnostic for first prohibited interface we see. - * If a class implemented 2 (or more) such interfaces, then we would only report diagnostic error for the first one. - * could thread `found` variable from CatchWinRTDiagnostics here as well, if we want more diagnostics reported */ } } return false; } - #endregion - /// - /// keeps track of the arity of all constructors, and reports the diagnostic (and exits) as soon as a two constructors of the same arity are seen. - /// - /// Object to raise diagnostic on - /// look for constructors of this class + /// Raises a diagnostic when multiple constructors for a class are defined with the same arity. + /// look for constructors of this class /// True if multiple constructors of the same arity exist for the given class public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { @@ -205,7 +210,7 @@ public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext con int arity = constructor.ParameterList.Parameters.Count; if (aritiesSeenSoFar.Contains(arity)) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity)); + Report(ref context, DiagnosticRules.ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity); return true; } else @@ -216,166 +221,110 @@ public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext con return false; } - /// - /// Checks each type in the given list of types and sees if any are equal to the given type name - /// - /// - /// - /// A list of the descendent nodes that are of the given type, possibly empty. - /// empty example: this property doesnt have any qualified types in its signature - /// - /// check to see if this type appears in the signature - /// name of the class this field is in - /// syntax location - /// either property or method + /// Checks each type in the given list of types and sees if any are equal to the given type name + /// + /// A list of the descendent nodes that are of the given type, possibly empty. + /// empty example: this property doesnt have any qualified types in its signature + /// check to see if this type appears in the signaturediagnostic to report if we see the typeName /// true if the given type is the same as the one in the list - private bool SignatureContainsTypeName(ref GeneratorExecutionContext context, - IEnumerable typesInSignature, - string typeName, - SyntaxToken classId, - Location loc, - SyntaxToken fieldKind) + private bool SignatureContainsTypeName(ref GeneratorExecutionContext context, IEnumerable typesInSignature, string typeName, Diagnostic diag) { foreach (T name in typesInSignature) { if (name.ToString().Equals(typeName)) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArraySignature_SystemArrayRule, loc, classId, fieldKind)); + context.ReportDiagnostic(diag); return true; } } return false; } - /// - /// Checks to see if the class declares any operators (overloading them) - /// - /// Compilation unit - /// + /// Checks to see if the class declares any operators (overloading them) + /// /// Class to check for operator declarations - /// operator declarations are just like method declarations except they use the `operator` keyword - /// + /// operator declarations are just like method declarations except they use the `operator` keyword /// True iff an operator is overloaded by the given class public bool OverloadsOperator(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) { var operatorDeclarations = classDeclaration.DescendantNodes().OfType(); - - foreach (var op in operatorDeclarations) - { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.OperatorOverloadedRule, op.GetLocation(), op.OperatorToken)); - } + foreach (var op in operatorDeclarations) { Report(ref context, DiagnosticRules.OperatorOverloadedRule, op.GetLocation(), op.OperatorToken); } return operatorDeclarations.Count() != 0; } - #region ArraySignatureChecking - - /// - /// Looks at all the properties of the given class and checks them for improper array types (System.Array instances, multidimensional, jagged) - /// - /// - /// + /// Looks at all the properties of the given class and checks them for improper array types (System.Array instances, multidimensional, jagged) + /// /// True iff any of the invalid array types are used in any of the propertyy signatures in the given class - public bool CheckPropertiesForArrayTypes(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + public bool CheckPropertySignature(ref GeneratorExecutionContext context, IEnumerable props, SyntaxToken typeId) { bool found = false; - var props = classDeclaration.DescendantNodes().OfType().Where(IsPublic); foreach (var prop in props) { var loc = prop.GetLocation(); var propId = prop.Identifier; - var classId = classDeclaration.Identifier; - - var qualName = prop.DescendantNodes().OfType(); - found |= SignatureContainsTypeName(ref context, qualName, "System.Array", classId, loc, propId); - var idName = prop.DescendantNodes().OfType(); - found |= SignatureContainsTypeName(ref context, idName, "Array", classId, loc, propId); + var qualifiedTypes = prop.DescendantNodes().OfType(); + var d = Diagnostic.Create(DiagnosticRules.ArraySignature_SystemArrayRule, loc, typeId, propId); + found |= SignatureContainsTypeName(ref context, qualifiedTypes, "System.Array", d); - found |= ArrayIsntOneDim(prop.DescendantNodes().OfType(), ref context, classId, propId, loc); + var types = prop.DescendantNodes().OfType(); + var d2 = Diagnostic.Create(DiagnosticRules.ArraySignature_SystemArrayRule, loc, typeId, propId); + found |= SignatureContainsTypeName(ref context, types, "Array", d2); + + found |= ArrayIsntOneDim(prop.DescendantNodes().OfType(), ref context, typeId, propId, loc); } return found; } /// - /// Look at all the array types and if any are of the form [][]+ or [,+] then raise the corresponding diagnostic and return true - /// - /// - /// - /// The type the array lives in - /// The code the array is a part of the signature for; e.g. property or method - /// + /// Look at all the array types and if any are of the form [][]+ or [,+] then raise the corresponding diagnostic and return true + /// The type the array lives in + /// The code the array is a part of the signature for; e.g. property or method /// True iff any of the array types given are multidimensional or jagged - private bool ArrayIsntOneDim(IEnumerable arrTypes, ref GeneratorExecutionContext context, SyntaxToken typeIdentifier, SyntaxToken fieldId, Location loc) + private bool ArrayIsntOneDim(IEnumerable arrTypes, + ref GeneratorExecutionContext context, + SyntaxToken typeIdentifier, + SyntaxToken fieldId, + Location loc) { foreach (var arrType in arrTypes) { var brackets = arrType.DescendantNodes().OfType(); - if (brackets.Count() > 1) // [][]+ ? + // [][]+ ? + if (brackets.Count() > 1) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArraySignature_JaggedArrayRule, loc, fieldId, typeIdentifier)); - return true; // could do or-eq on a `found` boolean instead of exiting as soon as we see invalid... + Report(ref context, DiagnosticRules.ArraySignature_JaggedArrayRule, loc, fieldId, typeIdentifier); + return true; } - // [,_] ? + // [,+] ? else if (brackets.Count() == 1 && brackets.First().ToString().Contains(",")) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArraySignature_MultiDimensionalArrayRule, loc, fieldId, typeIdentifier)); + Report(ref context, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule, loc, fieldId, typeIdentifier); return true; } } return false; } - - #endregion - - #region Parameters - - private bool ParamHasInOrOutAttribute(ParameterSyntax param) - { - string[] ls = new string[] { "In", "Out", "System.Runtime.InteropServices.In", "System.Runtime.InteropServices.Out" }; - return ls.Where(str => ParamHasAttribute(str, param)).Any(); - } - - /// - /// e.g. `int foo(out int i) { ... }` - /// - /// - /// - private bool ParamMarkedOutput(ParameterSyntax param) { return ModifiersContains(param.Modifiers, "out"); } - - /// - /// e.g. `int foo(ref int i) { ... }` - /// - /// the parameter to look for the ref keyword on - /// - private bool ParamMarkedRef(ParameterSyntax param) { return ModifiersContains(param.Modifiers, "ref"); } - + /// /// The code generation process makes functions with output param `__retval`, - /// we will shadow a user variable named the same thing -- so raise a diagnostic instead - /// - /// compilation unit to raise diagnostic on - /// the method whose parameteres we are inspecting - /// + /// we will shadow a user variable named the same thing -- so raise a diagnostic instead + /// compilation unit to raise diagnostic onthe method whose parameteres we are inspecting + /// True if any parameter is named "__retval" public bool HasConflictingParameterName(ref GeneratorExecutionContext context, MethodDeclarationSyntax method) { - foreach (ParameterSyntax parameter in method.ParameterList.Parameters) - { - if (SyntaxTokenIs(parameter.Identifier, "__retval")) - { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ParameterNamedValueRule, parameter.GetLocation(), method.Identifier, parameter.Identifier)); - return true; - } + var hasInvalidParams = method.ParameterList.Parameters.Where(param => SyntaxTokenIs(param.Identifier, "__retval")).Any(); + if (hasInvalidParams) + { + Report(ref context, DiagnosticRules.ParameterNamedValueRule, method.GetLocation(), method.Identifier); } - return false; + return hasInvalidParams; } /// /// Checks to see if an array parameter has been marked with both Write and Read attributes - /// Does extra work, by catching `ref` params, done here since this code can be used by class or interface related methods - /// - /// - /// - /// + /// Does extra work, by catching `ref` params, done here since this code can be used by class or interface related methods + /// /// true if array attributes are invalid (see summary) private bool CheckParamsForArrayAttributes(MethodDeclarationSyntax method, ref GeneratorExecutionContext context) { @@ -390,7 +339,7 @@ private bool CheckParamsForArrayAttributes(MethodDeclarationSyntax method, ref G // Nothing can be marked `ref` if (ParamMarkedRef(param)) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.RefParameterFound, method.GetLocation(), method.Identifier, param.Identifier)); + Report(ref context, DiagnosticRules.RefParameterFound, method.GetLocation(), param.Identifier); found |= true; } @@ -399,13 +348,13 @@ private bool CheckParamsForArrayAttributes(MethodDeclarationSyntax method, ref G // recommend using ReadOnlyArray or WriteOnlyArray if (isArrayType) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier)); + Report(ref context, DiagnosticRules.ArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier); found |= true; } // if not array type, stil can't use [In] or [Out] else { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.NonArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier)); + Report(ref context, DiagnosticRules.NonArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier); found |= true; } } @@ -415,27 +364,26 @@ private bool CheckParamsForArrayAttributes(MethodDeclarationSyntax method, ref G // can't be both ReadOnly and WriteOnly if (hasReadOnlyArray && hasWriteOnlyArray) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArrayParamMarkedBoth, method.GetLocation(), method.Identifier, param.Identifier)); + Report(ref context, DiagnosticRules.ArrayParamMarkedBoth, method.GetLocation(), method.Identifier, param.Identifier); found |= true; } // can't be both output (writeonly) and marked read only else if (hasReadOnlyArray && isOutputParam) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArrayOutputParamMarkedRead, method.GetLocation(), method.Identifier, param.Identifier)); + Report(ref context, DiagnosticRules.ArrayOutputParamMarkedRead, method.GetLocation(), method.Identifier, param.Identifier); found |= true; } // must have some indication of ReadOnly or WriteOnly else if (!hasWriteOnlyArray && !hasReadOnlyArray && !isOutputParam) - { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.ArrayParamNotMarked, method.GetLocation(), method.Identifier, param.Identifier - , hasWriteOnlyArray, hasReadOnlyArray, isOutputParam)); + { + Report(ref context, DiagnosticRules.ArrayParamNotMarked, method.GetLocation(), method.Identifier, param.Identifier, hasWriteOnlyArray, hasReadOnlyArray, isOutputParam); found |= true; } } // Non-array types shouldn't have attributes meant for arrays else if (hasWriteOnlyArray || hasReadOnlyArray) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.NonArrayMarked, method.GetLocation(), method.Identifier, param.Identifier)); + Report(ref context, DiagnosticRules.NonArrayMarked, method.GetLocation(), method.Identifier, param.Identifier); found |= true; } } @@ -443,49 +391,24 @@ private bool CheckParamsForArrayAttributes(MethodDeclarationSyntax method, ref G return found; } -#endregion - - #region CheckingMethods - - /// - /// Loops over each method declared in the given class and checks for various diagnostics - /// - /// - /// - /// True iff any of the diagnostics checked for are found. - public bool ClassHasInvalidMethods(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) + public bool HasInvalidMethods(ref GeneratorExecutionContext context, IEnumerable methodDeclarations, SyntaxToken typeId) + where T : TypeDeclarationSyntax { bool found = false; - IEnumerable methods = classDeclaration.ChildNodes().OfType(); - Dictionary methodsHasAttributeMap = new Dictionary(); - + /* we can't throw the diagnostic as soon as we see a second overload without an attribute, * as there could be a third overload with the default attribute - * we use this map to keep track of these cases, and after we have checked all methods, - * we check the elements of the map to raise diagnostics for those that didn't get attributed */ + * So store a diagnostic in case we see all methods and none of this overload have the attribute */ Dictionary overloadsWithoutAttributeMap = new Dictionary(); - foreach (MethodDeclarationSyntax method in methods.Where(IsPublic)) + // var methodDeclarations = interfaceDeclaration.DescendantNodes().OfType(); + foreach (MethodDeclarationSyntax method in methodDeclarations) { - found |= CheckParamsForArrayAttributes(method, ref context); - - /* Gather information on overloaded methods; make sure there is only one marked DefaultOverload */ - found |= CheckOverloadAttributes(method, ref methodsHasAttributeMap, ref overloadsWithoutAttributeMap, classDeclaration.Identifier, ref context); - - /* make sure no parameter has the name "__retval" */ + found |= CheckOverloadAttributes(ref context, method, ref methodsHasAttributeMap, ref overloadsWithoutAttributeMap, typeId); found |= HasConflictingParameterName(ref context, method); - - /* see if method signature contains the types System.Array or Array */ - var qualName = method.DescendantNodes().OfType(); - found |= SignatureContainsTypeName(ref context, qualName, "System.Array", classDeclaration.Identifier, method.GetLocation(), method.Identifier); - - var idName = method.DescendantNodes().OfType(); - found |= SignatureContainsTypeName(ref context, idName, "Array", classDeclaration.Identifier, method.GetLocation(), method.Identifier); - - found |= ArrayIsntOneDim(method.DescendantNodes().OfType(), ref context, classDeclaration.Identifier, method.Identifier, method.GetLocation()); + found |= CheckMethod(ref context, method, typeId); } - /* Finishes up the work started by `CheckOverloadAttributes` */ foreach (var thing in overloadsWithoutAttributeMap) { @@ -494,68 +417,26 @@ public bool ClassHasInvalidMethods(ref GeneratorExecutionContext context, ClassD } return found; } - - /// - /// Looks at all the methods declared on the given interface and checks them for improper array types (System.Array instances, multidimensional, jagged) - /// - /// - /// - /// True iff any of the invalid array types are used in any of the method signatures on the given interface - public bool InterfaceHasInvalidMethods(ref GeneratorExecutionContext context, InterfaceDeclarationSyntax interfaceDeclaration) + private bool CheckMethod(ref GeneratorExecutionContext context, MethodDeclarationSyntax method, SyntaxToken parentNodeId) { bool found = false; - var methodDeclarations = interfaceDeclaration.DescendantNodes().OfType(); - foreach (var method in methodDeclarations) - { - var loc = method.GetLocation(); - var methodId = method.Identifier; - var interfaceId = interfaceDeclaration.Identifier; - - var qualifiedNames = method.DescendantNodes().OfType(); - found |= SignatureContainsTypeName(ref context, qualifiedNames, "System.Array", interfaceId, loc, methodId); - - var identifiers = method.DescendantNodes().OfType(); - found |= SignatureContainsTypeName(ref context, identifiers, "Array", interfaceId, loc, methodId); - - found |= ArrayIsntOneDim(method.DescendantNodes().OfType(), ref context, interfaceId, methodId, loc); - - found |= CheckParamsForArrayAttributes(method, ref context); - } + Location loc = method.GetLocation(); + SyntaxToken methodId = method.Identifier; + IEnumerable qualifiedTypes = method.DescendantNodes().OfType(); + IEnumerable types = method.DescendantNodes().OfType(); + IEnumerable arrays = method.DescendantNodes().OfType(); + + var d = Diagnostic.Create(DiagnosticRules.ArraySignature_SystemArrayRule, loc, parentNodeId, methodId); + found |= SignatureContainsTypeName(ref context, qualifiedTypes, "System.Array", d); + found |= SignatureContainsTypeName(ref context, types, "Array", d); + found |= ArrayIsntOneDim(arrays, ref context, parentNodeId, methodId, loc); + found |= CheckParamsForArrayAttributes(method, ref context); return found; } - #endregion - - #region Structs - - /* SimplifySyntaxTypeString - * returns the more common term for the given kind of syntax; used when creating a diagnostic for an invalid field in a struct */ - private string SimplifySyntaxTypeString(string syntaxType) - { - switch (syntaxType) - { - case "EventFieldDeclarationSyntax": - return "event"; - case "ConstructorDeclarationSyntax": - return "constructor"; - case "DelegateDeclarationSyntax": - return "delegate"; - case "IndexerDeclarationSyntax": - return "indexer"; - case "MethodDeclarationSyntax": - return "method"; - case "OperatorDeclarationSyntax": - return "operator"; - case "PropertyDeclarationSyntax": - return "property"; - default: - return "unknown syntax type: " + syntaxType; - } - } /// /// returns true iff there is a field of the given type in the given struct - /// e.g., if T is PropertyDeclarationSyntax, then if the struct has a property, we report a diagnostic and return true */ - /// + /// e.g., if T is PropertyDeclarationSyntax, then if the struct has a property, we report a diagnostic and return true /// T can vary over MethodDeclartion, EventDeclaration, etc... /// /// @@ -564,10 +445,7 @@ public bool StructHasFieldOfType(ref GeneratorExecutionContext context, Struc { if (structDeclaration.DescendantNodes().OfType().Any()) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructHasInvalidFieldRule2, - structDeclaration.GetLocation(), - structDeclaration.Identifier, - SimplifySyntaxTypeString(typeof(T).Name))); + Report(ref context, DiagnosticRules.StructHasInvalidFieldRule2, structDeclaration.GetLocation(), structDeclaration.Identifier, SimplifySyntaxTypeString(typeof(T).Name)); return true; } return false; @@ -575,26 +453,27 @@ public bool StructHasFieldOfType(ref GeneratorExecutionContext context, Struc /// /// returns true if there is a field declared private, - /// or (inclusive) declared with a type that is a class or one of object, byte or dynamic - /// + /// or (inclusive) declared with a type that is a class or one of object, byte or dynamic + /// The field to inspectThe name of the struct the field belongs to + /// A list of qualified class and interface names, which are invalid types to use in a struct for WinRT Component /// True if the struct has a field of an type that is not supported in Windows Runtime - public bool StructHasFieldOfInvalidType(ref GeneratorExecutionContext context, + public bool CheckFieldValidity(ref GeneratorExecutionContext context, FieldDeclarationSyntax field, - StructDeclarationSyntax structDeclaration, - List classNames) + SyntaxToken structId, + HashSet typeNames) { bool found = false; /* No private fields allowed in Windows Runtime components */ if (!IsPublic(field)) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructHasPrivateFieldRule, field.GetLocation(), structDeclaration.Identifier)); + Report(ref context, DiagnosticRules.StructHasPrivateFieldRule, field.GetLocation(), structId); found |= true; } if (ModifiersContains(field.Modifiers, "const")) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructHasConstFieldRule, field.GetLocation(), structDeclaration.Identifier)); + Report(ref context, DiagnosticRules.StructHasConstFieldRule, field.GetLocation(), structId); found |= true; } @@ -602,22 +481,14 @@ public bool StructHasFieldOfInvalidType(ref GeneratorExecutionContext context, { var typeStr = variable.Type.ToString(); - List invalidTypes = new List { "object", "dynamic" }; - invalidTypes.AddRange(classNames); - - if (invalidTypes.Contains(typeStr)) + HashSet invalidTypes = new HashSet { "object", "dynamic" }; + if (SymbolSetHasString(typeNames, typeStr) || invalidTypes.Contains(typeStr)) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructHasInvalidFieldRule, - variable.GetLocation(), - structDeclaration.Identifier, - field.ToString(), - typeStr)); + Report(ref context, DiagnosticRules.StructHasInvalidFieldRule, variable.GetLocation(), structId, field.ToString(), typeStr); found |= true; } } return found; } - - #endregion } } diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index 8746e0508..cfa02ec55 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -11,6 +11,7 @@ using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; using System.Text; +using WinRT.SourceGenerator; namespace Generator { @@ -110,7 +111,6 @@ private void GenerateSources(GeneratorExecutionContext context) Logger.Log("Adding " + file); context.AddSource(Path.GetFileNameWithoutExtension(file), SourceText.From(File.ReadAllText(file), Encoding.UTF8)); } - Directory.Delete(outputDir, true); } @@ -119,7 +119,7 @@ private string GetWinmdOutputFile(GeneratorExecutionContext context) return Path.Combine(GetGeneratedFilesDir(context), GetAssemblyName(context) + ".winmd"); } - private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) + private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) { Logger.Log("Writing " + outputFile); var managedPeBuilder = new ManagedPEBuilder( @@ -137,11 +137,34 @@ private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) peBlob.WriteContentTo(fs); } + private HashSet CollectDefinedTypes(GeneratorExecutionContext context) + { + WinRTRules winrtRules = new WinRTRules(); + HashSet userCreatedTypes = new HashSet(); + foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) + { + var model = context.Compilation.GetSemanticModel(tree); + var classes = tree.GetRoot().DescendantNodes().OfType().Where(winrtRules.IsPublic); + var interfaces = tree.GetRoot().DescendantNodes().OfType().Where(winrtRules.IsPublic); + foreach (var @class in classes) + { + userCreatedTypes.Add(model.GetDeclaredSymbol(@class)); + } + foreach (var @interface in interfaces) + { + userCreatedTypes.Add(model.GetDeclaredSymbol(@interface)); + } + } + return userCreatedTypes; + } private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) { bool found = false; WinRTRules winrtRules = new WinRTRules(); + + HashSet userCreatedTypes = CollectDefinedTypes(context); + foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { var model = context.Compilation.GetSemanticModel(tree); @@ -150,35 +173,29 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) var classes = nodes.OfType().Where(winrtRules.IsPublic); var interfaces = nodes.OfType().Where(winrtRules.IsPublic); var structs = nodes.OfType(); - - // Used in the checking of structure fields - List classNames = new List(); - - /* Check all classes */ + foreach (ClassDeclarationSyntax classDeclaration in classes) { - classNames.Add(classDeclaration.Identifier.ToString()); - - /* exports multidimensional array */ - found |= winrtRules.CheckPropertiesForArrayTypes(ref context, classDeclaration); - - /* exposes an operator overload */ found |= winrtRules.OverloadsOperator(ref context, classDeclaration); - - /* parameters named __retval*/ - found |= winrtRules.ClassHasInvalidMethods(ref context, classDeclaration); - - /* multiple constructors of the same arity */ found |= winrtRules.HasMultipleConstructorsOfSameArity(ref context, classDeclaration); - - /* implementing async interfaces */ - var classSymbol = model.GetDeclaredSymbol(classDeclaration); - found |= winrtRules.ImplementsAsyncInterface(ref context, classSymbol, classDeclaration); + found |= winrtRules.ImplementsAsyncInterface(ref context, model.GetDeclaredSymbol(classDeclaration), classDeclaration); + + var props = classDeclaration.DescendantNodes().OfType().Where(winrtRules.IsPublic); + found |= winrtRules.CheckPropertySignature(ref context, props, classDeclaration.Identifier); + + var publicMethods = classDeclaration.ChildNodes().OfType().Where(winrtRules.IsPublic); + found |= winrtRules.HasInvalidMethods(ref context, publicMethods,classDeclaration.Identifier); } foreach (InterfaceDeclarationSyntax interfaceDeclaration in interfaces) { - found |= winrtRules.InterfaceHasInvalidMethods(ref context, interfaceDeclaration); + found |= winrtRules.ImplementsAsyncInterface(ref context, model.GetDeclaredSymbol(interfaceDeclaration), interfaceDeclaration); + + var props = interfaceDeclaration.DescendantNodes().OfType(); + found |= winrtRules.CheckPropertySignature(ref context, props, interfaceDeclaration.Identifier); + + var methods = interfaceDeclaration.DescendantNodes().OfType(); + found |= winrtRules.HasInvalidMethods(ref context, methods, interfaceDeclaration.Identifier); } /* Check all structs */ @@ -193,9 +210,14 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); var fields = structDeclaration.DescendantNodes().OfType(); - foreach (var field in fields) + foreach (var field in fields) + { + found |= winrtRules.CheckFieldValidity(ref context, field, structDeclaration.Identifier, userCreatedTypes); + } + if (!fields.Any()) { - found |= winrtRules.StructHasFieldOfInvalidType(ref context, field, structDeclaration, classNames); + context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructWithNoFieldsRule, structDeclaration.GetLocation(), model.GetDeclaredSymbol(structDeclaration))); + found |= true; } } } @@ -216,8 +238,6 @@ internal sealed class WriteOnlyArrayAttribute : global::System.Attribute { } }", Encoding.UTF8)); - - } public void Execute(GeneratorExecutionContext context) From 564bbbf348569cd94021c62c38c6d6b18549eaf9 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Thu, 17 Dec 2020 12:49:32 -0800 Subject: [PATCH 36/41] cleanup data --- src/Authoring/DiagnosticTests/NegativeData.cs | 4160 +++++++++-------- src/Authoring/DiagnosticTests/PositiveData.cs | 191 +- 2 files changed, 2235 insertions(+), 2116 deletions(-) diff --git a/src/Authoring/DiagnosticTests/NegativeData.cs b/src/Authoring/DiagnosticTests/NegativeData.cs index f6778afe6..93b5140fd 100644 --- a/src/Authoring/DiagnosticTests/NegativeData.cs +++ b/src/Authoring/DiagnosticTests/NegativeData.cs @@ -1,2018 +1,2142 @@ -namespace DiagnosticTests -{ - public partial class TestDiagnostics - { - - // Cases to add -- WIP - private const string StructWithInterfaceField = @" -namespace Test -{ - public interface Foo - { - int Id(int i); - } - - public struct StructWithIface_Invalid - { - public Foo ifaceField; - } -}"; - - private const string UnsealedClass = @" -namespace Test -{ - public class UnsealedClass - { - public UnsealedClass() {} - } -}"; - private const string UnsealedClass2 = @" -namespace Test -{ - public class UnsealedClass - { - private UnsealedClass() {} - } -}"; - - private const string GenericClass = @" -namespace Test -{ - public sealed class GenericClass - { - public UnsealedClass() {} - } -}"; - private const string GenericInterface = @" -namespace Test -{ - public interface GenIface - { - int Foo(T input); - } -}"; - - private const string InterfaceInheritsException = @" -namespace Test -{ - public interface IfaceWithExceptions : System.Exception - { - int Foo(T input); - } -}"; - private const string ClassInheritsException = @" -namespace Test -{ - public sealed class ClassWithExceptions : System.Exception - { - public ClassWithExceptions() {} - } -}"; - - // namespace tests -- WIP - private const string _NamespaceTest1 = @" -namespace Test -{ - namespace OtherNamespace_Valid - { - public sealed class Class1 - { - int x; - public Class1(int a) { x = a; } - } - } - - // WME1068 - public sealed class TestDiagnostics - { - bool b; - public TestDiagnostics(bool x) { b = x; } - } -} -}"; - private const string _NamespaceTest2 = @" -namespace OtherNamespace -{ - -// WME1044 ? - public sealed class Class1 - { - int x; - - public Class1(int a) - { - x = a; - } - } -}"; - private const string _NamespaceTest3 = @" -namespace Test -{ -// WME1067 ?? - namespace InnerNamespace - { - public sealed class Class1 - { - int x; - public Class1(int a) { x = a; } - } - } -}"; - // multidim array - private const string MultiDim_2DProp = @" -namespace Test -{ - public sealed class MultiDim_2DProp - { - public int[,] Arr_2d { get; set; } - private int[,] PrivArr_2d { get; set; } - } -}"; - private const string MultiDim_3DProp = @" -namespace Test -{ - public sealed class MultiDim_3DProp - { - public int[,,] Arr_3d { get; set; } - private int[,] PrivArr_2d { get; set; } - } -}"; - private const string MultiDim_3DProp_Whitespace = @" -namespace Test -{ - public sealed class MultiDim_3DProp - { - public int[ , , ] Arr_3d { get; set; } - private int[,] PrivArr_2d { get; set; } - } -}"; - // 2d class - private const string MultiDim_2D_PublicClassPublicMethod1 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod1 - { - public int[,] D2_ReturnOnly() { return new int[4, 2]; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod2 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod2 - { - public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod3 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod3 - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod4 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod4 - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod5 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod5 - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod6 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod6 - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - } -}"; - // 3d class - private const string MultiDim_3D_PublicClassPublicMethod1 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod1 - { - public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod2 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod3 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod4 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod5 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod6 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } -}"; - // 2d iface - private const string MultiDim_2D_Interface1 = @" -namespace Test -{ - public interface MultiDim_2D_Interface1 - { - public int[,] D2_ReturnOnly(); - } -}"; - private const string MultiDim_2D_Interface2 = @" -namespace Test -{ - public interface MultiDim_2D_Interface2 - { - public int[,] D2_ReturnAndInput1(int[,] arr); - } -}"; - private const string MultiDim_2D_Interface3 = @" -namespace Test -{ - public interface MultiDim_2D_Interface3 - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); - } -}"; - private const string MultiDim_2D_Interface4 = @" -namespace Test -{ - public interface MultiDim_2D_Interface4 - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); - } -}"; - private const string MultiDim_2D_Interface5 = @" -namespace Test -{ - public interface MultiDim_2D_Interface5 - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); - } -}"; - private const string MultiDim_2D_Interface6 = @" -namespace Test -{ - public interface MultiDim_2D_Interface6 - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); - } -}"; - // 3d iface - private const string MultiDim_3D_Interface1 = @" -namespace Test -{ - public interface MultiDim_3D_Interface1 - { - public int[,,] D3_ReturnOnly(); - } -}"; - private const string MultiDim_3D_Interface2 = @" -namespace Test -{ - public interface MultiDim_3D_Interface2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr); - } -}"; - private const string MultiDim_3D_Interface3 = @" -namespace Test -{ - public interface MultiDim_3D_Interface3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); - } -}"; - private const string MultiDim_3D_Interface4 = @" -namespace Test -{ - public interface MultiDim_3D_Interface4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); - } -}"; - private const string MultiDim_3D_Interface5 = @" -namespace Test -{ - public interface MultiDim_3D_Interface5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); - } -}"; - private const string MultiDim_3D_Interface6 = @" -namespace Test -{ -public interface MultiDim_3D_Interface6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - -}"; - // subnamespace 2d iface - private const string SubNamespaceInterface_D2Method1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnOnly(); - } - } -}"; - private const string SubNamespaceInterface_D2Method2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnAndInput1(int[,] arr); - } - } -}"; - private const string SubNamespaceInterface_D2Method3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); - } - } -}"; - private const string SubNamespaceInterface_D2Method4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); - } - } -}"; - private const string SubNamespaceInterface_D2Method5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); - } - } -}"; - private const string SubNamespaceInterface_D2Method6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); - } - } -}"; - // subnamespace 3d iface - private const string SubNamespaceInterface_D3Method1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method1 - { - public int[,,] D3_ReturnOnly(); - } - } -}"; - private const string SubNamespaceInterface_D3Method2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr); - } - } -}"; - private const string SubNamespaceInterface_D3Method3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); - } - } -}"; - private const string SubNamespaceInterface_D3Method4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - } -}"; - private const string SubNamespaceInterface_D3Method5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); - } - } -}"; - private const string SubNamespaceInterface_D3Method6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - } -}"; - // system array - private const string ArrayInstanceProperty1 = @" -namespace Test -{ - // this might be valid... - public sealed class ArrayInstanceProperty1 - { - public int[] Arr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - } -}"; - private const string ArrayInstanceProperty2 = @" -namespace Test -{ -public sealed class ArrayInstanceProperty2 - { - public System.Array Arr - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - } -}"; - private const string ArrayInstanceProperty3 = @" -namespace Test -{ - // this might be valid... - public sealed class ArrayInstanceProperty3 - { - public int[] Arr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } - -}"; - private const string ArrayInstanceProperty4 = @" -namespace Test -{ -public sealed class ArrayInstanceProperty4 - { - public System.Array Arr - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } -}"; - private const string ArrayInstanceInterface1 = @" -namespace Test -{ - public interface ArrayInstanceInterface1 - { - System.Array Id(System.Array arr); - } -}"; - private const string ArrayInstanceInterface2 = @" -namespace Test -{ - public interface ArrayInstanceInterface2 - { - void Method2(System.Array arr); - } -}"; - private const string ArrayInstanceInterface3 = @" -namespace Test -{ - public interface ArrayInstanceInterface3 - { - System.Array Method3(); - } -}"; - private const string SystemArrayProperty5 = @" -namespace Test -{ - public sealed class SystemArrayProperty - { - public System.Array Arr { get; set; } - } -}"; - private const string SystemArrayJustReturn = @" -namespace Test -{ - public sealed class JustReturn - { - public System.Array SystemArrayMethod() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } -}"; - private const string SystemArrayUnaryAndReturn = @" -namespace Test -{ - public sealed class UnaryAndReturn - { - public System.Array SystemArrayMethod(System.Array arr) { return arr; } - } -}"; - private const string SystemArraySecondArgClass = @" -namespace Test -{ - public sealed class SecondArgClass - { - public bool SystemArrayMethod(bool a, System.Array arr) { return a; } - } -}"; - private const string SystemArraySecondArg2Class = @" -namespace Test -{ -public sealed class SecondArg2Class - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b) { return a; } - } -}"; - private const string SystemArraySecondArgAndReturnTypeClass = @" -namespace Test -{ - public sealed class SecondArgAndReturnType - { - public System.Array SystemArrayMethod(bool a, System.Array arr) { return arr; } - } -}"; - private const string SystemArraySecondArgAndReturnTypeClass2 = @" -namespace Test -{ - public sealed class SecondArgAndReturnTypeClass2 - { - public System.Array SystemArrayMethod(bool a, System.Array arr, bool b) { return arr; } - } -}"; - private const string SystemArrayNilArgsButReturnTypeInterface = @" -namespace Test -{ -public interface NilArgsButReturnTypeInterface - { - public System.Array SystemArrayMethod(); - } -}"; - private const string SystemArrayUnaryAndReturnTypeInterface = @" -namespace Test -{ -public interface UnaryAndReturnTypeInterface - { - public System.Array SystemArrayMethod(System.Array arr); - } -}"; - private const string SystemArraySecondArgAndReturnTypeInterface = @" -namespace Test -{ -public interface SecondArgAndReturnTypeInterface - { - public System.Array SystemArrayMethod(bool a, System.Array arr); - } -}"; - private const string SystemArraySecondArgAndReturnTypeInterface2 = @" -namespace Test -{ - public interface SecondArgAndReturnTypeInterface2 - { - public System.Array SystemArrayMetho(bool a, System.Array arr, bool b); - } -}"; - private const string SystemArraySecondArgInterface = @" -namespace Test -{ - public interface SecondArgInterface - { - public bool SystemArrayMethod(bool a, System.Array arr); - } -}"; - private const string SystemArraySecondArgInterface2 = @" -namespace Test -{ -public interface SecondArgInterface2 - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b); - } -}"; - private const string SystemArraySubNamespace_ReturnOnly = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_ReturnOnly - { - public System.Array SystemArrayMethod(); - } -} -}"; - private const string SystemArraySubNamespace_ReturnAndInput1 = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_ReturnAndInput1 - { - public System.Array SystemArrayMethod(System.Array arr); - } -} -}"; - private const string SystemArraySubNamespace_ReturnAndInput2of2 = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_ReturnAndInput2of2 - { - public System.Array SystemArrayMethod(bool a, System.Array arr); - } -} -}"; - private const string SystemArraySubNamespace_ReturnAndInput2of3 = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_ReturnAndInput2of3 - { - public System.Array SystemArrayMethod(bool a, System.Array arr, bool b); - } -} -}"; - private const string SystemArraySubNamespace_NotReturnAndInput2of2 = @" -namespace Test -{ - namespace SubNamespace -{ - public interface SubNamespace_NotReturnAndInput2of2 - { - public bool SystemArrayMethod(bool a, System.Array arr); - } -} -}"; - private const string SystemArraySubNamespace_NotReturnAndInput2of3 = @" -namespace Test -{ - namespace SubNamespace -{ -public interface SubNamespace_NotReturnAndInput2of3 - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b); - } -} -}"; - // constructor of same arity - private const string ConstructorsOfSameArity = @" -namespace TestNamespace -{ - public sealed class SameArityConstructors - { - private int num; - private string word; - - public SameArityConstructors(int i) - { - num = i; - word = ""dog""; - } - - public SameArityConstructors(string s) - { - num = 38; - word = s; - } - } -}"; - // async interfaces - private const string ClassImplementsIAsyncOperationWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class OpWithProgress : IAsyncOperationWithProgress - { - AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperationWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ClassImplementsIAsyncActionWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public class ActionWithProgress : IAsyncActionWithProgress - { - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ClassImplementsIAsyncOperation = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class Op : IAsyncOperation - { - AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperation.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ClassImplementsIAsyncAction = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class AsyAction : IAsyncAction - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string InterfaceImplementsIAsyncOperationWithProgress = @" -using Windows.Foundation; using System; -namespace TestNamespace -{ - public interface OpWithProgress : IAsyncOperationWithProgress {} -}"; - private const string InterfaceImplementsIAsyncActionWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public class ActionWithProgress : IAsyncActionWithProgress {} -}"; - private const string InterfaceImplementsIAsyncOperation = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public interface IAsyncOperation : IAsyncOperation {} -}"; - private const string InterfaceImplementsIAsyncAction = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public interface AsyAction : IAsyncAction {} -}"; - private const string InterfaceImplementsIAsyncOperationWithProgress2 = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public interface OpWithProgress : IAsyncOperationWithProgress - { - AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - void IAsyncInfo.Close(); - int IAsyncOperationWithProgress.GetResults(); - } -}"; - private const string InterfaceImplementsIAsyncActionWithProgress2 = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public class ActionWithProgress : IAsyncActionWithProgress - { - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string InterfaceImplementsIAsyncOperation2 = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class Op : IAsyncOperation - { - AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperation.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string InterfaceImplementsIAsyncAction2 = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class AsyAction : IAsyncAction - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - } -}"; - - // readonlyarray / writeonlyarray attribute - private const string TestArrayParamAttrUnary_1 = @" -public sealed class OnlyParam -{ - public void BothAttributes_Separate([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_2 = @" -public sealed class OnlyParam -{ - public void BothAttributes_Together([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_3 = @" -public sealed class OnlyParam -{ - public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } -}"; - private const string TestArrayParamAttrUnary_4 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedIn([In] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_5 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedOut([Out] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_6 = @" -public sealed class OnlyParam -{ - public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrUnary_7 = @" -public sealed class OnlyParam -{ - public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrUnary_8 = @" -public sealed class OnlyParam -{ - public void ParamMarkedIn([In] int arr) { } -}"; - private const string TestArrayParamAttrUnary_9 = @" -public sealed class OnlyParam -{ - public void ParamMarkedOut([Out] int arr) { } -}"; - private const string TestArrayParamAttrUnary_10 = @" -public sealed class OnlyParam -{ - public void ArrayNotMarked(int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_11 = @" -public sealed class OnlyParam -{ - public void ParamMarkedIn([System.Runtime.InteropServices.In] int arr) { } -}"; - private const string TestArrayParamAttrUnary_12 = @" -public sealed class OnlyParam -{ - public void ParamMarkedOut([System.Runtime.InteropServices.Out] int arr) { } -}"; - private const string TestArrayParamAttrUnary_13 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedIn([System.Runtime.InteropServices.In] int[] arr) { } -}"; - private const string TestArrayParamAttrUnary_14 = @" -public sealed class OnlyParam -{ - public void ArrayMarkedOut([System.Runtime.InteropServices.Out] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_1 = @" -public sealed class TwoParam -{ - public void BothAttributes_Separate(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_2 = @" -public sealed class TwoParam -{ - public void BothAttributes_Together(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_3 = @" -public sealed class TwoParam -{ - public void MarkedOutAndReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } -}"; - private const string TestArrayParamAttrBinary_4 = @" -public sealed class TwoParam -{ - public void ArrayMarkedIn(int i, [In] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_5 = @" -public sealed class TwoParam -{ - public void ArrayMarkedOut(int i, [Out] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_6 = @" -public sealed class TwoParam -{ - public void NonArrayMarkedReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrBinary_7 = @" -public sealed class TwoParam -{ - public void NonArrayMarkedWriteOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } -}"; - private const string TestArrayParamAttrBinary_8 = @" -public sealed class TwoParam -{ - public void ParamMarkedIn(int i, [In] int arr) { } -}"; - private const string TestArrayParamAttrBinary_9 = @" -public sealed class TwoParam -{ - public void ParamMarkedOut(int i, [Out] int arr) { } -}"; - private const string TestArrayParamAttrBinary_10 = @" -public sealed class TwoParam -{ - public void ArrayNotMarked(int i, int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_11 = @" -public sealed class TwoArray -{ - public void OneValidOneInvalid_1( -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] -[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] ys) { } -}"; - private const string TestArrayParamAttrBinary_12 = @" -public sealed class TwoArray -{ - public void OneValidOneInvalid_2( -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] -[System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, -[System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] ys) { } -}"; - private const string TestArrayParamAttrBinary_13 = @" -public sealed class TwoArray -{ - public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } -}"; - private const string TestArrayParamAttrBinary_14 = @" -public sealed class TwoParam -{ - public void ArrayMarkedIn(int i, [In] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_15 = @" -public sealed class TwoArray -{ - public void ArrayMarkedIn2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_16 = @" -public sealed class TwoArray -{ - public void ArrayMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_17 = @" -public sealed class TwoArray -{ - public void ArrayNotMarked(int i, int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_18 = @" -public sealed class TwoArray -{ - public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i) { } -}"; - private const string TestArrayParamAttrBinary_19 = @" -public sealed class TwoArray -{ - public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int i) { } -}"; - private const string TestArrayParamAttrBinary_20 = @" -public sealed class TwoArray -{ - public void NonArrayMarkedWriteOnly2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } -}"; - private const string TestArrayParamAttrBinary_21 = @" -public sealed class TwoArray -{ - public void ParamMarkedIn([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int arr) { } -}"; - private const string TestArrayParamAttrBinary_22 = @" -public sealed class TwoArray -{ - public void ParamMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int arr) { } -}"; - private const string TestArrayParamAttrBinary_23 = @" -public sealed class TwoArray -{ - public void ParamMarkedOut2([Out] int arr, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs) { } -}"; - private const string TestArrayParamAttrBinary_24 = @" -public sealed class TwoArray -{ - public void ArrayNotMarked([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, int[] arr) { } -}"; - // ref param - private const string RefParam_InterfaceMethod = @" -public interface IHaveAMethodWithRefParam - { - void foo(ref int i); - } -"; - private const string RefParam_ClassMethod = @" -public sealed class ClassWithMethodUsingRefParam - { - public void MethodWithRefParam(ref int i) { i++; } - } -"; - // operator overload - private const string OperatorOverload_Class = @" - public sealed class ClassThatOverloadsOperator - { - public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) - { - return thing; - } - }"; - // param name conflict - private const string DunderRetValParam = @" -public sealed class ParameterNamedDunderRetVal - { - public int Identity(int __retval) - { - return __retval; - } - } -"; - // struct fields - private const string StructWithConstructor = @" - namespace Test -{ - public struct StructWithConstructor_Invalid - { - int X; - StructWithConstructor_Invalid(int x) - { - X = x; - } - } -} "; - private const string StructWithClassField = @" -namespace Test -{ - public sealed class SillyClass - { - public double Identity(double d) - { - return d; - } - - public SillyClass() { } - } - - public struct StructWithClass_Invalid - { - public SillyClass classField; - } -}"; - private const string StructWithClassField2 = @" -namespace Test -{ - public sealed class SillyClass - { - public double Identity(double d) - { - return d; - } - - public SillyClass() { } - } -} - -namespace Prod -{ - public struct StructWithClass_Invalid - { - public Test.SillyClass classField; - } -}"; - private const string StructWithDelegateField = @" -namespace Test { -public struct StructWithDelegate_Invalid - { - public delegate int ADelegate(int x); - } -}"; - private const string StructWithPrimitiveTypesMissingPublicKeyword = @" -namespace Test -{ - public struct StructWithAllValidFields - { - bool boolean; - char character; - decimal dec; - double dbl; - float flt; - int i; - uint nat; - long lng; - ulong ulng; - short sh; - ushort us; - string str; - } -}"; - private const string EmptyStruct = @" -namespace Test -{ - public struct Mt {} -}"; - private const string StructWithIndexer = @" -namespace Test -{ -public struct StructWithIndexer_Invalid - { - int[] arr; - int this[int i] => arr[i]; - } -}"; - private const string StructWithMethods = @" -namespace Test -{ -public struct StructWithMethods_Invalid - { - int foo(int x) - { - return x; - } - } -}"; - private const string StructWithConst = @" -namespace Test -{ - public struct StructWithConst_Invalid - { - const int five = 5; - } -}"; - private const string StructWithProperty = @" -namespace Test -{ - public enum BasicEnum - { - First = 0, - Second = 1 - } - - public struct Posn_Invalid - { - BasicEnum enumField; - - public int x { get; } - public int y { get; } - } -}"; - private const string StructWithPrivateField = @" -namespace Test -{ -public struct StructWithPrivateField_Invalid - { - private int x; - } -}"; - private const string StructWithObjectField = @" -namespace Test -{ -public struct StructWithObjectField_Invalid - { - public object obj; - } -}"; - private const string StructWithDynamicField = @" -namespace Test -{ -public struct StructWithDynamicField_Invalid - { - public dynamic dyn; - } -}"; - private const string TwoOverloads_NoAttribute_NamesHaveNumber = @" -namespace Test -{ - public sealed class TwoOverloads_NoAttribute_WithNum - { - public string OverloadExample1(string s) { return s; } - - public int OverloadExample1(int n) { return n; } - } -}"; - // DefaultOverload attribute tests - private const string TwoOverloads_TwoAttribute_OneInList_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInList - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - DefaultOverload] - public string OverloadExample(string s) { return s; } - - [DefaultOverload] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInList_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInList - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_TwoLists_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_TwoLists - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [DefaultOverload] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - DefaultOverload] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInSeparateList_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInSeparateList - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [DefaultOverload] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute - { - - [DefaultOverload] - public string OverloadExample(string s) { return s; } - - [DefaultOverload] - public int OverloadExample(int n) { return n; } - } -}"; - private const string ThreeOverloads_TwoAttributes_Unqualified= @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class ThreeOverloads_TwoAttributes - { - public string OverloadExample(string s) { return s; } - - [DefaultOverload] - public int OverloadExample(int n) { return n; } - - [DefaultOverload] - public bool OverloadExample(bool b) { return b; } - } -}"; - private const string TwoOverloads_NoAttribute = @" -namespace Test -{ - public sealed class TwoOverloads_NoAttribute - { - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_OneInList = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInList - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_NoAttribute_OneIrrevAttr = @" -namespace Test -{ - public sealed class TwoOverloads_NoAttribute_OneIrrevAttr - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInList = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInList - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_TwoLists = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_TwoLists - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInSeparateList = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInSeparateList - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute - { - - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string ThreeOverloads_TwoAttributes = @" -namespace Test -{ - public sealed class ThreeOverloads_TwoAttributes - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public bool OverloadExample(bool b) { return b; } - } -}"; - // jagged 2d/3d prop - private const string Jagged2D_Property2 = @" -namespace Test -{ - public sealed class Jagged2D_Property2 - { - public int[][] Arr { get; set; } - } -}"; - private const string Jagged3D_Property1 = @" -namespace Test -{ - public sealed class Jagged3D_Property1 - { - public int[][][] Arr3 { get; set; } - } -}"; - // jagged 2d class method - private const string Jagged2D_ClassMethod1 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod1 - { - public int[][] J2_ReturnOnly() - { - int[][] arr = new int[2][]; - arr[0] = new int[1] { 1 }; - arr[1] = new int[1] { 2 }; - return arr; - } - - } -}"; - private const string Jagged2D_ClassMethod2 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod2 - { - public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } - } -}"; - private const string Jagged2D_ClassMethod3 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod3 - { - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } - } -}"; - private const string Jagged2D_ClassMethod4 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod4 - { - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } - } -}"; - private const string Jagged2D_ClassMethod5 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod5 - { - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } - } -}"; - private const string Jagged2D_ClassMethod6 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod6 - { - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - } -}"; - // jagged 3d class method - private const string Jagged3D_ClassMethod1 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod1 - { - public int[][][] J3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - - } -}"; - private const string Jagged3D_ClassMethod2 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod1 - { - public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } - } -}"; - private const string Jagged3D_ClassMethod3 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod3 - { - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - } -}"; - private const string Jagged3D_ClassMethod4 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod4 - { - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - } -}"; - private const string Jagged3D_ClassMethod5 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod5 - { - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - } -}"; - private const string Jagged3D_ClassMethod6 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod6 - { - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } -}"; - // jagged 2d interface method - private const string Jagged2D_InterfaceMethod1 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod1 - { - public int[][] J2_ReturnOnly(); - } -}"; - private const string Jagged2D_InterfaceMethod2 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod2 - { - public int[][] J2_ReturnAndInput1(int[,] arr); - } -}"; - private const string Jagged2D_InterfaceMethod3 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod3 - { - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); - } -}"; - private const string Jagged2D_InterfaceMethod4 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod4 - { - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); - } -}"; - private const string Jagged2D_InterfaceMethod5 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod5 - { - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); - } -}"; - private const string Jagged2D_InterfaceMethod6 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod6 - { - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); - } -}"; - // jagged 2d interface method - private const string Jagged3D_InterfaceMethod1 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod1 - { - public int[][][] J3_ReturnOnly(); - } -}"; - private const string Jagged3D_InterfaceMethod2 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod2 - { - public int[][][] J3_ReturnAndInput1(int[][][] arr); - } -}"; - private const string Jagged3D_InterfaceMethod3 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod3 - { - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); - } -}"; - private const string Jagged3D_InterfaceMethod4 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod4 - { - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); - } -}"; - private const string Jagged3D_InterfaceMethod5 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod5 - { - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); - } -}"; - private const string Jagged3D_InterfaceMethod6 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod6 - { - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); - } -}"; - // subnamespace jagged 2d iface - private const string SubNamespace_Jagged2DInterface1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface1 - { - public int[][] J2_ReturnOnly(); - } - } -}"; - private const string SubNamespace_Jagged2DInterface2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface2 - { - public int[][] J2_ReturnAndInput1(int[,] arr); - } - } -}"; - private const string SubNamespace_Jagged2DInterface3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface3 - { - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); - } - } -}"; - private const string SubNamespace_Jagged2DInterface4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface4 - { - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); - } - } -}"; - private const string SubNamespace_Jagged2DInterface5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface5 - { - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); - } - } -}"; - private const string SubNamespace_Jagged2DInterface6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface6 - { - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); - } - } -}"; - // subnamespace jagged 3d iface - private const string SubNamespace_Jagged3DInterface1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface1 - { - public int[][][] J3_ReturnOnly(); - } - } -}"; - private const string SubNamespace_Jagged3DInterface2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface2 - { - public int[][][] J3_ReturnAndInput1(int[][][] arr); - } - } -}"; - private const string SubNamespace_Jagged3DInterface3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface3 - { - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); - } - } -}"; - private const string SubNamespace_Jagged3DInterface4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface4 - { - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); - } - } -}"; - private const string SubNamespace_Jagged3DInterface5 = @" -namespace Test -{ - namespace SubNamespace - - { - public interface SubNamespace_Jagged3DInterface5 - { - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); - } - } -}"; - private const string SubNamespace_Jagged3DInterface6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface6 - { - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); - } - } -}"; - } -} +namespace DiagnosticTests +{ + public partial class TestDiagnostics + { + + // Cases to add -- WIP + private const string StructWithInterfaceField = @" +namespace Test +{ + public interface Foo + { + int Id(int i); + } + + public struct StructWithIface_Invalid + { + public Foo ifaceField; + } +}"; + + private const string UnsealedClass = @" +namespace Test +{ + public class UnsealedClass + { + public UnsealedClass() {} + } +}"; + private const string UnsealedClass2 = @" +namespace Test +{ + public class UnsealedClass + { + private UnsealedClass() {} + } +}"; + + private const string GenericClass = @" +namespace Test +{ + public sealed class GenericClass + { + public UnsealedClass() {} + } +}"; + private const string GenericInterface = @" +namespace Test +{ + public interface GenIface + { + int Foo(T input); + } +}"; + + private const string InterfaceInheritsException = @" +namespace Test +{ + public interface IfaceWithExceptions : System.Exception + { + int Foo(T input); + } +}"; + private const string ClassInheritsException = @" +namespace Test +{ + public sealed class ClassWithExceptions : System.Exception + { + public ClassWithExceptions() {} + } +}"; + + // namespace tests -- WIP + private const string _NamespaceTest1 = @" +namespace Test +{ + namespace OtherNamespace_Valid + { + public sealed class Class1 + { + int x; + public Class1(int a) { x = a; } + } + } + + // WME1068 + public sealed class TestDiagnostics + { + bool b; + public TestDiagnostics(bool x) { b = x; } + } +} +}"; + private const string _NamespaceTest2 = @" +namespace OtherNamespace +{ + + // WME1044 ? + public sealed class Class1 + { + int x; + + public Class1(int a) + { + x = a; + } + } +}"; + private const string _NamespaceTest3 = @" +namespace Test +{ + // WME1067 ?? + namespace InnerNamespace + { + public sealed class Class1 + { + int x; + public Class1(int a) { x = a; } + } + } +}"; + // multidim array + private const string MultiDim_2DProp = @" +namespace Test +{ + public sealed class MultiDim_2DProp + { + public int[,] Arr_2d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string MultiDim_3DProp = @" +namespace Test +{ + public sealed class MultiDim_3DProp + { + public int[,,] Arr_3d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string MultiDim_3DProp_Whitespace = @" +namespace Test +{ + public sealed class MultiDim_3DProp + { + public int[ , , ] Arr_3d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + // 2d class + private const string MultiDim_2D_PublicClassPublicMethod1 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod1 + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod2 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod2 + { + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod3 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod4 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod5 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod6 = @" +namespace Test +{ + public sealed class MultiDim_2D_PublicClassPublicMethod6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + } +}"; + // 3d class + private const string MultiDim_3D_PublicClassPublicMethod1 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod1 + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod2 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod3 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod4 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod5 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod6 = @" +namespace Test +{ + public sealed class MultiDim_3D_PublicClassPublicMethod6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + // 2d iface + private const string MultiDim_2D_Interface1 = @" +namespace Test +{ + public interface MultiDim_2D_Interface1 + { + public int[,] D2_ReturnOnly(); + } +}"; + private const string MultiDim_2D_Interface2 = @" +namespace Test +{ + public interface MultiDim_2D_Interface2 + { + public int[,] D2_ReturnAndInput1(int[,] arr); + } +}"; + private const string MultiDim_2D_Interface3 = @" +namespace Test +{ + public interface MultiDim_2D_Interface3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + } +}"; + private const string MultiDim_2D_Interface4 = @" +namespace Test +{ + public interface MultiDim_2D_Interface4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + } +}"; + private const string MultiDim_2D_Interface5 = @" +namespace Test +{ + public interface MultiDim_2D_Interface5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + } +}"; + private const string MultiDim_2D_Interface6 = @" +namespace Test +{ + public interface MultiDim_2D_Interface6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + } +}"; + // 3d iface + private const string MultiDim_3D_Interface1 = @" +namespace Test +{ + public interface MultiDim_3D_Interface1 + { + public int[,,] D3_ReturnOnly(); + } +}"; + private const string MultiDim_3D_Interface2 = @" +namespace Test +{ + public interface MultiDim_3D_Interface2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface3 = @" +namespace Test +{ + public interface MultiDim_3D_Interface3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface4 = @" +namespace Test +{ + public interface MultiDim_3D_Interface4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + } +}"; + private const string MultiDim_3D_Interface5 = @" +namespace Test +{ + public interface MultiDim_3D_Interface5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface6 = @" +namespace Test +{ +public interface MultiDim_3D_Interface6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + +}"; + // subnamespace 2d iface + private const string SubNamespaceInterface_D2Method1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnOnly(); + } + } +}"; + private const string SubNamespaceInterface_D2Method2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput1(int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + } + } +}"; + private const string SubNamespaceInterface_D2Method5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + } + } +}"; + // subnamespace 3d iface + private const string SubNamespaceInterface_D3Method1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method1 + { + public int[,,] D3_ReturnOnly(); + } + } +}"; + private const string SubNamespaceInterface_D3Method2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + } +}"; + private const string SubNamespaceInterface_D3Method5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + } +}"; + // system array + private const string ArrayInstanceProperty1 = @" +namespace Test +{ + public sealed class ArrayInstanceProperty1 + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } +}"; + private const string ArrayInstanceProperty2 = @" +namespace Test +{ +public sealed class ArrayInstanceProperty2 + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } +}"; + private const string ArrayInstanceProperty3 = @" +namespace Test +{ + public sealed class ArrayInstanceProperty3 + { + public int[] Arr + { + get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } + +}"; + private const string ArrayInstanceProperty4 = @" +namespace Test +{ +public sealed class ArrayInstanceProperty4 + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } +}"; + private const string ArrayInstanceInterface1 = @" +namespace Test +{ + public interface ArrayInstanceInterface1 + { + System.Array Id(System.Array arr); + } +}"; + private const string ArrayInstanceInterface2 = @" +namespace Test +{ + public interface ArrayInstanceInterface2 + { + void Method2(System.Array arr); + } +}"; + private const string ArrayInstanceInterface3 = @" +namespace Test +{ + public interface ArrayInstanceInterface3 + { + System.Array Method3(); + } +}"; + private const string SystemArrayProperty5 = @" +namespace Test +{ + public sealed class SystemArrayProperty + { + public System.Array Arr { get; set; } + } +}"; + private const string SystemArrayJustReturn = @" +namespace Test +{ + public sealed class JustReturn + { + public System.Array SystemArrayMethod() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string SystemArrayUnaryAndReturn = @" +namespace Test +{ + public sealed class UnaryAndReturn + { + public System.Array SystemArrayMethod(System.Array arr) { return arr; } + } +}"; + private const string SystemArraySecondArgClass = @" +namespace Test +{ + public sealed class SecondArgClass + { + public bool SystemArrayMethod(bool a, System.Array arr) { return a; } + } +}"; + private const string SystemArraySecondArg2Class = @" +namespace Test +{ + public sealed class SecondArg2Class + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string SystemArraySecondArgAndReturnTypeClass = @" +namespace Test +{ + public sealed class SecondArgAndReturnType + { + public System.Array SystemArrayMethod(bool a, System.Array arr) { return arr; } + } +}"; + private const string SystemArraySecondArgAndReturnTypeClass2 = @" +namespace Test +{ + public sealed class SecondArgAndReturnTypeClass2 + { + public System.Array SystemArrayMethod(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string SystemArrayNilArgsButReturnTypeInterface = @" +namespace Test +{ + public interface NilArgsButReturnTypeInterface + { + public System.Array SystemArrayMethod(); + } +}"; + private const string SystemArrayUnaryAndReturnTypeInterface = @" +namespace Test +{ + public interface UnaryAndReturnTypeInterface + { + public System.Array SystemArrayMethod(System.Array arr); + } +}"; + private const string SystemArraySecondArgAndReturnTypeInterface = @" +namespace Test +{ + public interface SecondArgAndReturnTypeInterface + { + public System.Array SystemArrayMethod(bool a, System.Array arr); + } +}"; + private const string SystemArraySecondArgAndReturnTypeInterface2 = @" +namespace Test +{ + public interface SecondArgAndReturnTypeInterface2 + { + public System.Array SystemArrayMetho(bool a, System.Array arr, bool b); + } +}"; + private const string SystemArraySecondArgInterface = @" +namespace Test +{ + public interface SecondArgInterface + { + public bool SystemArrayMethod(bool a, System.Array arr); + } +}"; + private const string SystemArraySecondArgInterface2 = @" +namespace Test +{ + public interface SecondArgInterface2 + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b); + } +}"; + private const string SystemArraySubNamespace_ReturnOnly = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_ReturnOnly + { + public System.Array SystemArrayMethod(); + } + } +}"; + private const string SystemArraySubNamespace_ReturnAndInput1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_ReturnAndInput1 + { + public System.Array SystemArrayMethod(System.Array arr); + } + } +}"; + private const string SystemArraySubNamespace_ReturnAndInput2of2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_ReturnAndInput2of2 + { + public System.Array SystemArrayMethod(bool a, System.Array arr); + } + } +}"; + private const string SystemArraySubNamespace_ReturnAndInput2of3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_ReturnAndInput2of3 + { + public System.Array SystemArrayMethod(bool a, System.Array arr, bool b); + } + } +}"; + private const string SystemArraySubNamespace_NotReturnAndInput2of2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_NotReturnAndInput2of2 + { + public bool SystemArrayMethod(bool a, System.Array arr); + } + } +}"; + private const string SystemArraySubNamespace_NotReturnAndInput2of3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_NotReturnAndInput2of3 + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b); + } + } +}"; + // constructor of same arity + private const string ConstructorsOfSameArity = @" +namespace TestNamespace +{ + public sealed class SameArityConstructors + { + private int num; + private string word; + + public SameArityConstructors(int i) + { + num = i; + word = ""dog""; + } + + public SameArityConstructors(string s) + { + num = 38; + word = s; + } + } +}"; + // async interfaces + private const string ClassImplementsIAsyncOperationWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperationWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncActionWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncOperation = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncAction = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class AsyAction : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string InterfaceImplementsIAsyncOperationWithProgress = @" +using Windows.Foundation; using System; +namespace TestNamespace +{ + public interface OpWithProgress : IAsyncOperationWithProgress {} +}"; + private const string InterfaceImplementsIAsyncActionWithProgress = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public class ActionWithProgress : IAsyncActionWithProgress {} +}"; + private const string InterfaceImplementsIAsyncOperation = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public interface IAsyncOperation : IAsyncOperation {} +}"; + private const string InterfaceImplementsIAsyncAction = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public interface AsyAction : IAsyncAction {} +}"; + private const string InterfaceImplementsIAsyncOperationWithProgress2 = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public interface OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + void IAsyncInfo.Close(); + int IAsyncOperationWithProgress.GetResults(); + } +}"; + private const string InterfaceImplementsIAsyncActionWithProgress2 = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string InterfaceImplementsIAsyncOperation2 = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string InterfaceImplementsIAsyncAction2 = @" +using Windows.Foundation; +using System; +namespace TestNamespace +{ + public sealed class AsyAction : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +}"; + + // readonlyarray / writeonlyarray attribute + private const string TestArrayParamAttrUnary_1 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void BothAttributes_Separate([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] + [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) + { + return; + } + } +}"; + private const string TestArrayParamAttrUnary_2 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void BothAttributes_Together([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string TestArrayParamAttrUnary_3 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string TestArrayParamAttrUnary_4 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void ArrayMarkedIn([In] int[] arr) { } + } +}"; + private const string TestArrayParamAttrUnary_5 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void ArrayMarkedOut([Out] int[] arr) { } + } +}"; + private const string TestArrayParamAttrUnary_6 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } + } +}"; + private const string TestArrayParamAttrUnary_7 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } + } +}"; + private const string TestArrayParamAttrUnary_8 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void ParamMarkedIn([In] int arr) { } + } +}"; + private const string TestArrayParamAttrUnary_9 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void ParamMarkedOut([Out] int arr) { } + } +}"; + private const string TestArrayParamAttrUnary_10 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void ArrayNotMarked(int[] arr) { } + } +}"; + private const string TestArrayParamAttrUnary_11 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void ParamMarkedIn([System.Runtime.InteropServices.In] int arr) { } + } +}"; + private const string TestArrayParamAttrUnary_12 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void ParamMarkedOut([System.Runtime.InteropServices.Out] int arr) { } + } +}"; + private const string TestArrayParamAttrUnary_13 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void ArrayMarkedIn([System.Runtime.InteropServices.In] int[] arr) { } + } +}"; + private const string TestArrayParamAttrUnary_14 = @" +namespace Test +{ + public sealed class OnlyParam + { + public void ArrayMarkedOut([System.Runtime.InteropServices.Out] int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_1 = @" +namespace Test +{ + public sealed class TwoParam + { + public void BothAttributes_Separate(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_2 = @" +namespace Test +{ + public sealed class TwoParam + { + public void BothAttributes_Together(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_3 = @" +namespace Test +{ + public sealed class TwoParam + { + public void MarkedOutAndReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string TestArrayParamAttrBinary_4 = @" +namespace Test +{ + public sealed class TwoParam + { + public void ArrayMarkedIn(int i, [In] int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_5 = @" +namespace Test +{ + public sealed class TwoParam + { + public void ArrayMarkedOut(int i, [Out] int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_6 = @" +namespace Test +{ + public sealed class TwoParam + { + public void NonArrayMarkedReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } + } +}"; + private const string TestArrayParamAttrBinary_7 = @" +namespace Test +{ + public sealed class TwoParam + { + public void NonArrayMarkedWriteOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } + } +}"; + private const string TestArrayParamAttrBinary_8 = @" +namespace Test +{ + public sealed class TwoParam + { + public void ParamMarkedIn(int i, [In] int arr) { } + } +}"; + private const string TestArrayParamAttrBinary_9 = @" +namespace Test +{ + public sealed class TwoParam + { + public void ParamMarkedOut(int i, [Out] int arr) { } + } +}"; + private const string TestArrayParamAttrBinary_10 = @" +namespace Test +{ + public sealed class TwoParam + { + public void ArrayNotMarked(int i, int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_11 = @" +namespace Test +{ + public sealed class TwoArray + { + public void OneValidOneInvalid_1( + [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, + [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] + [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] ys) + { + return; + } + } +}"; + private const string TestArrayParamAttrBinary_12 = @" +namespace Test +{ + public sealed class TwoArray + { + public void OneValidOneInvalid_2( + [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] + [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, + [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] ys) + { + return; + } + } +}"; + private const string TestArrayParamAttrBinary_13 = @" +namespace Test +{ + public sealed class TwoArray + { + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) + { + arr = new int[] { }; + } + } +}"; + private const string TestArrayParamAttrBinary_14 = @" +namespace Test{ + public sealed class TwoParam + { + public void ArrayMarkedIn(int i, [In] int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_15 = @" +namespace Test +{ + public sealed class TwoArray + { + public void ArrayMarkedIn2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_16 = @" +namespace Test +{ + public sealed class TwoArray + { + public void ArrayMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_17 = @" +namespace Test +{ + public sealed class TwoArray + { + public void ArrayNotMarked(int i, int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_18 = @" +namespace Test +{ + public sealed class TwoArray + { + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i) { } + } +}"; + private const string TestArrayParamAttrBinary_19 = @" +namespace Test +{ + public sealed class TwoArray + { + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int i) { } + } +}"; + private const string TestArrayParamAttrBinary_20 = @" +namespace Test +{ + public sealed class TwoArray + { + public void NonArrayMarkedWriteOnly2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string TestArrayParamAttrBinary_21 = @" +namespace Test +{ + public sealed class TwoArray + { + public void ParamMarkedIn([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int arr) { } + } +}"; + private const string TestArrayParamAttrBinary_22 = @" +namespace Test +{ + public sealed class TwoArray + { + public void ParamMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int arr) { } + } +}"; + private const string TestArrayParamAttrBinary_23 = @" +namespace Test +{ + public sealed class TwoArray + { + public void ParamMarkedOut2([Out] int arr, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs) { } + } +}"; + private const string TestArrayParamAttrBinary_24 = @" +namespace Test +{ + public sealed class TwoArray + { + public void ArrayNotMarked([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, int[] arr) { } + } +}"; + // ref param + private const string RefParam_InterfaceMethod = @" +namespace Test +{ + public interface IHaveAMethodWithRefParam + { + void foo(ref int i); + } +}"; + private const string RefParam_ClassMethod = @" +namespace Test +{ + public sealed class ClassWithMethodUsingRefParam + { + public void MethodWithRefParam(ref int i) { i++; } + } +}"; + // operator overload + private const string OperatorOverload_Class = @" +namespace Test +{ + public sealed class ClassThatOverloadsOperator + { + public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) + { + return thing; + } + } +}"; + + // param name conflict + private const string DunderRetValParam = @" +namespace Test +{ + public sealed class ParameterNamedDunderRetVal + { + public int Identity(int __retval) + { + return __retval; + } + } +}"; + // struct fields + private const string StructWithConstructor = @" +namespace Test +{ + public struct StructWithConstructor_Invalid + { + int X; + StructWithConstructor_Invalid(int x) + { + X = x; + } + } +} "; + private const string StructWithClassField = @" +namespace Test +{ + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + + public SillyClass() { } + } + + public struct StructWithClass_Invalid + { + public SillyClass classField; + } +}"; + private const string StructWithClassField2 = @" +namespace Test +{ + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + + public SillyClass() { } + } +} + +namespace Prod +{ + public struct StructWithClass_Invalid + { + public Test.SillyClass classField; + } +}"; + private const string StructWithDelegateField = @" +namespace Test +{ + public struct StructWithDelegate_Invalid + { + public delegate int ADelegate(int x); + } +}"; + private const string StructWithPrimitiveTypesMissingPublicKeyword = @" +namespace Test +{ + public struct StructWithAllValidFields + { + bool boolean; + char character; + decimal dec; + double dbl; + float flt; + int i; + uint nat; + long lng; + ulong ulng; + short sh; + ushort us; + string str; + } +}"; + private const string EmptyStruct = @" +namespace Test +{ + public struct Mt {} +}"; + private const string StructWithIndexer = @" +namespace Test +{ + public struct StructWithIndexer_Invalid + { + int[] arr; + int this[int i] => arr[i]; + } +}"; + private const string StructWithMethods = @" +namespace Test +{ + public struct StructWithMethods_Invalid + { + int foo(int x) + { + return x; + } + } +}"; + private const string StructWithConst = @" +namespace Test +{ + public struct StructWithConst_Invalid + { + const int five = 5; + } +}"; + private const string StructWithProperty = @" +namespace Test +{ + public enum BasicEnum + { + First = 0, + Second = 1 + } + + public struct Posn_Invalid + { + BasicEnum enumField; + + public int x { get; } + public int y { get; } + } +}"; + private const string StructWithPrivateField = @" +namespace Test +{ + public struct StructWithPrivateField_Invalid + { + private int x; + } +}"; + private const string StructWithObjectField = @" +namespace Test +{ + public struct StructWithObjectField_Invalid + { + public object obj; + } +}"; + private const string StructWithDynamicField = @" +namespace Test +{ + public struct StructWithDynamicField_Invalid + { + public dynamic dyn; + } +}"; + private const string TwoOverloads_NoAttribute_NamesHaveNumber = @" +namespace Test +{ + public sealed class TwoOverloads_NoAttribute_WithNum + { + public string OverloadExample1(string s) { return s; } + + public int OverloadExample1(int n) { return n; } + } +}"; + // DefaultOverload attribute tests + private const string TwoOverloads_TwoAttribute_OneInList_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload] + public string OverloadExample(string s) { return s; } + + [DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInList_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_TwoLists_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_TwoLists + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInSeparateList_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInSeparateList + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_Unqualified = @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute + { + [DefaultOverload] + public string OverloadExample(string s) { return s; } + + [DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string ThreeOverloads_TwoAttributes_Unqualified= @" +using Windows.Foundation.Metadata; +namespace Test +{ + public sealed class ThreeOverloads_TwoAttributes + { + public string OverloadExample(string s) { return s; } + + [DefaultOverload] + public int OverloadExample(int n) { return n; } + + [DefaultOverload] + public bool OverloadExample(bool b) { return b; } + } +}"; + private const string TwoOverloads_NoAttribute = @" +namespace Test +{ + public sealed class TwoOverloads_NoAttribute + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInList = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInList + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_NoAttribute_OneIrrevAttr = @" +namespace Test +{ + public sealed class TwoOverloads_NoAttribute_OneIrrevAttr + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInList = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInList + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_TwoLists = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_TwoLists + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInSeparateList = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute_BothInSeparateList + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute = @" +namespace Test +{ + public sealed class TwoOverloads_TwoAttribute + { + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string ThreeOverloads_TwoAttributes = @" +namespace Test +{ + public sealed class ThreeOverloads_TwoAttributes + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } +}"; + // jagged 2d/3d prop + private const string Jagged2D_Property2 = @" +namespace Test +{ + public sealed class Jagged2D_Property2 + { + public int[][] Arr { get; set; } + } +}"; + private const string Jagged3D_Property1 = @" +namespace Test +{ + public sealed class Jagged3D_Property1 + { + public int[][][] Arr3 { get; set; } + } +}"; + // jagged 2d class method + private const string Jagged2D_ClassMethod1 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod1 + { + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + } +}"; + private const string Jagged2D_ClassMethod2 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod2 + { + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + } +}"; + private const string Jagged2D_ClassMethod3 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + } +}"; + private const string Jagged2D_ClassMethod4 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + } +}"; + private const string Jagged2D_ClassMethod5 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + } +}"; + private const string Jagged2D_ClassMethod6 = @" +namespace Test +{ + public sealed class Jagged2D_ClassMethod6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } + } +}"; + // jagged 3d class method + private const string Jagged3D_ClassMethod1 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod1 + { + public int[][][] J3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + + } +}"; + private const string Jagged3D_ClassMethod2 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod1 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod3 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod4 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod5 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + } +}"; + private const string Jagged3D_ClassMethod6 = @" +namespace Test +{ + public sealed class Jagged3D_ClassMethod6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + // jagged 2d interface method + private const string Jagged2D_InterfaceMethod1 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod1 + { + public int[][] J2_ReturnOnly(); + } +}"; + private const string Jagged2D_InterfaceMethod2 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod2 + { + public int[][] J2_ReturnAndInput1(int[,] arr); + } +}"; + private const string Jagged2D_InterfaceMethod3 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + } +}"; + private const string Jagged2D_InterfaceMethod4 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + } +}"; + private const string Jagged2D_InterfaceMethod5 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + } +}"; + private const string Jagged2D_InterfaceMethod6 = @" +namespace Test +{ + public interface Jagged2D_InterfaceMethod6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); + } +}"; + // jagged 2d interface method + private const string Jagged3D_InterfaceMethod1 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod1 + { + public int[][][] J3_ReturnOnly(); + } +}"; + private const string Jagged3D_InterfaceMethod2 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod2 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod3 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod4 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + } +}"; + private const string Jagged3D_InterfaceMethod5 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod6 = @" +namespace Test +{ + public interface Jagged3D_InterfaceMethod6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } +}"; + // subnamespace jagged 2d iface + private const string SubNamespace_Jagged2DInterface1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface1 + { + public int[][] J2_ReturnOnly(); + } + } +}"; + private const string SubNamespace_Jagged2DInterface2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface2 + { + public int[][] J2_ReturnAndInput1(int[,] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + } + } +}"; + private const string SubNamespace_Jagged2DInterface6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); + } + } +}"; + // subnamespace jagged 3d iface + private const string SubNamespace_Jagged3DInterface1 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface1 + { + public int[][][] J3_ReturnOnly(); + } + } +}"; + private const string SubNamespace_Jagged3DInterface2 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface2 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface3 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface4 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + } +}"; + private const string SubNamespace_Jagged3DInterface5 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface6 = @" +namespace Test +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + } +}"; + } +} diff --git a/src/Authoring/DiagnosticTests/PositiveData.cs b/src/Authoring/DiagnosticTests/PositiveData.cs index e3e389222..1082a91e9 100644 --- a/src/Authoring/DiagnosticTests/PositiveData.cs +++ b/src/Authoring/DiagnosticTests/PositiveData.cs @@ -12,8 +12,7 @@ namespace InnerComponent { public sealed class Class2 { public int Y { get; } } } -} -"; +}"; //// DefaultOverload attribute private const string Valid_TwoOverloads_DiffParamCount = @" @@ -28,10 +27,9 @@ public sealed class Valid_TwoOverloads_DiffParamCount private const string Valid_TwoOverloads_OneAttribute_OneInList = @" namespace Test { -public sealed class Valid_TwoOverloads_OneAttribute_OneInList + public sealed class Valid_TwoOverloads_OneAttribute_OneInList { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), Windows.Foundation.Metadata.DefaultOverload()] public string OverloadExample(string s) { return s; } @@ -44,8 +42,7 @@ namespace Test { public sealed class Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute { - - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] public string OverloadExample(string s) { return s; } [Windows.Foundation.Metadata.DefaultOverload()] @@ -55,10 +52,10 @@ public sealed class Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute private const string Valid_TwoOverloads_OneAttribute_TwoLists = @" namespace Test { - public sealed class Valid_TwoOverloads_OneAttribute_TwoLists + public sealed class Valid_TwoOverloads_OneAttribute_TwoLists { - [Windows.Foundation.Metadata.Deprecated(""hu"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] [Windows.Foundation.Metadata.DefaultOverload()] public string OverloadExample(string s) { return s; } @@ -70,7 +67,6 @@ namespace Test { public sealed class Valid_ThreeOverloads_OneAttribute { - public string OverloadExample(string s) { return s; } [Windows.Foundation.Metadata.DefaultOverload()] @@ -159,7 +155,7 @@ public int[][][] J3_ReturnOnly() private const string Valid_Jagged3D_PublicClassPrivateMethods = @" namespace Test { -public sealed class Valid_Jagged3D_PublicClassPrivateMethods + public sealed class Valid_Jagged3D_PublicClassPrivateMethods { private int[][][] D3_ReturnOnly() { @@ -198,7 +194,7 @@ public sealed class Jagged3D_Property2 private const string Valid_MultiDimArray_PrivateClassPublicProperty1 = @" namespace Test { -internal class Valid_MultiDimArray_PrivateClassPublicProperty1 + internal class Valid_MultiDimArray_PrivateClassPublicProperty1 { public int[,] Arr_2d { get; set; } } @@ -206,7 +202,6 @@ internal class Valid_MultiDimArray_PrivateClassPublicProperty1 private const string Valid_MultiDimArray_PrivateClassPublicProperty2 = @" namespace Test { - internal class Valid_MultiDimArray_PrivateClassPublicProperty2 { public int[,,] Arr_3d { get; set; } @@ -215,7 +210,7 @@ internal class Valid_MultiDimArray_PrivateClassPublicProperty2 private const string Valid_MultiDimArray_PrivateClassPublicProperty3 = @" namespace Test { -internal class Valid_MultiDimArray_PrivateClassPublicProperty3 + internal class Valid_MultiDimArray_PrivateClassPublicProperty3 { private int[,] PrivArr_2d { get; set; } } @@ -223,7 +218,7 @@ internal class Valid_MultiDimArray_PrivateClassPublicProperty3 private const string Valid_MultiDimArray_PrivateClassPublicProperty4 = @" namespace Test { -internal class Valid_MultiDimArray_PrivateClassPublicProperty4 + internal class Valid_MultiDimArray_PrivateClassPublicProperty4 { private int[,,] PrivArr_3d { get; set; } } @@ -231,7 +226,7 @@ internal class Valid_MultiDimArray_PrivateClassPublicProperty4 private const string Valid_MultiDimArray_PublicClassPrivateProperty1 = @" namespace Test { -public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 { private int[,] PrivArr_2d { get; set; } } @@ -248,7 +243,7 @@ public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 private const string Valid_2D_PrivateClass_PublicMethod1 = @" namespace Test { -internal sealed class Valid_2D_PrivateClass_PublicMethod1 + internal sealed class Valid_2D_PrivateClass_PublicMethod1 { public int[,] D2_ReturnOnly() { return new int[4, 2]; } } @@ -264,7 +259,7 @@ internal sealed class Valid_2D_PrivateClass_PublicMethod2 private const string Valid_2D_PrivateClass_PublicMethod3 = @" namespace Test { -internal sealed class Valid_2D_PrivateClass_PublicMethod3 + internal sealed class Valid_2D_PrivateClass_PublicMethod3 { public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } } @@ -297,7 +292,7 @@ internal sealed class Valid_2D_PrivateClass_PublicMethod6 private const string Valid_3D_PrivateClass_PublicMethod1 = @" namespace Test { -internal sealed class Valid_3D_PrivateClass_PublicMethod1 + internal sealed class Valid_3D_PrivateClass_PublicMethod1 { public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } } @@ -354,7 +349,7 @@ public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 private const string Valid_MultiDimArray_PublicClassPrivateMethod2 = @" namespace Test { -public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 { private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } } @@ -378,7 +373,7 @@ public sealed class Valid_MultiDimArray_PublicClassPrivateProperty4 private const string Valid_MultiDimArray_PublicClassPrivateMethod5 = @" namespace Test { -public sealed class Valid_MultiDimArray_PublicClassPrivateProperty5 + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty5 { private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } } @@ -395,7 +390,7 @@ public sealed class Valid_MultiDimArray_PublicClassPrivateProperty6 private const string Valid_SystemArray_Interface1 = @" namespace Test { -internal interface Valid_SystemArray_Interface1 + internal interface Valid_SystemArray_Interface1 { System.Array Id(System.Array arr); } @@ -403,7 +398,7 @@ internal interface Valid_SystemArray_Interface1 private const string Valid_SystemArray_Interface2 = @" namespace Test { -internal interface Valid_SystemArray_Interface2 + internal interface Valid_SystemArray_Interface2 { void Method2(System.Array arr); } @@ -419,7 +414,7 @@ internal interface Valid_SystemArray_Interface3 private const string Valid_SystemArray_InternalClass1 = @" namespace Test { -internal class Valid_SystemArray_InternalClass1 + internal class Valid_SystemArray_InternalClass1 { public System.Array Arr_2d { get; set; } } @@ -427,7 +422,7 @@ internal class Valid_SystemArray_InternalClass1 private const string Valid_SystemArray_InternalClass2 = @" namespace Test { -internal class Valid_SystemArray_InternalClass2 + internal class Valid_SystemArray_InternalClass2 { public System.Array Arr_3d { get; set; } @@ -436,7 +431,7 @@ internal class Valid_SystemArray_InternalClass2 private const string Valid_SystemArray_InternalClass3 = @" namespace Test { -internal class Valid_SystemArray_InternalClass3 + internal class Valid_SystemArray_InternalClass3 { private System.Array PrivArr_2d { get; set; } } @@ -444,7 +439,7 @@ internal class Valid_SystemArray_InternalClass3 private const string Valid_SystemArray_InternalClass4 = @" namespace Test { -internal class Valid_SystemArray_InternalClass4 + internal class Valid_SystemArray_InternalClass4 { private System.Array PrivArr_3d { get; set; } } @@ -452,7 +447,7 @@ internal class Valid_SystemArray_InternalClass4 private const string Valid_SystemArray_PublicClassPrivateProperty1 = @" namespace Test { -public sealed class Valid_SystemArray_PublicClassPrivateProperty1 + public sealed class Valid_SystemArray_PublicClassPrivateProperty1 { private System.Array PrivArr_2d { get; set; } } @@ -461,7 +456,7 @@ public sealed class Valid_SystemArray_PublicClassPrivateProperty1 using System; namespace Test { -public sealed class Valid_SystemArray_PublicClassPrivateProperty2 + public sealed class Valid_SystemArray_PublicClassPrivateProperty2 { private Array PrivArr_3d { get; set; } } @@ -469,7 +464,7 @@ public sealed class Valid_SystemArray_PublicClassPrivateProperty2 private const string Valid_SystemArray_PublicClassPrivateProperty3 = @" namespace Test { -public sealed class Valid_SystemArrayPublicClassPrivateProperty3 + public sealed class Valid_SystemArrayPublicClassPrivateProperty3 { private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } } @@ -477,7 +472,7 @@ public sealed class Valid_SystemArrayPublicClassPrivateProperty3 private const string Valid_SystemArray_PublicClassPrivateProperty4 = @" namespace Test { -public sealed class Valid_SystemArrayPublicClassPrivateProperty4 + public sealed class Valid_SystemArrayPublicClassPrivateProperty4 { private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } } @@ -485,7 +480,7 @@ public sealed class Valid_SystemArrayPublicClassPrivateProperty4 private const string Valid_SystemArray_PublicClassPrivateProperty5 = @" namespace Test { -public sealed class Valid_SystemArrayPublicClassPrivateProperty1 + public sealed class Valid_SystemArrayPublicClassPrivateProperty1 { private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } } @@ -501,7 +496,7 @@ public sealed class Valid_SystemArrayPublicClassPrivateProperty2 private const string Valid_SystemArray_InternalClassPublicMethods1 = @" namespace Test { -internal sealed class Valid_SystemArray_InternalClassPublicMethods1 + internal sealed class Valid_SystemArray_InternalClassPublicMethods1 { public System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } @@ -509,7 +504,7 @@ internal sealed class Valid_SystemArray_InternalClassPublicMethods1 private const string Valid_SystemArray_InternalClassPublicMethods2 = @" namespace Test { -internal sealed class Valid_SystemArray_InternalClassPublicMethods2 + internal sealed class Valid_SystemArray_InternalClassPublicMethods2 { public System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } } @@ -517,7 +512,7 @@ internal sealed class Valid_SystemArray_InternalClassPublicMethods2 private const string Valid_SystemArray_InternalClassPublicMethods3 = @" namespace Test { -internal sealed class Valid_SystemArray_InternalClassPublicMethods3 + internal sealed class Valid_SystemArray_InternalClassPublicMethods3 { public System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } } @@ -525,7 +520,7 @@ internal sealed class Valid_SystemArray_InternalClassPublicMethods3 private const string Valid_SystemArray_InternalClassPublicMethods4 = @" namespace Test { -internal sealed class Valid_SystemArray_InternalClassPublicMethods4 + internal sealed class Valid_SystemArray_InternalClassPublicMethods4 { public bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } } @@ -533,7 +528,7 @@ internal sealed class Valid_SystemArray_InternalClassPublicMethods4 private const string Valid_SystemArray_InternalClassPublicMethods5 = @" namespace Test { -internal sealed class Valid_SystemArray_InternalClassPublicMethods5 + internal sealed class Valid_SystemArray_InternalClassPublicMethods5 { public bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } } @@ -541,7 +536,7 @@ internal sealed class Valid_SystemArray_InternalClassPublicMethods5 private const string Valid_SystemArray_InternalClassPublicMethods6 = @" namespace Test { -internal sealed class Valid_SystemArray_InternalClassPublicMethods6 + internal sealed class Valid_SystemArray_InternalClassPublicMethods6 { public System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } } @@ -549,7 +544,7 @@ internal sealed class Valid_SystemArray_InternalClassPublicMethods6 private const string Valid_SystemArray_PrivateClassPublicProperty1 = @" namespace Test { -internal sealed class Valid_SystemArray_PrivateClassPublicProperty1 + internal sealed class Valid_SystemArray_PrivateClassPublicProperty1 { public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } } @@ -557,7 +552,7 @@ internal sealed class Valid_SystemArray_PrivateClassPublicProperty1 private const string Valid_SystemArray_PrivateClassPublicProperty2 = @" namespace Test { -internal sealed class Valid_SystemArray_PrivateClassPublicProperty2 + internal sealed class Valid_SystemArray_PrivateClassPublicProperty2 { public System.Array Arr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } } @@ -565,7 +560,7 @@ internal sealed class Valid_SystemArray_PrivateClassPublicProperty2 private const string Valid_SystemArray_PrivateClassPublicProperty3 = @" namespace Test { -internal sealed class Valid_SystemArray_PrivateClassPublicProperty3 + internal sealed class Valid_SystemArray_PrivateClassPublicProperty3 { public int[] Arr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } } @@ -573,7 +568,7 @@ internal sealed class Valid_SystemArray_PrivateClassPublicProperty3 private const string Valid_SystemArray_PrivateClassPublicProperty4 = @" namespace Test { -internal sealed class Valid_SystemArray_PrivateClassPublicProperty4 + internal sealed class Valid_SystemArray_PrivateClassPublicProperty4 { public System.Array Arr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } } @@ -581,7 +576,7 @@ internal sealed class Valid_SystemArray_PrivateClassPublicProperty4 private const string Valid_SystemArray_PrivateClassPublicProperty5 = @" namespace Test { -internal sealed class Valid_SystemArray_PrivateClassPublicProperty5 + internal sealed class Valid_SystemArray_PrivateClassPublicProperty5 { private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } } @@ -589,7 +584,7 @@ internal sealed class Valid_SystemArray_PrivateClassPublicProperty5 private const string Valid_SystemArray_PrivateClassPublicProperty6 = @" namespace Test { -internal sealed class Valid_SystemArray_PrivateClassPublicProperty6 + internal sealed class Valid_SystemArray_PrivateClassPublicProperty6 { private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } } @@ -597,7 +592,7 @@ internal sealed class Valid_SystemArray_PrivateClassPublicProperty6 private const string Valid_SystemArray_PrivateClassPublicProperty7 = @" namespace Test { -internal sealed class Valid_SystemArray_PrivateClassPublicProperty7 + internal sealed class Valid_SystemArray_PrivateClassPublicProperty7 { private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } } @@ -605,7 +600,7 @@ internal sealed class Valid_SystemArray_PrivateClassPublicProperty7 private const string Valid_SystemArray_PrivateClassPublicProperty8 = @" namespace Test { -internal sealed class Valid_SystemArray_PrivateClassPublicProperty8 + internal sealed class Valid_SystemArray_PrivateClassPublicProperty8 { private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } } @@ -613,7 +608,7 @@ internal sealed class Valid_SystemArray_PrivateClassPublicProperty8 private const string Valid_SystemArrayPublicClassPrivateMethod1 = @" namespace Test { -public sealed class Valid_SystemArrayPublicClassPrivateMethod1 + public sealed class Valid_SystemArrayPublicClassPrivateMethod1 { private System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } @@ -621,7 +616,7 @@ public sealed class Valid_SystemArrayPublicClassPrivateMethod1 private const string Valid_SystemArrayPublicClassPrivateMethod2 = @" namespace Test { -public sealed class Valid_SystemArrayPublicClassPrivateMethod2 + public sealed class Valid_SystemArrayPublicClassPrivateMethod2 { private System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } } @@ -629,7 +624,7 @@ public sealed class Valid_SystemArrayPublicClassPrivateMethod2 private const string Valid_SystemArrayPublicClassPrivateMethod3 = @" namespace Test { -public sealed class Valid_SystemArrayPublicClassPrivateMethod3 + public sealed class Valid_SystemArrayPublicClassPrivateMethod3 { private System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } } @@ -637,7 +632,7 @@ public sealed class Valid_SystemArrayPublicClassPrivateMethod3 private const string Valid_SystemArrayPublicClassPrivateMethod4 = @" namespace Test { -public sealed class Valid_SystemArrayPublicClassPrivateMethod4 + public sealed class Valid_SystemArrayPublicClassPrivateMethod4 { private System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } } @@ -645,7 +640,7 @@ public sealed class Valid_SystemArrayPublicClassPrivateMethod4 private const string Valid_SystemArrayPublicClassPrivateMethod5 = @" namespace Test { -public sealed class Valid_SystemArrayPublicClassPrivateMethod5 + public sealed class Valid_SystemArrayPublicClassPrivateMethod5 { private bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } } @@ -670,120 +665,120 @@ public sealed class SystemArrayProperty_Valid private const string Valid_ArrayParamAttrUnary_1 = @" namespace TestNamespace { - public sealed class OnlyParam - { - public int GetSum([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } - } + public sealed class OnlyParam + { + public int GetSum([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } }"; private const string Valid_ArrayParamAttrUnary_2 = @" namespace TestNamespace { - public sealed class OnlyParam - { - public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } + public sealed class OnlyParam + { + public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } }"; private const string Valid_ArrayParamAttrUnary_3 = @" namespace TestNamespace { - public sealed class OnlyParam - { + public sealed class OnlyParam + { public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } + } }"; private const string Valid_ArrayParamAttrUnary_4 = @" namespace TestNamespace { - public sealed class OnlyParam - { + public sealed class OnlyParam + { public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } - } + } }"; private const string Valid_ArrayParamAttrUnary_5 = @" namespace TestNamespace { - public sealed class OnlyParam - { + public sealed class OnlyParam + { public void ArrayNotMarked_Valid(out int[] arr) { arr = new int[] { }; } - } + } }"; private const string Valid_ArrayParamAttrBinary_1 = @" namespace TestNamespace { - public sealed class TwoParam - { - public int GetSum(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } - } + public sealed class TwoParam + { + public int GetSum(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } }"; private const string Valid_ArrayParamAttrBinary_2 = @" namespace TestNamespace { - public sealed class TwoParam - { - public void MarkedWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } + public sealed class TwoParam + { + public void MarkedWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } }"; private const string Valid_ArrayParamAttrBinary_3 = @" namespace TestNamespace { - public sealed class TwoParam - { + public sealed class TwoParam + { public void MarkedOutAndWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } + } }"; private const string Valid_ArrayParamAttrBinary_4 = @" namespace TestNamespace { - public sealed class TwoParam - { + public sealed class TwoParam + { public void MarkedOutOnly_Valid(int i, out int[] arr) { arr = new int[] { }; } - } + } }"; private const string Valid_ArrayParamAttrBinary_5 = @" namespace TestNamespace { - public sealed class TwoParam - { + public sealed class TwoParam + { public void ArrayNotMarked_Valid(int i, out int[] arr) { arr = new int[] { }; } - } + } }"; private const string Valid_ArrayParamAttrBinary_6 = @" namespace TestNamespace { - public sealed class TwoArray - { + public sealed class TwoArray + { public void MarkedReadOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } - } + } }"; private const string Valid_ArrayParamAttrBinary_7 = @" namespace TestNamespace { - public sealed class TwoArray - { + public sealed class TwoArray + { public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } + } }"; private const string Valid_ArrayParamAttrBinary_8 = @" namespace TestNamespace { - public sealed class TwoArray - { + public sealed class TwoArray + { public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } + } }"; private const string Valid_ArrayParamAttrBinary_9 = @" namespace TestNamespace { - public sealed class TwoArray - { + public sealed class TwoArray + { public void MarkedOut_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, out int[] arr) { arr = new int[] { }; } - } + } }"; //// Struct field private const string Valid_StructWithByteField = @" namespace Test { -public struct StructWithByteField_Valid + public struct StructWithByteField_Valid { public byte b; } From 8231eb6e8c6817db3185f022513ac906a110b6df Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Thu, 17 Dec 2020 12:55:31 -0800 Subject: [PATCH 37/41] remove workarounds --- .../WinRT.SourceGenerator/Generator.cs | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index cfa02ec55..e05bb2b35 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -224,32 +224,12 @@ private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) return found; } - private void AddArrayAttributes(ref GeneratorExecutionContext context) - { - context.AddSource("System.Runtime.InteropServices.WindowsRuntime", SourceText.From(@" -namespace System.Runtime.InteropServices.WindowsRuntime -{ - [global::System.AttributeUsage(System.AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] - internal sealed class ReadOnlyArrayAttribute : global::System.Attribute - { - } - [global::System.AttributeUsage(System.AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] - internal sealed class WriteOnlyArrayAttribute : global::System.Attribute - { - } -}", Encoding.UTF8)); - } - public void Execute(GeneratorExecutionContext context) { - /* Temporary workaround needed when unit testing -- need to specify - * this property on the unit test's source code's anlayzer config options - * ***** if (!IsCsWinRTComponent(context)) { return; } - */ Logger.Initialize(context); From b6f3fac658a1b611bca1fb3ee940a6e3b0b2ff68 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Thu, 17 Dec 2020 13:11:11 -0800 Subject: [PATCH 38/41] clean the diagnostic rules clean rules --- .../DiagnosticTests/UnitTestDiagnostics.cs | 36 +++++++------ .../WinRT.SourceGenerator/DiagnosticRules.cs | 50 ++++++------------- .../WinRT.SourceGenerator/DiagnosticUtils.cs | 2 +- .../WinRT.SourceGenerator/Generator.cs | 2 - 4 files changed, 36 insertions(+), 54 deletions(-) diff --git a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs index eaee3b3f5..b13c8bdc2 100644 --- a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs +++ b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs @@ -9,15 +9,19 @@ namespace DiagnosticTests { [TestFixture] public partial class TestDiagnostics - { - /// Add unit tests by creating a source code like this: - /// private const string MyNewTest = @"namespace Test { ... }"; - /// - /// And have a DiagnosticDescriptor for the one to check for, they live in WinRT.SourceGenerator.DiagnosticRules - /// - /// Then go to the ValidCases/InvalidCases property here and add an entry for it - - + { + /* UnitTests require the "IsCsWinRTComponent" check in Generator.cs to be commented out, + until we can pass AnalyzerConfigOptions in our TestHelpers.cs file + --- + Add unit tests by creating a source code like this: + private const string MyNewTest = @"namespace Test { ... }"; + + And have a DiagnosticDescriptor for the one to check for, they live in WinRT.SourceGenerator.DiagnosticRules + + Then go to the ValidCases/InvalidCases property here and add an entry for it + */ + + /// /// CheckNoDiagnostic asserts that no diagnostics are raised on the /// compilation produced from the cswinrt source generator based on the given source code /// @@ -26,7 +30,7 @@ public partial class TestDiagnostics public void CheckNoDiagnostic(string source) { Compilation compilation = CreateCompilation(source); - RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); + RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); var WinRTDiagnostics = diagnosticsFound.Where(diag => diag.Id.StartsWith("WME")); Assert.That(!WinRTDiagnostics.Any()); } @@ -42,8 +46,8 @@ public void CodeHasDiagnostic(string testCode, DiagnosticDescriptor rule) RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); HashSet diagDescsFound = MakeDiagnosticSet(diagnosticsFound); Assert.That(diagDescsFound.Contains(rule)); - } - + } + #region InvalidTests private static IEnumerable InvalidCases { @@ -295,12 +299,12 @@ private static IEnumerable InvalidCases yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 5/6"); yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 6/6"); } - } - + } + #endregion - + #region ValidTests - + private static IEnumerable ValidCases { get diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs index f37ef44cb..37afd84b9 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs @@ -4,13 +4,11 @@ namespace WinRT.SourceGenerator { public class DiagnosticRules { - /// - /// helper function that does most of the boilerplate information needed for Diagnostics - /// + /// Helper function that does most of the boilerplate information needed for Diagnostics /// string, a short identifier for the diagnostic /// string, a few words generally describing the diagnostic /// string, describes the diagnostic -- formatted with {0}, ... -- - /// such that data can be passed in for the code the diagnostic is reported for /// + /// such that data can be passed in for the code the diagnostic is reported for private static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) { return new DiagnosticDescriptor( @@ -43,16 +41,15 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( "WME1092", "Parameter Named Value Rule", - ("The method {0} has a parameter named {1} which is the same as the default return value name. " + "The method {0} has a parameter named {1} which is the same as the default return value name. " + "Consider using another name for the parameter or use the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute " - + "to explicitly specify the name of the return value.")); + + "to explicitly specify the name of the return value."); public static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( "WME1060(b)", "Private field in struct", "Structure {0} has non-public field. All fields must be public for Windows Runtime structures."); - public static DiagnosticDescriptor StructHasConstFieldRule = MakeRule( "WME1060(b)", "Const field in struct", @@ -61,14 +58,14 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( "WME1060", "Invalid field in struct", - ("Structure {0} has field '{1}' of type {2}; {2} is not a valid Windows Runtime field type. Each field " - + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.")); + "Structure {0} has field '{1}' of type {2}; {2} is not a valid Windows Runtime field type. Each field " + + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure."); public static DiagnosticDescriptor StructHasInvalidFieldRule2 = MakeRule( "WME1060", "Invalid field in struct", - ("Structure {0} has a field of type {1}; {1} is not a valid Windows Runtime field type. Each field " - + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure.")); + "Structure {0} has a field of type {1}; {1} is not a valid Windows Runtime field type. Each field " + + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure."); public static DiagnosticDescriptor OperatorOverloadedRule = MakeRule( "WME1087", @@ -77,46 +74,37 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor MethodOverload_MultipleDefaultAttribute = MakeRule( "WME1059", - "Only one overload should be designated default", // todo better msg - //"Multiple {0}-parameter overloads of '{1}.{2}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); - "In class {2}: Multiple {0}-parameter overloads of '{1}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + "Only one overload should be designated default", + "In class {2}: Multiple {0}-parameter overloads of '{1}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute. The attribute may only be applied to one overload of the method."); public static DiagnosticDescriptor MethodOverload_NeedDefaultAttribute = MakeRule( "WME1085", "Multiple overloads seen, one needs a default", // todo better msg - //"The {0}-parameter overloads of {1}.{2} must have exactly one method specified as the default overload - // by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); "In class {2}: The {0}-parameter overloads of {1} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); public static DiagnosticDescriptor ArraySignature_JaggedArrayRule = MakeRule( "WME1036", "Array signature found with jagged array, which is not a valid WinRT type", - // "Method {0} has a nested array of type {1} in its signature. Arrays in Windows Runtime method signature cannot be nested."); public static DiagnosticDescriptor ArraySignature_MultiDimensionalArrayRule = MakeRule( "WME1035", "Array signature found with multi-dimensional array, which is not a valid WinRT type", - // "Method '{0}' has a multi-dimensional array of type '{1}' in its signature. Arrays in Windows Runtime method signatures must be one dimensional."); public static DiagnosticDescriptor ArraySignature_SystemArrayRule = MakeRule( - "WME10??", - "Array signature found with System.Array instance, which is not a valid WinRT type", // todo better msg - // // - "In type {0}: the method {1} has signature that contains a System.Array instance; use a different type like List"); - // "Method {0} has a multi-dimensional array of type {1} in its signature. Arrays in Windows Runtime must be one dimensional" + "WME1034", + "Array signature found with System.Array instance, which is not a valid WinRT type", + "In type {0}: the method {1} has signature that contains a System.Array instance; SystemArray is not a valid Windows Runtime type. Try using a different type like IList"); public static DiagnosticDescriptor RefParameterFound = MakeRule( - "WME11??", + "WME", "Parameter passed by reference", - // "Method '{0}' has parameter '{1}' marked `ref`. Reference parameters are not allowed in Windows Runtime."); public static DiagnosticDescriptor ArrayMarkedInOrOut = MakeRule( "WME1103", "Array parameter marked InAttribute or OutAttribute", - // "Method '{0}' has parameter '{1}' which is an array, and which has either a " + "System.Runtime.InteropServices.InAttribute or a System.Runtime.InteropServices.OutAttribute. " + "In the Windows Runtime, array parameters must have either ReadOnlyArray or WriteOnlyArray. " @@ -127,7 +115,6 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes "WME1105", "Parameter (not array type) marked InAttribute or OutAttribute", "Method '{0}' has parameter '{1}' with a System.Runtime.InteropServices.InAttribute " - // + "or System.Runtime.InteropServices.OutAttribute.Windows Runtime does not support " + "marking parameters with System.Runtime.InteropServices.InAttribute or " + "System.Runtime.InteropServices.OutAttribute. Please consider removing " @@ -137,32 +124,25 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor ArrayParamMarkedBoth = MakeRule( "WME1101", "Array paramter marked both ReadOnlyArray and WriteOnlyArray", - // "Method '{0}' has parameter '{1}' which is an array, and which has both ReadOnlyArray and WriteOnlyArray. " + "In the Windows Runtime, the contents array parameters must be either readable " + "or writable.Please remove one of the attributes from '{1}'."); - /// WME1102 public static DiagnosticDescriptor ArrayOutputParamMarkedRead = MakeRule( "WME1102", "Array parameter marked `out` and ReadOnlyArray", - // "Method '{0}' has an output parameter '{1}' which is an array, but which has ReadOnlyArray attribute. In the Windows Runtime, " + "the contents of output arrays are writable.Please remove the attribute from '{1}'."); - /// WME1106 public static DiagnosticDescriptor ArrayParamNotMarked = MakeRule( "WME1106", "Array parameter not marked ReadOnlyArray or WriteOnlyArray way", - // "Method '{0}' has parameter '{1}' which is an array. In the Windows Runtime, the " - + "contents of array parameters must be either readable or writable.Please apply either ReadOnlyArray or WriteOnlyArray to '{1}'." - + "hasWriteOnly: {2} ; hasReadOnly: {3} ; HasOut: {4}"); + + "contents of array parameters must be either readable or writable.Please apply either ReadOnlyArray or WriteOnlyArray to '{1}'."); public static DiagnosticDescriptor NonArrayMarked = MakeRule( "WME1104", "Non-array parameter marked with ReadOnlyArray or WriteOnlyArray", - // "Method '{0}' has parameter '{1}' which is not an array, and which has either a " + "ReadOnlyArray attribute or a WriteOnlyArray attribute . Windows Runtime does " + "not support marking non-array parameters with ReadOnlyArray or WriteOnlyArray."); diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index 339194518..69b235736 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -376,7 +376,7 @@ private bool CheckParamsForArrayAttributes(MethodDeclarationSyntax method, ref G // must have some indication of ReadOnly or WriteOnly else if (!hasWriteOnlyArray && !hasReadOnlyArray && !isOutputParam) { - Report(ref context, DiagnosticRules.ArrayParamNotMarked, method.GetLocation(), method.Identifier, param.Identifier, hasWriteOnlyArray, hasReadOnlyArray, isOutputParam); + Report(ref context, DiagnosticRules.ArrayParamNotMarked, method.GetLocation(), method.Identifier, param.Identifier); found |= true; } } diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index e05bb2b35..fd9677eaf 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -233,8 +233,6 @@ public void Execute(GeneratorExecutionContext context) Logger.Initialize(context); - AddArrayAttributes(ref context); - if (CatchWinRTDiagnostics(ref context)) { Logger.Log("Exiting early -- found errors in authored runtime component."); From 70ec2bcc0c5640f895036e41616236a3730c0ec9 Mon Sep 17 00:00:00 2001 From: Joshua Larkin <70237359+j0shuams@users.noreply.github.com> Date: Wed, 30 Dec 2020 15:17:04 -0800 Subject: [PATCH 39/41] Add final diagnostics, refactoring (#643) * add tests for exposing invalid types * consolidating signature checks * splitting utilities into two files, catching (some) invalid types * bool to void change * using class fields instead of passing reference * add namespace diagnostic, reorganize * enumerable tests should be nongeneric * add test for basetype and bad interface * add case for basetype implementing not valid interfaces * fix test names * rename scanner * clean up IsInvalidNamespace * custom map, struct refactoring * custom type mapping support * Better custom type mapping support * Add special case for AsyncAction --- src/Authoring/AuthoringSample/Program.cs | 6 +- .../DiagnosticTests/DiagnosticTests.csproj | 3 +- .../{TestHelpers.cs => Helpers.cs} | 16 +- src/Authoring/DiagnosticTests/NegativeData.cs | 4674 +++++++++-------- src/Authoring/DiagnosticTests/PositiveData.cs | 2388 ++++++--- .../DiagnosticTests/UnitTestDiagnostics.cs | 415 -- src/Authoring/DiagnosticTests/UnitTesting.cs | 562 ++ .../DiagnosticHelpers.cs | 436 ++ .../WinRT.SourceGenerator/DiagnosticUtils.cs | 894 ++-- .../WinRT.SourceGenerator/Generator.cs | 574 +- .../{DiagnosticRules.cs => WinRTRules.cs} | 327 +- .../WinRT.SourceGenerator/WinRTTypeWriter.cs | 8 +- 12 files changed, 5936 insertions(+), 4367 deletions(-) rename src/Authoring/DiagnosticTests/{TestHelpers.cs => Helpers.cs} (81%) delete mode 100644 src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs create mode 100644 src/Authoring/DiagnosticTests/UnitTesting.cs create mode 100644 src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs rename src/Authoring/WinRT.SourceGenerator/{DiagnosticRules.cs => WinRTRules.cs} (75%) diff --git a/src/Authoring/AuthoringSample/Program.cs b/src/Authoring/AuthoringSample/Program.cs index abe508325..aacef833e 100644 --- a/src/Authoring/AuthoringSample/Program.cs +++ b/src/Authoring/AuthoringSample/Program.cs @@ -3,12 +3,11 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Reflection; using System.Threading; using System.Threading.Tasks; using Windows.Foundation; using Windows.Foundation.Metadata; -using WinRT; +using System.Runtime.InteropServices.WindowsRuntime; namespace AuthoringSample { @@ -181,7 +180,7 @@ public struct ComplexStruct public BasicStruct BasicStruct; } - public class CustomWWW : IWwwFormUrlDecoderEntry + public sealed class CustomWWW : IWwwFormUrlDecoderEntry { public string Name => "CustomWWW"; @@ -330,6 +329,7 @@ public int GetSum(CustomDictionary dictionary, string element) return -1; } + public void SetTypeToTestClass() { Type = typeof(TestClass); diff --git a/src/Authoring/DiagnosticTests/DiagnosticTests.csproj b/src/Authoring/DiagnosticTests/DiagnosticTests.csproj index 57dc7acde..e080e85aa 100644 --- a/src/Authoring/DiagnosticTests/DiagnosticTests.csproj +++ b/src/Authoring/DiagnosticTests/DiagnosticTests.csproj @@ -1,8 +1,7 @@  - netcoreapp3.1 - + net5.0-windows10.0.19041.0 false diff --git a/src/Authoring/DiagnosticTests/TestHelpers.cs b/src/Authoring/DiagnosticTests/Helpers.cs similarity index 81% rename from src/Authoring/DiagnosticTests/TestHelpers.cs rename to src/Authoring/DiagnosticTests/Helpers.cs index 5aa1baa09..1f61ae37e 100644 --- a/src/Authoring/DiagnosticTests/TestHelpers.cs +++ b/src/Authoring/DiagnosticTests/Helpers.cs @@ -1,7 +1,5 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.VisualBasic; -using NUnit.Framework; using System.Collections.Immutable; using System.Collections.Generic; using System.Linq; @@ -9,19 +7,19 @@ namespace DiagnosticTests { - public partial class TestDiagnostics + public sealed partial class UnitTesting { /// /// CreateCompilation creates a CSharpCompilation /// /// string of source code /// - private Compilation CreateCompilation(string source) - => CSharpCompilation.Create( - assemblyName: "compilation", - syntaxTrees: new[] { CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Preview)) }, - references: new[] { MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location) }, - options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + private Compilation CreateCompilation(string source) + => CSharpCompilation.Create( + assemblyName: "compilation", + syntaxTrees: new[] { CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Preview)) }, + references: new[] { MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location) }, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); /// /// CreateDriver makes a CSharpGeneratorDriver diff --git a/src/Authoring/DiagnosticTests/NegativeData.cs b/src/Authoring/DiagnosticTests/NegativeData.cs index 93b5140fd..e3f8ae299 100644 --- a/src/Authoring/DiagnosticTests/NegativeData.cs +++ b/src/Authoring/DiagnosticTests/NegativeData.cs @@ -1,2142 +1,2532 @@ -namespace DiagnosticTests -{ - public partial class TestDiagnostics - { - - // Cases to add -- WIP - private const string StructWithInterfaceField = @" -namespace Test -{ - public interface Foo - { - int Id(int i); - } - - public struct StructWithIface_Invalid - { - public Foo ifaceField; - } -}"; - - private const string UnsealedClass = @" -namespace Test -{ - public class UnsealedClass - { - public UnsealedClass() {} - } -}"; - private const string UnsealedClass2 = @" -namespace Test -{ - public class UnsealedClass - { - private UnsealedClass() {} - } -}"; - - private const string GenericClass = @" -namespace Test -{ - public sealed class GenericClass - { - public UnsealedClass() {} - } -}"; - private const string GenericInterface = @" -namespace Test -{ - public interface GenIface - { - int Foo(T input); - } -}"; - - private const string InterfaceInheritsException = @" -namespace Test -{ - public interface IfaceWithExceptions : System.Exception - { - int Foo(T input); - } -}"; - private const string ClassInheritsException = @" -namespace Test -{ - public sealed class ClassWithExceptions : System.Exception - { - public ClassWithExceptions() {} - } -}"; - - // namespace tests -- WIP - private const string _NamespaceTest1 = @" -namespace Test -{ - namespace OtherNamespace_Valid - { - public sealed class Class1 - { - int x; - public Class1(int a) { x = a; } - } - } - - // WME1068 - public sealed class TestDiagnostics - { - bool b; - public TestDiagnostics(bool x) { b = x; } - } -} -}"; - private const string _NamespaceTest2 = @" -namespace OtherNamespace -{ - - // WME1044 ? - public sealed class Class1 - { - int x; - - public Class1(int a) - { - x = a; - } - } -}"; - private const string _NamespaceTest3 = @" -namespace Test -{ - // WME1067 ?? - namespace InnerNamespace - { - public sealed class Class1 - { - int x; - public Class1(int a) { x = a; } - } - } -}"; - // multidim array - private const string MultiDim_2DProp = @" -namespace Test -{ - public sealed class MultiDim_2DProp - { - public int[,] Arr_2d { get; set; } - private int[,] PrivArr_2d { get; set; } - } -}"; - private const string MultiDim_3DProp = @" -namespace Test -{ - public sealed class MultiDim_3DProp - { - public int[,,] Arr_3d { get; set; } - private int[,] PrivArr_2d { get; set; } - } -}"; - private const string MultiDim_3DProp_Whitespace = @" -namespace Test -{ - public sealed class MultiDim_3DProp - { - public int[ , , ] Arr_3d { get; set; } - private int[,] PrivArr_2d { get; set; } - } -}"; - // 2d class - private const string MultiDim_2D_PublicClassPublicMethod1 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod1 - { - public int[,] D2_ReturnOnly() { return new int[4, 2]; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod2 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod2 - { - public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod3 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod3 - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod4 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod4 - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod5 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod5 - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - } -}"; - private const string MultiDim_2D_PublicClassPublicMethod6 = @" -namespace Test -{ - public sealed class MultiDim_2D_PublicClassPublicMethod6 - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - } -}"; - // 3d class - private const string MultiDim_3D_PublicClassPublicMethod1 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod1 - { - public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod2 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod3 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod4 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod5 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - } -}"; - private const string MultiDim_3D_PublicClassPublicMethod6 = @" -namespace Test -{ - public sealed class MultiDim_3D_PublicClassPublicMethod6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } -}"; - // 2d iface - private const string MultiDim_2D_Interface1 = @" -namespace Test -{ - public interface MultiDim_2D_Interface1 - { - public int[,] D2_ReturnOnly(); - } -}"; - private const string MultiDim_2D_Interface2 = @" -namespace Test -{ - public interface MultiDim_2D_Interface2 - { - public int[,] D2_ReturnAndInput1(int[,] arr); - } -}"; - private const string MultiDim_2D_Interface3 = @" -namespace Test -{ - public interface MultiDim_2D_Interface3 - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); - } -}"; - private const string MultiDim_2D_Interface4 = @" -namespace Test -{ - public interface MultiDim_2D_Interface4 - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); - } -}"; - private const string MultiDim_2D_Interface5 = @" -namespace Test -{ - public interface MultiDim_2D_Interface5 - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); - } -}"; - private const string MultiDim_2D_Interface6 = @" -namespace Test -{ - public interface MultiDim_2D_Interface6 - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); - } -}"; - // 3d iface - private const string MultiDim_3D_Interface1 = @" -namespace Test -{ - public interface MultiDim_3D_Interface1 - { - public int[,,] D3_ReturnOnly(); - } -}"; - private const string MultiDim_3D_Interface2 = @" -namespace Test -{ - public interface MultiDim_3D_Interface2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr); - } -}"; - private const string MultiDim_3D_Interface3 = @" -namespace Test -{ - public interface MultiDim_3D_Interface3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); - } -}"; - private const string MultiDim_3D_Interface4 = @" -namespace Test -{ - public interface MultiDim_3D_Interface4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); - } -}"; - private const string MultiDim_3D_Interface5 = @" -namespace Test -{ - public interface MultiDim_3D_Interface5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); - } -}"; - private const string MultiDim_3D_Interface6 = @" -namespace Test -{ -public interface MultiDim_3D_Interface6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - -}"; - // subnamespace 2d iface - private const string SubNamespaceInterface_D2Method1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnOnly(); - } - } -}"; - private const string SubNamespaceInterface_D2Method2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnAndInput1(int[,] arr); - } - } -}"; - private const string SubNamespaceInterface_D2Method3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); - } - } -}"; - private const string SubNamespaceInterface_D2Method4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); - } - } -}"; - private const string SubNamespaceInterface_D2Method5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); - } - } -}"; - private const string SubNamespaceInterface_D2Method6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D2Methods - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); - } - } -}"; - // subnamespace 3d iface - private const string SubNamespaceInterface_D3Method1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method1 - { - public int[,,] D3_ReturnOnly(); - } - } -}"; - private const string SubNamespaceInterface_D3Method2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr); - } - } -}"; - private const string SubNamespaceInterface_D3Method3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); - } - } -}"; - private const string SubNamespaceInterface_D3Method4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - } -}"; - private const string SubNamespaceInterface_D3Method5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); - } - } -}"; - private const string SubNamespaceInterface_D3Method6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespaceInterface_D3Method6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); - } - } -}"; - // system array - private const string ArrayInstanceProperty1 = @" -namespace Test -{ - public sealed class ArrayInstanceProperty1 - { - public int[] Arr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - } -}"; - private const string ArrayInstanceProperty2 = @" -namespace Test -{ -public sealed class ArrayInstanceProperty2 - { - public System.Array Arr - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } - } - } -}"; - private const string ArrayInstanceProperty3 = @" -namespace Test -{ - public sealed class ArrayInstanceProperty3 - { - public int[] Arr - { - get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } - -}"; - private const string ArrayInstanceProperty4 = @" -namespace Test -{ -public sealed class ArrayInstanceProperty4 - { - public System.Array Arr - { - get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } - } -}"; - private const string ArrayInstanceInterface1 = @" -namespace Test -{ - public interface ArrayInstanceInterface1 - { - System.Array Id(System.Array arr); - } -}"; - private const string ArrayInstanceInterface2 = @" -namespace Test -{ - public interface ArrayInstanceInterface2 - { - void Method2(System.Array arr); - } -}"; - private const string ArrayInstanceInterface3 = @" -namespace Test -{ - public interface ArrayInstanceInterface3 - { - System.Array Method3(); - } -}"; - private const string SystemArrayProperty5 = @" -namespace Test -{ - public sealed class SystemArrayProperty - { - public System.Array Arr { get; set; } - } -}"; - private const string SystemArrayJustReturn = @" -namespace Test -{ - public sealed class JustReturn - { - public System.Array SystemArrayMethod() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } -}"; - private const string SystemArrayUnaryAndReturn = @" -namespace Test -{ - public sealed class UnaryAndReturn - { - public System.Array SystemArrayMethod(System.Array arr) { return arr; } - } -}"; - private const string SystemArraySecondArgClass = @" -namespace Test -{ - public sealed class SecondArgClass - { - public bool SystemArrayMethod(bool a, System.Array arr) { return a; } - } -}"; - private const string SystemArraySecondArg2Class = @" -namespace Test -{ - public sealed class SecondArg2Class - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b) { return a; } - } -}"; - private const string SystemArraySecondArgAndReturnTypeClass = @" -namespace Test -{ - public sealed class SecondArgAndReturnType - { - public System.Array SystemArrayMethod(bool a, System.Array arr) { return arr; } - } -}"; - private const string SystemArraySecondArgAndReturnTypeClass2 = @" -namespace Test -{ - public sealed class SecondArgAndReturnTypeClass2 - { - public System.Array SystemArrayMethod(bool a, System.Array arr, bool b) { return arr; } - } -}"; - private const string SystemArrayNilArgsButReturnTypeInterface = @" -namespace Test -{ - public interface NilArgsButReturnTypeInterface - { - public System.Array SystemArrayMethod(); - } -}"; - private const string SystemArrayUnaryAndReturnTypeInterface = @" -namespace Test -{ - public interface UnaryAndReturnTypeInterface - { - public System.Array SystemArrayMethod(System.Array arr); - } -}"; - private const string SystemArraySecondArgAndReturnTypeInterface = @" -namespace Test -{ - public interface SecondArgAndReturnTypeInterface - { - public System.Array SystemArrayMethod(bool a, System.Array arr); - } -}"; - private const string SystemArraySecondArgAndReturnTypeInterface2 = @" -namespace Test -{ - public interface SecondArgAndReturnTypeInterface2 - { - public System.Array SystemArrayMetho(bool a, System.Array arr, bool b); - } -}"; - private const string SystemArraySecondArgInterface = @" -namespace Test -{ - public interface SecondArgInterface - { - public bool SystemArrayMethod(bool a, System.Array arr); - } -}"; - private const string SystemArraySecondArgInterface2 = @" -namespace Test -{ - public interface SecondArgInterface2 - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b); - } -}"; - private const string SystemArraySubNamespace_ReturnOnly = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_ReturnOnly - { - public System.Array SystemArrayMethod(); - } - } -}"; - private const string SystemArraySubNamespace_ReturnAndInput1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_ReturnAndInput1 - { - public System.Array SystemArrayMethod(System.Array arr); - } - } -}"; - private const string SystemArraySubNamespace_ReturnAndInput2of2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_ReturnAndInput2of2 - { - public System.Array SystemArrayMethod(bool a, System.Array arr); - } - } -}"; - private const string SystemArraySubNamespace_ReturnAndInput2of3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_ReturnAndInput2of3 - { - public System.Array SystemArrayMethod(bool a, System.Array arr, bool b); - } - } -}"; - private const string SystemArraySubNamespace_NotReturnAndInput2of2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_NotReturnAndInput2of2 - { - public bool SystemArrayMethod(bool a, System.Array arr); - } - } -}"; - private const string SystemArraySubNamespace_NotReturnAndInput2of3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_NotReturnAndInput2of3 - { - public bool SystemArrayMethod(bool a, System.Array arr, bool b); - } - } -}"; - // constructor of same arity - private const string ConstructorsOfSameArity = @" -namespace TestNamespace -{ - public sealed class SameArityConstructors - { - private int num; - private string word; - - public SameArityConstructors(int i) - { - num = i; - word = ""dog""; - } - - public SameArityConstructors(string s) - { - num = 38; - word = s; - } - } -}"; - // async interfaces - private const string ClassImplementsIAsyncOperationWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class OpWithProgress : IAsyncOperationWithProgress - { - AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperationWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ClassImplementsIAsyncActionWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public class ActionWithProgress : IAsyncActionWithProgress - { - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ClassImplementsIAsyncOperation = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class Op : IAsyncOperation - { - AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperation.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string ClassImplementsIAsyncAction = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class AsyAction : IAsyncAction - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string InterfaceImplementsIAsyncOperationWithProgress = @" -using Windows.Foundation; using System; -namespace TestNamespace -{ - public interface OpWithProgress : IAsyncOperationWithProgress {} -}"; - private const string InterfaceImplementsIAsyncActionWithProgress = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public class ActionWithProgress : IAsyncActionWithProgress {} -}"; - private const string InterfaceImplementsIAsyncOperation = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public interface IAsyncOperation : IAsyncOperation {} -}"; - private const string InterfaceImplementsIAsyncAction = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public interface AsyAction : IAsyncAction {} -}"; - private const string InterfaceImplementsIAsyncOperationWithProgress2 = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public interface OpWithProgress : IAsyncOperationWithProgress - { - AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - void IAsyncInfo.Close(); - int IAsyncOperationWithProgress.GetResults(); - } -}"; - private const string InterfaceImplementsIAsyncActionWithProgress2 = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public class ActionWithProgress : IAsyncActionWithProgress - { - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - void IAsyncActionWithProgress.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string InterfaceImplementsIAsyncOperation2 = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class Op : IAsyncOperation - { - AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - void IAsyncInfo.Cancel() - { - throw new NotImplementedException(); - } - - void IAsyncInfo.Close() - { - throw new NotImplementedException(); - } - - int IAsyncOperation.GetResults() - { - throw new NotImplementedException(); - } - } -}"; - private const string InterfaceImplementsIAsyncAction2 = @" -using Windows.Foundation; -using System; -namespace TestNamespace -{ - public sealed class AsyAction : IAsyncAction - { - public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public Exception ErrorCode => throw new NotImplementedException(); - - public uint Id => throw new NotImplementedException(); - - public AsyncStatus Status => throw new NotImplementedException(); - - AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); - - uint IAsyncInfo.Id => throw new NotImplementedException(); - - AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); - - public void Cancel() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public void GetResults() - { - throw new NotImplementedException(); - } - } -}"; - - // readonlyarray / writeonlyarray attribute - private const string TestArrayParamAttrUnary_1 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void BothAttributes_Separate([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] - [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) - { - return; - } - } -}"; - private const string TestArrayParamAttrUnary_2 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void BothAttributes_Together([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } - } -}"; - private const string TestArrayParamAttrUnary_3 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string TestArrayParamAttrUnary_4 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void ArrayMarkedIn([In] int[] arr) { } - } -}"; - private const string TestArrayParamAttrUnary_5 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void ArrayMarkedOut([Out] int[] arr) { } - } -}"; - private const string TestArrayParamAttrUnary_6 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } - } -}"; - private const string TestArrayParamAttrUnary_7 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } - } -}"; - private const string TestArrayParamAttrUnary_8 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void ParamMarkedIn([In] int arr) { } - } -}"; - private const string TestArrayParamAttrUnary_9 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void ParamMarkedOut([Out] int arr) { } - } -}"; - private const string TestArrayParamAttrUnary_10 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void ArrayNotMarked(int[] arr) { } - } -}"; - private const string TestArrayParamAttrUnary_11 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void ParamMarkedIn([System.Runtime.InteropServices.In] int arr) { } - } -}"; - private const string TestArrayParamAttrUnary_12 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void ParamMarkedOut([System.Runtime.InteropServices.Out] int arr) { } - } -}"; - private const string TestArrayParamAttrUnary_13 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void ArrayMarkedIn([System.Runtime.InteropServices.In] int[] arr) { } - } -}"; - private const string TestArrayParamAttrUnary_14 = @" -namespace Test -{ - public sealed class OnlyParam - { - public void ArrayMarkedOut([System.Runtime.InteropServices.Out] int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_1 = @" -namespace Test -{ - public sealed class TwoParam - { - public void BothAttributes_Separate(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_2 = @" -namespace Test -{ - public sealed class TwoParam - { - public void BothAttributes_Together(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_3 = @" -namespace Test -{ - public sealed class TwoParam - { - public void MarkedOutAndReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string TestArrayParamAttrBinary_4 = @" -namespace Test -{ - public sealed class TwoParam - { - public void ArrayMarkedIn(int i, [In] int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_5 = @" -namespace Test -{ - public sealed class TwoParam - { - public void ArrayMarkedOut(int i, [Out] int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_6 = @" -namespace Test -{ - public sealed class TwoParam - { - public void NonArrayMarkedReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } - } -}"; - private const string TestArrayParamAttrBinary_7 = @" -namespace Test -{ - public sealed class TwoParam - { - public void NonArrayMarkedWriteOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } - } -}"; - private const string TestArrayParamAttrBinary_8 = @" -namespace Test -{ - public sealed class TwoParam - { - public void ParamMarkedIn(int i, [In] int arr) { } - } -}"; - private const string TestArrayParamAttrBinary_9 = @" -namespace Test -{ - public sealed class TwoParam - { - public void ParamMarkedOut(int i, [Out] int arr) { } - } -}"; - private const string TestArrayParamAttrBinary_10 = @" -namespace Test -{ - public sealed class TwoParam - { - public void ArrayNotMarked(int i, int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_11 = @" -namespace Test -{ - public sealed class TwoArray - { - public void OneValidOneInvalid_1( - [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, - [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] - [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] ys) - { - return; - } - } -}"; - private const string TestArrayParamAttrBinary_12 = @" -namespace Test -{ - public sealed class TwoArray - { - public void OneValidOneInvalid_2( - [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] - [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, - [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] ys) - { - return; - } - } -}"; - private const string TestArrayParamAttrBinary_13 = @" -namespace Test -{ - public sealed class TwoArray - { - public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) - { - arr = new int[] { }; - } - } -}"; - private const string TestArrayParamAttrBinary_14 = @" -namespace Test{ - public sealed class TwoParam - { - public void ArrayMarkedIn(int i, [In] int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_15 = @" -namespace Test -{ - public sealed class TwoArray - { - public void ArrayMarkedIn2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_16 = @" -namespace Test -{ - public sealed class TwoArray - { - public void ArrayMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_17 = @" -namespace Test -{ - public sealed class TwoArray - { - public void ArrayNotMarked(int i, int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_18 = @" -namespace Test -{ - public sealed class TwoArray - { - public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i) { } - } -}"; - private const string TestArrayParamAttrBinary_19 = @" -namespace Test -{ - public sealed class TwoArray - { - public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int i) { } - } -}"; - private const string TestArrayParamAttrBinary_20 = @" -namespace Test -{ - public sealed class TwoArray - { - public void NonArrayMarkedWriteOnly2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string TestArrayParamAttrBinary_21 = @" -namespace Test -{ - public sealed class TwoArray - { - public void ParamMarkedIn([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int arr) { } - } -}"; - private const string TestArrayParamAttrBinary_22 = @" -namespace Test -{ - public sealed class TwoArray - { - public void ParamMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int arr) { } - } -}"; - private const string TestArrayParamAttrBinary_23 = @" -namespace Test -{ - public sealed class TwoArray - { - public void ParamMarkedOut2([Out] int arr, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs) { } - } -}"; - private const string TestArrayParamAttrBinary_24 = @" -namespace Test -{ - public sealed class TwoArray - { - public void ArrayNotMarked([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, int[] arr) { } - } -}"; - // ref param - private const string RefParam_InterfaceMethod = @" -namespace Test -{ - public interface IHaveAMethodWithRefParam - { - void foo(ref int i); - } -}"; - private const string RefParam_ClassMethod = @" -namespace Test -{ - public sealed class ClassWithMethodUsingRefParam - { - public void MethodWithRefParam(ref int i) { i++; } - } -}"; - // operator overload - private const string OperatorOverload_Class = @" -namespace Test -{ - public sealed class ClassThatOverloadsOperator - { - public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) - { - return thing; - } - } -}"; - - // param name conflict - private const string DunderRetValParam = @" -namespace Test -{ - public sealed class ParameterNamedDunderRetVal - { - public int Identity(int __retval) - { - return __retval; - } - } -}"; - // struct fields - private const string StructWithConstructor = @" -namespace Test -{ - public struct StructWithConstructor_Invalid - { - int X; - StructWithConstructor_Invalid(int x) - { - X = x; - } - } -} "; - private const string StructWithClassField = @" -namespace Test -{ - public sealed class SillyClass - { - public double Identity(double d) - { - return d; - } - - public SillyClass() { } - } - - public struct StructWithClass_Invalid - { - public SillyClass classField; - } -}"; - private const string StructWithClassField2 = @" -namespace Test -{ - public sealed class SillyClass - { - public double Identity(double d) - { - return d; - } - - public SillyClass() { } - } -} - -namespace Prod -{ - public struct StructWithClass_Invalid - { - public Test.SillyClass classField; - } -}"; - private const string StructWithDelegateField = @" -namespace Test -{ - public struct StructWithDelegate_Invalid - { - public delegate int ADelegate(int x); - } -}"; - private const string StructWithPrimitiveTypesMissingPublicKeyword = @" -namespace Test -{ - public struct StructWithAllValidFields - { - bool boolean; - char character; - decimal dec; - double dbl; - float flt; - int i; - uint nat; - long lng; - ulong ulng; - short sh; - ushort us; - string str; - } -}"; - private const string EmptyStruct = @" -namespace Test -{ - public struct Mt {} -}"; - private const string StructWithIndexer = @" -namespace Test -{ - public struct StructWithIndexer_Invalid - { - int[] arr; - int this[int i] => arr[i]; - } -}"; - private const string StructWithMethods = @" -namespace Test -{ - public struct StructWithMethods_Invalid - { - int foo(int x) - { - return x; - } - } -}"; - private const string StructWithConst = @" -namespace Test -{ - public struct StructWithConst_Invalid - { - const int five = 5; - } -}"; - private const string StructWithProperty = @" -namespace Test -{ - public enum BasicEnum - { - First = 0, - Second = 1 - } - - public struct Posn_Invalid - { - BasicEnum enumField; - - public int x { get; } - public int y { get; } - } -}"; - private const string StructWithPrivateField = @" -namespace Test -{ - public struct StructWithPrivateField_Invalid - { - private int x; - } -}"; - private const string StructWithObjectField = @" -namespace Test -{ - public struct StructWithObjectField_Invalid - { - public object obj; - } -}"; - private const string StructWithDynamicField = @" -namespace Test -{ - public struct StructWithDynamicField_Invalid - { - public dynamic dyn; - } -}"; - private const string TwoOverloads_NoAttribute_NamesHaveNumber = @" -namespace Test -{ - public sealed class TwoOverloads_NoAttribute_WithNum - { - public string OverloadExample1(string s) { return s; } - - public int OverloadExample1(int n) { return n; } - } -}"; - // DefaultOverload attribute tests - private const string TwoOverloads_TwoAttribute_OneInList_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInList - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - DefaultOverload] - public string OverloadExample(string s) { return s; } - - [DefaultOverload] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInList_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInList - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_TwoLists_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_TwoLists - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [DefaultOverload] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - DefaultOverload] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInSeparateList_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInSeparateList - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [DefaultOverload] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_Unqualified = @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute - { - [DefaultOverload] - public string OverloadExample(string s) { return s; } - - [DefaultOverload] - public int OverloadExample(int n) { return n; } - } -}"; - private const string ThreeOverloads_TwoAttributes_Unqualified= @" -using Windows.Foundation.Metadata; -namespace Test -{ - public sealed class ThreeOverloads_TwoAttributes - { - public string OverloadExample(string s) { return s; } - - [DefaultOverload] - public int OverloadExample(int n) { return n; } - - [DefaultOverload] - public bool OverloadExample(bool b) { return b; } - } -}"; - private const string TwoOverloads_NoAttribute = @" -namespace Test -{ - public sealed class TwoOverloads_NoAttribute - { - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_OneInList = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInList - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_NoAttribute_OneIrrevAttr = @" -namespace Test -{ - public sealed class TwoOverloads_NoAttribute_OneIrrevAttr - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInList = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInList - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_TwoLists = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_TwoLists - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute_BothInSeparateList = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute_BothInSeparateList - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string TwoOverloads_TwoAttribute = @" -namespace Test -{ - public sealed class TwoOverloads_TwoAttribute - { - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string ThreeOverloads_TwoAttributes = @" -namespace Test -{ - public sealed class ThreeOverloads_TwoAttributes - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public bool OverloadExample(bool b) { return b; } - } -}"; - // jagged 2d/3d prop - private const string Jagged2D_Property2 = @" -namespace Test -{ - public sealed class Jagged2D_Property2 - { - public int[][] Arr { get; set; } - } -}"; - private const string Jagged3D_Property1 = @" -namespace Test -{ - public sealed class Jagged3D_Property1 - { - public int[][][] Arr3 { get; set; } - } -}"; - // jagged 2d class method - private const string Jagged2D_ClassMethod1 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod1 - { - public int[][] J2_ReturnOnly() - { - int[][] arr = new int[2][]; - arr[0] = new int[1] { 1 }; - arr[1] = new int[1] { 2 }; - return arr; - } - } -}"; - private const string Jagged2D_ClassMethod2 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod2 - { - public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } - } -}"; - private const string Jagged2D_ClassMethod3 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod3 - { - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } - } -}"; - private const string Jagged2D_ClassMethod4 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod4 - { - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } - } -}"; - private const string Jagged2D_ClassMethod5 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod5 - { - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } - } -}"; - private const string Jagged2D_ClassMethod6 = @" -namespace Test -{ - public sealed class Jagged2D_ClassMethod6 - { - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - } -}"; - // jagged 3d class method - private const string Jagged3D_ClassMethod1 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod1 - { - public int[][][] J3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - - } -}"; - private const string Jagged3D_ClassMethod2 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod1 - { - public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } - } -}"; - private const string Jagged3D_ClassMethod3 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod3 - { - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - } -}"; - private const string Jagged3D_ClassMethod4 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod4 - { - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - } -}"; - private const string Jagged3D_ClassMethod5 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod5 - { - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - } -}"; - private const string Jagged3D_ClassMethod6 = @" -namespace Test -{ - public sealed class Jagged3D_ClassMethod6 - { - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } -}"; - // jagged 2d interface method - private const string Jagged2D_InterfaceMethod1 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod1 - { - public int[][] J2_ReturnOnly(); - } -}"; - private const string Jagged2D_InterfaceMethod2 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod2 - { - public int[][] J2_ReturnAndInput1(int[,] arr); - } -}"; - private const string Jagged2D_InterfaceMethod3 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod3 - { - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); - } -}"; - private const string Jagged2D_InterfaceMethod4 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod4 - { - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); - } -}"; - private const string Jagged2D_InterfaceMethod5 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod5 - { - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); - } -}"; - private const string Jagged2D_InterfaceMethod6 = @" -namespace Test -{ - public interface Jagged2D_InterfaceMethod6 - { - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); - } -}"; - // jagged 2d interface method - private const string Jagged3D_InterfaceMethod1 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod1 - { - public int[][][] J3_ReturnOnly(); - } -}"; - private const string Jagged3D_InterfaceMethod2 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod2 - { - public int[][][] J3_ReturnAndInput1(int[][][] arr); - } -}"; - private const string Jagged3D_InterfaceMethod3 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod3 - { - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); - } -}"; - private const string Jagged3D_InterfaceMethod4 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod4 - { - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); - } -}"; - private const string Jagged3D_InterfaceMethod5 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod5 - { - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); - } -}"; - private const string Jagged3D_InterfaceMethod6 = @" -namespace Test -{ - public interface Jagged3D_InterfaceMethod6 - { - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); - } -}"; - // subnamespace jagged 2d iface - private const string SubNamespace_Jagged2DInterface1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface1 - { - public int[][] J2_ReturnOnly(); - } - } -}"; - private const string SubNamespace_Jagged2DInterface2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface2 - { - public int[][] J2_ReturnAndInput1(int[,] arr); - } - } -}"; - private const string SubNamespace_Jagged2DInterface3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface3 - { - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); - } - } -}"; - private const string SubNamespace_Jagged2DInterface4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface4 - { - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); - } - } -}"; - private const string SubNamespace_Jagged2DInterface5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface5 - { - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); - } - } -}"; - private const string SubNamespace_Jagged2DInterface6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged2DInterface6 - { - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); - } - } -}"; - // subnamespace jagged 3d iface - private const string SubNamespace_Jagged3DInterface1 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface1 - { - public int[][][] J3_ReturnOnly(); - } - } -}"; - private const string SubNamespace_Jagged3DInterface2 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface2 - { - public int[][][] J3_ReturnAndInput1(int[][][] arr); - } - } -}"; - private const string SubNamespace_Jagged3DInterface3 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface3 - { - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); - } - } -}"; - private const string SubNamespace_Jagged3DInterface4 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface4 - { - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); - } - } -}"; - private const string SubNamespace_Jagged3DInterface5 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface5 - { - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); - } - } -}"; - private const string SubNamespace_Jagged3DInterface6 = @" -namespace Test -{ - namespace SubNamespace - { - public interface SubNamespace_Jagged3DInterface6 - { - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); - } - } -}"; - } -} +namespace DiagnosticTests +{ + public sealed partial class UnitTesting + { + private const string SameNameNamespacesDisjoint = @" +namespace DiagnosticTests +{ + public sealed class Coords + { + public Coords() {} + } +} + +namespace A +{ + public sealed class Dummy + { + public Dummy() {} + } +} + +namespace A +{ + public sealed class Blank { public Blank() {} } +}"; + + + private const string NamespaceDifferByDot = @" +namespace DiagnosticTests.A +{ + private DiagnosticTests.B.Blank _blank; + public sealed class Dummy + { + public Dummy() {} + } +} + +namespace DiagnosticTests.B +{ + public sealed class Blank { public Blank() {} } +}"; + + private const string NamespaceDifferByDot2 = @" +namespace DiagnosticTests.A +{ + private DiagnosticTests.Blank _blank; + public sealed class Dummy + { + public Dummy() {} + } +} + +namespace DiagnosticTests +{ + public sealed class Blank { public Blank() {} } +}"; + private const string NamespacesDifferByCase = @" +namespace DiagnosticTests +{ + public sealed class Blank { public Blank() { } } + + namespace Sample + { + public sealed class AnotherBlank { public AnotherBlank() { } } + } + + namespace samplE + { + public sealed class AnotherBlank { public AnotherBlank() { } } + } +}"; + + private const string DisjointNamespaces = @" +// ""Test.winmd"" - types in namespace A won't be accessible +namespace DiagnosticTests +{ + public sealed class Blank { public Blank() { } } +} + +namespace A +{ + public sealed class Class4 { public Class4() { } } +}"; + + + + private const string DisjointNamespaces2 = @" +// ""Test.winmd"" uses the other namespace +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() { } + public void Foo(A.B.F arg) { return; } + } +} + +namespace A +{ + public sealed class Class4 { public Class4() { } } + namespace B + { + public sealed class F { public F() {} } + } +}"; + + private const string NoPublicTypes = @" +namespace DiagnosticTests +{ + internal sealed class RuntimeComponent + { + public RuntimeComponent() {} + } +}"; + // Generic Dictionary + private const string InterfaceWithGenericDictReturnType = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + Dictionary MakeDictionary(int length); + } +}"; + private const string InterfaceWithGenericDictInput = @" + +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + int ReturnInt(System.Collections.Generic.Dictionary ls); + } +}"; + private const string ClassWithGenericDictReturnType = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public System.Collections.Generic.Dictionary ReturnsDict(int length) { return new Dictionary(); }; + } +}"; + private const string ClassWithGenericDictInput = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public int ReturnsInt(Dictionary ls) { return 0; } + } +}"; + private const string IfaceWithGenDictProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + public Dictionary Dict { get; set; } + } +}"; + private const string ClassWithGenDictProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public Dictionary Dict { get; set; } + } +}"; + // Generic ReadOnlyDictionary + private const string InterfaceWithGenericRODictReturnType = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public interface MyInterface + { + System.Collections.ObjectModel.ReadOnlyDictionary MakeIntList(int length); + } +}"; + private const string InterfaceWithGenericRODictInput = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public interface MyInterface + { + int InputIsRODict(ReadOnlyDictionary rodict); + } +}"; + private const string ClassWithGenericRODictReturnType = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public ReadOnlyDictionary ReturnsRODict(int length) { return new ReadOnlyDictionary(); } + } +}"; + private const string ClassWithGenericRODictInput = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public int ReturnsInt(ReadOnlyDictionary ls) { return 0; } + } +}"; + private const string IfaceWithGenRODictProp = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public interface MyInterface + { + public ReadOnlyDictionary RODict { get; set; } + } +}"; + private const string ClassWithGenRODictProp = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public ReadOnlyDictionary RODict { get; set; } + } +}"; + // NonGeneric KeyValuePair + private const string InterfaceWithGenericKVPairReturnType = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + KeyValuePair KVPair(int length); + } +}"; + private const string InterfaceWithGenericKVPairInput = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + int ReturnsInt(System.Collections.Generic.KeyValuePair kvp); + } +}"; + private const string ClassWithGenericKVPairReturnType = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public KeyValuePair ReturnsKVPair(int length); + } +}"; + private const string ClassWithGenericKVPairInput = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public int ReturnsInt(KeyValuePair ls) { return 0; } + } +}"; + private const string IfaceWithGenKVPairProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + public KeyValuePair KVpair { get; set; } + } +}"; + private const string ClassWithGenKVPairProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public KeyValuePair KVpair { get; set; } + } +}"; + // Generic Enumerable + private const string InterfaceWithGenericEnumerableReturnType = @" +using System.Linq; +namespace DiagnosticTests +{ + public interface MyInterface + { + Enumerable MakeIntList(int length); + } +}"; + private const string InterfaceWithGenericEnumerableInput = @" +using System.Linq; +namespace DiagnosticTests +{ + public interface MyInterface + { + int ReturnsInt(Enumerable ls); + } +}"; + private const string ClassWithGenericEnumerableReturnType = @" +using System.Linq; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public Enumerable ReturnsEnumerable(int length) { return new Enumerable(); } + } +}"; + private const string ClassWithGenericEnumerableInput = @" +using System.Linq; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public int ReturnsInt(Enumerable ls) { return 0; } + } +}"; + private const string IfaceWithGenEnumerableProp = @" +using System.Linq; +namespace DiagnosticTests +{ + public interface MyInterface + { + public System.Linq.Enumerable Enumer { get; set; } + } +}"; + private const string ClassWithGenEnumerableProp = @" +using System.Linq; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public Enumerable Enumer { get; set; } + } +}"; + // Generic List + private const string InterfaceWithGenericListReturnType = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + List MakeIntList(int length); + } +}"; + private const string InterfaceWithGenericListInput = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + int SizeOfIntList(List ls); + } +}"; + private const string ClassWithGenericListReturnType = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public List ReturnsIntList(int length); + } +}"; + private const string ClassWithGenericListInput = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public int ReturnsIntList(List ls) { return 0; } + } +}"; + private const string IfaceWithGenListProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + public List IntList { get; set; } + } +}"; + private const string ClassWithGenListProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public System.Collections.Generic.List IntList { get; set; } + } +}"; + + private const string InterfaceWithOverloadNoAttribute = @" +namespace DiagnosticTests +{ + public interface MyInterface + { + int Foo(int n); + int Foo(string s); + } +}"; + private const string InterfaceWithOverloadAttributeTwice = @" +using Windows.Foundation.Metadata; +namespace DiagnosticTests +{ + public interface MyInterface + { + [DefaultOverload] + int Foo(int n); + [DefaultOverload] + int Foo(string s); + } +}"; + + private const string StructWithInterfaceField = @" +namespace DiagnosticTests +{ + public interface Foo + { + int Id(int i); + } + + public struct StructWithIface_Invalid + { + public Foo ifaceField; + } +}"; + + private const string UnsealedClass = @" +namespace DiagnosticTests +{ + public class UnsealedClass + { + public UnsealedClass() {} + } +}"; + private const string UnsealedClass2 = @" +namespace DiagnosticTests +{ + public class UnsealedClass + { + private UnsealedClass() {} + } +}"; + + private const string GenericClass = @" +namespace DiagnosticTests +{ + public sealed class GenericClass + { + public UnsealedClass() {} + } +}"; + private const string GenericInterface = @" +namespace DiagnosticTests +{ + public interface GenIface + { + int Foo(T input); + } +}"; + + private const string ClassInheritsException = @" +namespace DiagnosticTests +{ + public sealed class ClassWithExceptions : System.Exception + { + public ClassWithExceptions() {} + } +}"; + + // multidim array + private const string MultiDim_2DProp = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_2DProp + { + public int[,] Arr_2d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string MultiDim_3DProp = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_3DProp + { + public int[,,] Arr_3d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string MultiDim_3DProp_Whitespace = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_3DProp + { + public int[ , , ] Arr_3d { get; set; } + private int[,] PrivArr_2d { get; set; } + } +}"; + // 2d class + private const string MultiDim_2D_PublicClassPublicMethod1 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_2D_PublicClassPublicMethod1 + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod2 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_2D_PublicClassPublicMethod2 + { + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod3 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_2D_PublicClassPublicMethod3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod4 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_2D_PublicClassPublicMethod4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod5 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_2D_PublicClassPublicMethod5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + } +}"; + private const string MultiDim_2D_PublicClassPublicMethod6 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_2D_PublicClassPublicMethod6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + } +}"; + // 3d class + private const string MultiDim_3D_PublicClassPublicMethod1 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_3D_PublicClassPublicMethod1 + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod2 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_3D_PublicClassPublicMethod2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod3 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_3D_PublicClassPublicMethod3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod4 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_3D_PublicClassPublicMethod4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod5 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_3D_PublicClassPublicMethod5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string MultiDim_3D_PublicClassPublicMethod6 = @" +namespace DiagnosticTests +{ + public sealed class MultiDim_3D_PublicClassPublicMethod6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + // 2d iface + private const string MultiDim_2D_Interface1 = @" +namespace DiagnosticTests +{ + public interface MultiDim_2D_Interface1 + { + public int[,] D2_ReturnOnly(); + } +}"; + private const string MultiDim_2D_Interface2 = @" +namespace DiagnosticTests +{ + public interface MultiDim_2D_Interface2 + { + public int[,] D2_ReturnAndInput1(int[,] arr); + } +}"; + private const string MultiDim_2D_Interface3 = @" +namespace DiagnosticTests +{ + public interface MultiDim_2D_Interface3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + } +}"; + private const string MultiDim_2D_Interface4 = @" +namespace DiagnosticTests +{ + public interface MultiDim_2D_Interface4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + } +}"; + private const string MultiDim_2D_Interface5 = @" +namespace DiagnosticTests +{ + public interface MultiDim_2D_Interface5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + } +}"; + private const string MultiDim_2D_Interface6 = @" +namespace DiagnosticTests +{ + public interface MultiDim_2D_Interface6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + } +}"; + // 3d iface + private const string MultiDim_3D_Interface1 = @" +namespace DiagnosticTests +{ + public interface MultiDim_3D_Interface1 + { + public int[,,] D3_ReturnOnly(); + } +}"; + private const string MultiDim_3D_Interface2 = @" +namespace DiagnosticTests +{ + public interface MultiDim_3D_Interface2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface3 = @" +namespace DiagnosticTests +{ + public interface MultiDim_3D_Interface3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface4 = @" +namespace DiagnosticTests +{ + public interface MultiDim_3D_Interface4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + } +}"; + private const string MultiDim_3D_Interface5 = @" +namespace DiagnosticTests +{ + public interface MultiDim_3D_Interface5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + } +}"; + private const string MultiDim_3D_Interface6 = @" +namespace DiagnosticTests +{ + public interface MultiDim_3D_Interface6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } +}"; + // subnamespace 2d iface + private const string SubNamespaceInterface_D2Method1 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnOnly(); + } + } +}"; + private const string SubNamespaceInterface_D2Method2 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput1(int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method3 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method4 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b); + } + } +}"; + private const string SubNamespaceInterface_D2Method5 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr); + } + } +}"; + private const string SubNamespaceInterface_D2Method6 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D2Methods + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b); + } + } +}"; + // subnamespace 3d iface + private const string SubNamespaceInterface_D3Method1 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method1 + { + public int[,,] D3_ReturnOnly(); + } + } +}"; + private const string SubNamespaceInterface_D3Method2 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method3 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method4 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + } +}"; + private const string SubNamespaceInterface_D3Method5 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr); + } + } +}"; + private const string SubNamespaceInterface_D3Method6 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespaceInterface_D3Method6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b); + } + } +}"; + // system array + private const string ArrayInstanceProperty1 = @" +namespace DiagnosticTests +{ + public sealed class ArrayInstanceProperty2 + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } + } + } +}"; + private const string ArrayInstanceProperty2 = @" +namespace DiagnosticTests +{ +public sealed class ArrayInstanceProperty4 + { + public System.Array Arr + { + get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } + } +}"; + private const string ArrayInstanceInterface1 = @" +namespace DiagnosticTests +{ + public interface ArrayInstanceInterface1 + { + System.Array Id(System.Array arr); + } +}"; + private const string ArrayInstanceInterface2 = @" +namespace DiagnosticTests +{ + public interface ArrayInstanceInterface2 + { + void Method2(System.Array arr); + } +}"; + private const string ArrayInstanceInterface3 = @" +namespace DiagnosticTests +{ + public interface ArrayInstanceInterface3 + { + System.Array Method3(); + } +}"; + private const string SystemArrayProperty5 = @" +namespace DiagnosticTests +{ + public sealed class SystemArrayProperty + { + public System.Array Arr { get; set; } + } +}"; + private const string SystemArrayJustReturn = @" +namespace DiagnosticTests +{ + public sealed class JustReturn + { + public System.Array SystemArrayMethod() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string SystemArrayUnaryAndReturn = @" +namespace DiagnosticTests +{ + public sealed class UnaryAndReturn + { + public System.Array SystemArrayMethod(System.Array arr) { return arr; } + } +}"; + private const string SystemArraySecondArgClass = @" +namespace DiagnosticTests +{ + public sealed class SecondArgClass + { + public bool SystemArrayMethod(bool a, System.Array arr) { return a; } + } +}"; + private const string SystemArraySecondArg2Class = @" +namespace DiagnosticTests +{ + public sealed class SecondArg2Class + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string SystemArraySecondArgAndReturnTypeClass = @" +namespace DiagnosticTests +{ + public sealed class SecondArgAndReturnType + { + public System.Array SystemArrayMethod(bool a, System.Array arr) { return arr; } + } +}"; + private const string SystemArraySecondArgAndReturnTypeClass2 = @" +namespace DiagnosticTests +{ + public sealed class SecondArgAndReturnTypeClass2 + { + public System.Array SystemArrayMethod(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string SystemArrayNilArgsButReturnTypeInterface = @" +namespace DiagnosticTests +{ + public interface NilArgsButReturnTypeInterface + { + public System.Array SystemArrayMethod(); + } +}"; + private const string SystemArrayUnaryAndReturnTypeInterface = @" +namespace DiagnosticTests +{ + public interface UnaryAndReturnTypeInterface + { + public System.Array SystemArrayMethod(System.Array arr); + } +}"; + private const string SystemArraySecondArgAndReturnTypeInterface = @" +namespace DiagnosticTests +{ + public interface SecondArgAndReturnTypeInterface + { + public System.Array SystemArrayMethod(bool a, System.Array arr); + } +}"; + private const string SystemArraySecondArgAndReturnTypeInterface2 = @" +namespace DiagnosticTests +{ + public interface SecondArgAndReturnTypeInterface2 + { + public System.Array SystemArrayMetho(bool a, System.Array arr, bool b); + } +}"; + private const string SystemArraySecondArgInterface = @" +namespace DiagnosticTests +{ + public interface SecondArgInterface + { + public bool SystemArrayMethod(bool a, System.Array arr); + } +}"; + private const string SystemArraySecondArgInterface2 = @" +namespace DiagnosticTests +{ + public interface SecondArgInterface2 + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b); + } +}"; + private const string SystemArraySubNamespace_ReturnOnly = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_ReturnOnly + { + public System.Array SystemArrayMethod(); + } + } +}"; + private const string SystemArraySubNamespace_ReturnAndInput1 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_ReturnAndInput1 + { + public System.Array SystemArrayMethod(System.Array arr); + } + } +}"; + private const string SystemArraySubNamespace_ReturnAndInput2of2 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_ReturnAndInput2of2 + { + public System.Array SystemArrayMethod(bool a, System.Array arr); + } + } +}"; + private const string SystemArraySubNamespace_ReturnAndInput2of3 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_ReturnAndInput2of3 + { + public System.Array SystemArrayMethod(bool a, System.Array arr, bool b); + } + } +}"; + private const string SystemArraySubNamespace_NotReturnAndInput2of2 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_NotReturnAndInput2of2 + { + public bool SystemArrayMethod(bool a, System.Array arr); + } + } +}"; + private const string SystemArraySubNamespace_NotReturnAndInput2of3 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_NotReturnAndInput2of3 + { + public bool SystemArrayMethod(bool a, System.Array arr, bool b); + } + } +}"; + // constructor of same arity + private const string ConstructorsOfSameArity = @" +namespace DiagnosticTests +{ + public sealed class SameArityConstructors + { + private int num; + private string word; + + public SameArityConstructors(int i) + { + num = i; + word = ""dog""; + } + + public SameArityConstructors(string s) + { + num = 38; + word = s; + } + } +}"; + // async interfaces + private const string ClassImplementsAsyncAndException = @" +using Windows.Foundation; +namespace DiagnosticTests +{ + public sealed class OpWithProgress : System.Exception, IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperationWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + + + private const string ClassImplementsIAsyncOperationWithProgress = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public sealed class OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperationWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncActionWithProgress = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncActionWithProgress_Qualified = @" +using System; +namespace DiagnosticTests +{ + public class ActionWithProgress : Windows.Foundation.IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncOperation = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string ClassImplementsIAsyncAction = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public sealed class AsyAction : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string InterfaceImplementsIAsyncOperationWithProgress = @" +using Windows.Foundation; using System; +namespace DiagnosticTests +{ + public interface OpWithProgress : IAsyncOperationWithProgress {} +}"; + private const string InterfaceImplementsIAsyncActionWithProgress = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public class ActionWithProgress : IAsyncActionWithProgress {} +}"; + private const string InterfaceImplementsIAsyncOperation = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public interface IAsyncOperation : IAsyncOperation {} +}"; + private const string InterfaceImplementsIAsyncAction = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public interface AsyAction : IAsyncAction {} +}"; + private const string InterfaceImplementsIAsyncOperationWithProgress2 = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public interface OpWithProgress : IAsyncOperationWithProgress + { + AsyncOperationProgressHandler IAsyncOperationWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncOperationWithProgressCompletedHandler IAsyncOperationWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + void IAsyncInfo.Close(); + int IAsyncOperationWithProgress.GetResults(); + } +}"; + private const string InterfaceImplementsIAsyncActionWithProgress2 = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public class ActionWithProgress : IAsyncActionWithProgress + { + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + void IAsyncActionWithProgress.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string InterfaceImplementsIAsyncOperation2 = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public sealed class Op : IAsyncOperation + { + AsyncOperationCompletedHandler IAsyncOperation.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + void IAsyncInfo.Cancel() + { + throw new NotImplementedException(); + } + + void IAsyncInfo.Close() + { + throw new NotImplementedException(); + } + + int IAsyncOperation.GetResults() + { + throw new NotImplementedException(); + } + } +}"; + private const string InterfaceImplementsIAsyncAction2 = @" +using Windows.Foundation; +using System; +namespace DiagnosticTests +{ + public sealed class AsyAction : IAsyncAction + { + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + + AsyncActionProgressHandler IAsyncActionWithProgress.Progress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + AsyncActionWithProgressCompletedHandler IAsyncActionWithProgress.Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Exception IAsyncInfo.ErrorCode => throw new NotImplementedException(); + + uint IAsyncInfo.Id => throw new NotImplementedException(); + + AsyncStatus IAsyncInfo.Status => throw new NotImplementedException(); + + public void Cancel() + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void GetResults() + { + throw new NotImplementedException(); + } + } +}"; + + // readonlyarray / writeonlyarray attribute + private const string ArrayParamAttrUnary_1 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void BothAttributes_Separate([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] + [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) + { + return; + } + } +}"; + private const string ArrayParamAttrUnary_2 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void BothAttributes_Together([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string ArrayParamAttrUnary_3 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string ArrayParamAttrUnary_4 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void ArrayMarkedIn([In] int[] arr) { } + } +}"; + private const string ArrayParamAttrUnary_5 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void ArrayMarkedOut([Out] int[] arr) { } + } +}"; + private const string ArrayParamAttrUnary_6 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } + } +}"; + private const string ArrayParamAttrUnary_7 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } + } +}"; + private const string ArrayParamAttrUnary_8 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void ParamMarkedIn([In] int arr) { } + } +}"; + private const string ArrayParamAttrUnary_9 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void ParamMarkedOut([Out] int arr) { } + } +}"; + private const string ArrayParamAttrUnary_10 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void ArrayNotMarked(int[] arr) { } + } +}"; + private const string ArrayParamAttrUnary_11 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void ParamMarkedIn([System.Runtime.InteropServices.In] int arr) { } + } +}"; + private const string ArrayParamAttrUnary_12 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void ParamMarkedOut([System.Runtime.InteropServices.Out] int arr) { } + } +}"; + private const string ArrayParamAttrUnary_13 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void ArrayMarkedIn([System.Runtime.InteropServices.In] int[] arr) { } + } +}"; + private const string ArrayParamAttrUnary_14 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void ArrayMarkedOut([System.Runtime.InteropServices.Out] int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_1 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void BothAttributes_Separate(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray][System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_2 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void BothAttributes_Together(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray, System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_3 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void MarkedOutAndReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string ArrayParamAttrBinary_4 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void ArrayMarkedIn(int i, [In] int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_5 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void ArrayMarkedOut(int i, [Out] int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_6 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void NonArrayMarkedReadOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int arr) { } + } +}"; + private const string ArrayParamAttrBinary_7 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void NonArrayMarkedWriteOnly(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int arr) { } + } +}"; + private const string ArrayParamAttrBinary_8 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void ParamMarkedIn(int i, [In] int arr) { } + } +}"; + private const string ArrayParamAttrBinary_9 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void ParamMarkedOut(int i, [Out] int arr) { } + } +}"; + private const string ArrayParamAttrBinary_10 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void ArrayNotMarked(int i, int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_11 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void OneValidOneInvalid_1( + [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, + [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] + [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] ys) + { + return; + } + } +}"; + private const string ArrayParamAttrBinary_12 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void OneValidOneInvalid_2( + [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] + [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, + [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] ys) + { + return; + } + } +}"; + private const string ArrayParamAttrBinary_13 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void MarkedOutAndReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] out int[] arr) + { + arr = new int[] { }; + } + } +}"; + private const string ArrayParamAttrBinary_14 = @" +namespace DiagnosticTests{ + public sealed class TwoParam + { + public void ArrayMarkedIn(int i, [In] int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_15 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void ArrayMarkedIn2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_16 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void ArrayMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_17 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void ArrayNotMarked(int i, int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_18 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void NonArrayMarkedReadOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i) { } + } +}"; + private const string ArrayParamAttrBinary_19 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void NonArrayMarkedWriteOnly([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int i) { } + } +}"; + private const string ArrayParamAttrBinary_20 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void NonArrayMarkedWriteOnly2([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string ArrayParamAttrBinary_21 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void ParamMarkedIn([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [In] int arr) { } + } +}"; + private const string ArrayParamAttrBinary_22 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void ParamMarkedOut([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [Out] int arr) { } + } +}"; + private const string ArrayParamAttrBinary_23 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void ParamMarkedOut2([Out] int arr, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs) { } + } +}"; + private const string ArrayParamAttrBinary_24 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void ArrayNotMarked([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, int[] arr) { } + } +}"; + // ref param + private const string RefParam_InterfaceMethod = @" +namespace DiagnosticTests +{ + public interface IHaveAMethodWithRefParam + { + void foo(ref int i); + } +}"; + private const string RefParam_ClassMethod = @" +namespace DiagnosticTests +{ + public sealed class ClassWithMethodUsingRefParam + { + public void MethodWithRefParam(ref int i) { i++; } + } +}"; + // operator overload + private const string OperatorOverload_Class = @" +namespace DiagnosticTests +{ + public sealed class ClassThatOverloadsOperator + { + public static ClassThatOverloadsOperator operator +(ClassThatOverloadsOperator thing) + { + return thing; + } + } +}"; + + // param name conflict + private const string DunderRetValParam = @" +namespace DiagnosticTests +{ + public sealed class ParameterNamedDunderRetVal + { + public int Identity(int __retval) + { + return __retval; + } + } +}"; + // struct fields + private const string StructWithConstructor = @" +namespace DiagnosticTests +{ + public struct StructWithConstructor_Invalid + { + int X; + StructWithConstructor_Invalid(int x) + { + X = x; + } + } +} "; + private const string StructWithClassField = @" +namespace DiagnosticTests +{ + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + + public SillyClass() { } + } + + public struct StructWithClass_Invalid + { + public SillyClass classField; + } +}"; + private const string StructWithClassField2 = @" +namespace DiagnosticTests +{ + public sealed class SillyClass + { + public double Identity(double d) + { + return d; + } + + public SillyClass() { } + } +} + +namespace Prod +{ + public struct StructWithClass_Invalid + { + public DiagnosticTests.SillyClass classField; + } +}"; + private const string StructWithDelegateField = @" +namespace DiagnosticTests +{ + public struct StructWithDelegate_Invalid + { + public delegate int ADelegate(int x); + } +}"; + private const string StructWithPrimitiveTypesMissingPublicKeyword = @" +namespace DiagnosticTests +{ + public struct StructWithAllValidFields + { + bool boolean; + char character; + decimal dec; + double dbl; + float flt; + int i; + uint nat; + long lng; + ulong ulng; + short sh; + ushort us; + string str; + } +}"; + private const string EmptyStruct = @" +namespace DiagnosticTests +{ + public struct Mt {} +}"; + private const string StructWithIndexer = @" +namespace DiagnosticTests +{ + public struct StructWithIndexer_Invalid + { + int[] arr; + int this[int i] => arr[i]; + } +}"; + private const string StructWithMethods = @" +namespace DiagnosticTests +{ + public struct StructWithMethods_Invalid + { + int foo(int x) + { + return x; + } + } +}"; + private const string StructWithConst = @" +namespace DiagnosticTests +{ + public struct StructWithConst_Invalid + { + const int five = 5; + } +}"; + private const string StructWithProperty = @" +namespace DiagnosticTests +{ + public enum BasicEnum + { + First = 0, + Second = 1 + } + + public struct Posn_Invalid + { + BasicEnum enumField; + + public int x { get; } + public int y { get; } + } +}"; + private const string StructWithPrivateField = @" +namespace DiagnosticTests +{ + public struct StructWithPrivateField_Invalid + { + private int x; + } +}"; + private const string StructWithObjectField = @" +namespace DiagnosticTests +{ + public struct StructWithObjectField_Invalid + { + public object obj; + } +}"; + private const string StructWithDynamicField = @" +namespace DiagnosticTests +{ + public struct StructWithDynamicField_Invalid + { + public dynamic dyn; + } +}"; + private const string TwoOverloads_NoAttribute_NamesHaveNumber = @" +namespace DiagnosticTests +{ + public sealed class TwoOverloads_NoAttribute_WithNum + { + public string OverloadExample1(string s) { return s; } + + public int OverloadExample1(int n) { return n; } + } +}"; + // DefaultOverload attribute tests + private const string TwoOverloads_TwoAttribute_OneInList_Unqualified = @" +using Windows.Foundation.Metadata; +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_OneInList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload] + public string OverloadExample(string s) { return s; } + + [DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInList_Unqualified = @" +using Windows.Foundation.Metadata; +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_BothInList + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_TwoLists_Unqualified = @" +using Windows.Foundation.Metadata; +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_TwoLists + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Unqualified = @" +using Windows.Foundation.Metadata; +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInSeparateList_Unqualified = @" +using Windows.Foundation.Metadata; +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_BothInSeparateList + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_Unqualified = @" +using Windows.Foundation.Metadata; +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute + { + [DefaultOverload] + public string OverloadExample(string s) { return s; } + + [DefaultOverload] + public int OverloadExample(int n) { return n; } + } +}"; + private const string ThreeOverloads_TwoAttributes_Unqualified= @" +using Windows.Foundation.Metadata; +namespace DiagnosticTests +{ + public sealed class ThreeOverloads_TwoAttributes + { + public string OverloadExample(string s) { return s; } + + [DefaultOverload] + public int OverloadExample(int n) { return n; } + + [DefaultOverload] + public bool OverloadExample(bool b) { return b; } + } +}"; + private const string TwoOverloads_NoAttribute = @" +namespace DiagnosticTests +{ + public sealed class TwoOverloads_NoAttribute + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInList = @" +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_OneInList + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_NoAttribute_OneIrrevAttr = @" +namespace DiagnosticTests +{ + public sealed class TwoOverloads_NoAttribute_OneIrrevAttr + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInList = @" +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_BothInList + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_TwoLists = @" +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_TwoLists + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_OneInSeparateList_OneNot = @" +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_OneInSeparateList_OneNot + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute_BothInSeparateList = @" +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute_BothInSeparateList + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string TwoOverloads_TwoAttribute = @" +namespace DiagnosticTests +{ + public sealed class TwoOverloads_TwoAttribute + { + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string ThreeOverloads_TwoAttributes = @" +namespace DiagnosticTests +{ + public sealed class ThreeOverloads_TwoAttributes + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } +}"; + // jagged 2d/3d prop + private const string Jagged2D_Property2 = @" +namespace DiagnosticTests +{ + public sealed class Jagged2D_Property2 + { + public int[][] Arr { get; set; } + } +}"; + private const string Jagged3D_Property1 = @" +namespace DiagnosticTests +{ + public sealed class Jagged3D_Property1 + { + public int[][][] Arr3 { get; set; } + } +}"; + // jagged 2d class method + private const string Jagged2D_ClassMethod1 = @" +namespace DiagnosticTests +{ + public sealed class Jagged2D_ClassMethod1 + { + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + } +}"; + private const string Jagged2D_ClassMethod2 = @" +namespace DiagnosticTests +{ + public sealed class Jagged2D_ClassMethod2 + { + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + } +}"; + private const string Jagged2D_ClassMethod3 = @" +namespace DiagnosticTests +{ + public sealed class Jagged2D_ClassMethod3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + } +}"; + private const string Jagged2D_ClassMethod4 = @" +namespace DiagnosticTests +{ + public sealed class Jagged2D_ClassMethod4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + } +}"; + private const string Jagged2D_ClassMethod5 = @" +namespace DiagnosticTests +{ + public sealed class Jagged2D_ClassMethod5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + } +}"; + private const string Jagged2D_ClassMethod6 = @" +namespace DiagnosticTests +{ + public sealed class Jagged2D_ClassMethod6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } + } +}"; + // jagged 3d class method + private const string Jagged3D_ClassMethod1 = @" +namespace DiagnosticTests +{ + public sealed class Jagged3D_ClassMethod1 + { + public int[][][] J3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + + } +}"; + private const string Jagged3D_ClassMethod2 = @" +namespace DiagnosticTests +{ + public sealed class Jagged3D_ClassMethod1 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod3 = @" +namespace DiagnosticTests +{ + public sealed class Jagged3D_ClassMethod3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod4 = @" +namespace DiagnosticTests +{ + public sealed class Jagged3D_ClassMethod4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + } +}"; + private const string Jagged3D_ClassMethod5 = @" +namespace DiagnosticTests +{ + public sealed class Jagged3D_ClassMethod5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + } +}"; + private const string Jagged3D_ClassMethod6 = @" +namespace DiagnosticTests +{ + public sealed class Jagged3D_ClassMethod6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + // jagged 2d interface method + private const string Jagged2D_InterfaceMethod1 = @" +namespace DiagnosticTests +{ + public interface Jagged2D_InterfaceMethod1 + { + public int[][] J2_ReturnOnly(); + } +}"; + private const string Jagged2D_InterfaceMethod2 = @" +namespace DiagnosticTests +{ + public interface Jagged2D_InterfaceMethod2 + { + public int[][] J2_ReturnAndInput1(int[,] arr); + } +}"; + private const string Jagged2D_InterfaceMethod3 = @" +namespace DiagnosticTests +{ + public interface Jagged2D_InterfaceMethod3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + } +}"; + private const string Jagged2D_InterfaceMethod4 = @" +namespace DiagnosticTests +{ + public interface Jagged2D_InterfaceMethod4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + } +}"; + private const string Jagged2D_InterfaceMethod5 = @" +namespace DiagnosticTests +{ + public interface Jagged2D_InterfaceMethod5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + } +}"; + private const string Jagged2D_InterfaceMethod6 = @" +namespace DiagnosticTests +{ + public interface Jagged2D_InterfaceMethod6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); + } +}"; + // jagged 2d interface method + private const string Jagged3D_InterfaceMethod1 = @" +namespace DiagnosticTests +{ + public interface Jagged3D_InterfaceMethod1 + { + public int[][][] J3_ReturnOnly(); + } +}"; + private const string Jagged3D_InterfaceMethod2 = @" +namespace DiagnosticTests +{ + public interface Jagged3D_InterfaceMethod2 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod3 = @" +namespace DiagnosticTests +{ + public interface Jagged3D_InterfaceMethod3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod4 = @" +namespace DiagnosticTests +{ + public interface Jagged3D_InterfaceMethod4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + } +}"; + private const string Jagged3D_InterfaceMethod5 = @" +namespace DiagnosticTests +{ + public interface Jagged3D_InterfaceMethod5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + } +}"; + private const string Jagged3D_InterfaceMethod6 = @" +namespace DiagnosticTests +{ + public interface Jagged3D_InterfaceMethod6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } +}"; + // subnamespace jagged 2d iface + private const string SubNamespace_Jagged2DInterface1 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface1 + { + public int[][] J2_ReturnOnly(); + } + } +}"; + private const string SubNamespace_Jagged2DInterface2 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface2 + { + public int[][] J2_ReturnAndInput1(int[,] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface3 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface3 + { + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface4 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface4 + { + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr); + } + } +}"; + private const string SubNamespace_Jagged2DInterface5 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface5 + { + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b); + } + } +}"; + private const string SubNamespace_Jagged2DInterface6 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged2DInterface6 + { + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b); + } + } +}"; + // subnamespace jagged 3d iface + private const string SubNamespace_Jagged3DInterface1 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface1 + { + public int[][][] J3_ReturnOnly(); + } + } +}"; + private const string SubNamespace_Jagged3DInterface2 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface2 + { + public int[][][] J3_ReturnAndInput1(int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface3 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface3 + { + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface4 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface4 + { + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + } +}"; + private const string SubNamespace_Jagged3DInterface5 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface5 + { + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr); + } + } +}"; + private const string SubNamespace_Jagged3DInterface6 = @" +namespace DiagnosticTests +{ + namespace SubNamespace + { + public interface SubNamespace_Jagged3DInterface6 + { + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b); + } + } +}"; + } +} diff --git a/src/Authoring/DiagnosticTests/PositiveData.cs b/src/Authoring/DiagnosticTests/PositiveData.cs index 1082a91e9..b8ed9e125 100644 --- a/src/Authoring/DiagnosticTests/PositiveData.cs +++ b/src/Authoring/DiagnosticTests/PositiveData.cs @@ -1,824 +1,1570 @@ namespace DiagnosticTests { - public partial class TestDiagnostics - { - // WIP - private const string Valid_NamespaceUse1 = @" -namespace My.WindowsComponent -{ - public sealed Class1 { public int X { get; set; } } - - namespace InnerComponent - { - public sealed class Class2 { public int Y { get; } } - } -}"; - - //// DefaultOverload attribute - private const string Valid_TwoOverloads_DiffParamCount = @" -namespace Test -{ - public sealed class Valid_TwoOverloads_DiffParamCount - { - public string OverloadExample(string s) { return s; } - public int OverloadExample(int n, int m) { return n; } - } -}"; - private const string Valid_TwoOverloads_OneAttribute_OneInList = @" -namespace Test -{ - public sealed class Valid_TwoOverloads_OneAttribute_OneInList - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), - Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } - -}"; - private const string Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute = @" -namespace Test -{ - public sealed class Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute - { - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - private const string Valid_TwoOverloads_OneAttribute_TwoLists = @" -namespace Test -{ - public sealed class Valid_TwoOverloads_OneAttribute_TwoLists - { - - [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] - [Windows.Foundation.Metadata.DefaultOverload()] - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - } -}"; - private const string Valid_ThreeOverloads_OneAttribute = @" -namespace Test -{ - public sealed class Valid_ThreeOverloads_OneAttribute - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - - public bool OverloadExample(bool b) { return b; } - } -}"; - private const string Valid_ThreeOverloads_OneAttribute_2 = @" -namespace Test -{ - public sealed class Valid_ThreeOverloads_OneAttribute_2 - { - public string OverloadExample(string s) { return s; } - - public int OverloadExample(int n) { return n; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public bool OverloadExample(bool b) { return b; } - } -}"; - private const string Valid_TwoOverloads_OneAttribute_3 = @" -namespace Test -{ - public sealed class Valid_TwoOverloads_OneAttribute_3 - { - public string OverloadExample(string s) { return s; } - - [Windows.Foundation.Metadata.DefaultOverload()] - public int OverloadExample(int n) { return n; } - } -}"; - //// Jagged array - private const string Valid_JaggedMix_PrivateClassPublicProperty = @" -namespace Test -{ - internal sealed class Valid_JaggedArray_PrivateClassPublicProperty - { - private int[][] Arr { get; set; } - public int[][] ArrP { get; set; } - public int[][][] Arr3 { get; set; } - private int[][][] Arr3P { get; set; } - } -}"; - private const string Valid_Jagged2D_PrivateClassPublicMethods = @" -namespace Test -{ - internal sealed class Valid_JaggedArray_PrivateClassPublicMethods - { - public int[][] J2_ReturnOnly() - { - int[][] arr = new int[2][]; - arr[0] = new int[1] { 1 }; - arr[1] = new int[1] { 2 }; - return arr; - } - public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } - public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } - public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } - public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } - public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } - } -}"; - private const string Valid_Jagged3D_PrivateClassPublicMethods = @" -namespace Test -{ - internal sealed class Valid_Jagged3D_PrivateClassPublicMethods - { - public int[][][] J3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } - public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } -}"; - private const string Valid_Jagged3D_PublicClassPrivateMethods = @" -namespace Test -{ - public sealed class Valid_Jagged3D_PublicClassPrivateMethods - { - private int[][][] D3_ReturnOnly() - { - int[][] arr2 = new int[2][]; - arr2[0] = new int[1] { 1 }; - arr2[1] = new int[1] { 2 }; - - int[][][] arr = new int[1][][]; - arr[0] = arr2; - return arr; - } - private int[][][] D3_ReturnAndInput1(int[][][] arr) { return arr; } - private int[][][] D3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } - private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } - private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } - private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } - } -}"; - private const string Valid_Jagged2D_Property = @" -namespace Test -{ - public sealed class Jagged2D_Property1 - { - private int[][] ArrP { get; set; } - } -}"; - private const string Valid_Jagged3D_Property = @" -namespace Test -{ - public sealed class Jagged3D_Property2 - { - private int[][][] Arr3P { get; set; } - } -}"; - // prop - private const string Valid_MultiDimArray_PrivateClassPublicProperty1 = @" -namespace Test -{ - internal class Valid_MultiDimArray_PrivateClassPublicProperty1 - { - public int[,] Arr_2d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PrivateClassPublicProperty2 = @" -namespace Test -{ - internal class Valid_MultiDimArray_PrivateClassPublicProperty2 - { - public int[,,] Arr_3d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PrivateClassPublicProperty3 = @" -namespace Test -{ - internal class Valid_MultiDimArray_PrivateClassPublicProperty3 - { - private int[,] PrivArr_2d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PrivateClassPublicProperty4 = @" -namespace Test -{ - internal class Valid_MultiDimArray_PrivateClassPublicProperty4 - { - private int[,,] PrivArr_3d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateProperty1 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 - { - private int[,] PrivArr_2d { get; set; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateProperty2 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 - { - private int[,,] PrivArr_3d { get; set; } - } -}"; - // 2d - private const string Valid_2D_PrivateClass_PublicMethod1 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod1 - { - public int[,] D2_ReturnOnly() { return new int[4, 2]; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod2 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod2 - { - public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod3 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod3 - { - public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod4 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod4 - { - public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod5 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod5 - { - public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } - } -}"; - private const string Valid_2D_PrivateClass_PublicMethod6 = @" -namespace Test -{ - internal sealed class Valid_2D_PrivateClass_PublicMethod6 - { - public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } - } -}"; - // 3d - private const string Valid_3D_PrivateClass_PublicMethod1 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod1 - { - public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod2 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod2 - { - public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod3 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod3 - { - public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod4 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod4 - { - public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod5 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod5 - { - public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - } -}"; - private const string Valid_3D_PrivateClass_PublicMethod6 = @" -namespace Test -{ - internal sealed class Valid_3D_PrivateClass_PublicMethod6 - { - public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } -}"; - // methods - private const string Valid_MultiDimArray_PublicClassPrivateMethod1 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 - { - private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod2 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 - { - private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod3 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty3 - { - private int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod4 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty4 - { - private int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod5 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty5 - { - private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } - } -}"; - private const string Valid_MultiDimArray_PublicClassPrivateMethod6 = @" -namespace Test -{ - public sealed class Valid_MultiDimArray_PublicClassPrivateProperty6 - { - private bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } - } -}"; - //// System.Array - private const string Valid_SystemArray_Interface1 = @" -namespace Test -{ - internal interface Valid_SystemArray_Interface1 - { - System.Array Id(System.Array arr); - } -}"; - private const string Valid_SystemArray_Interface2 = @" -namespace Test -{ - internal interface Valid_SystemArray_Interface2 - { - void Method2(System.Array arr); - } -}"; - private const string Valid_SystemArray_Interface3 = @" -namespace Test -{ - internal interface Valid_SystemArray_Interface3 - { - System.Array Method3(); - } -}"; - private const string Valid_SystemArray_InternalClass1 = @" -namespace Test -{ - internal class Valid_SystemArray_InternalClass1 - { - public System.Array Arr_2d { get; set; } - } -}"; - private const string Valid_SystemArray_InternalClass2 = @" -namespace Test -{ - internal class Valid_SystemArray_InternalClass2 - { - - public System.Array Arr_3d { get; set; } - } -}"; - private const string Valid_SystemArray_InternalClass3 = @" -namespace Test -{ - internal class Valid_SystemArray_InternalClass3 - { - private System.Array PrivArr_2d { get; set; } - } -}"; - private const string Valid_SystemArray_InternalClass4 = @" -namespace Test -{ - internal class Valid_SystemArray_InternalClass4 - { - private System.Array PrivArr_3d { get; set; } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty1 = @" -namespace Test -{ - public sealed class Valid_SystemArray_PublicClassPrivateProperty1 - { - private System.Array PrivArr_2d { get; set; } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty2 = @" -using System; -namespace Test -{ - public sealed class Valid_SystemArray_PublicClassPrivateProperty2 - { - private Array PrivArr_3d { get; set; } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty3 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateProperty3 - { - private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty4 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateProperty4 - { - private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty5 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateProperty1 - { - private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PublicClassPrivateProperty6 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateProperty2 - { - private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods1 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_InternalClassPublicMethods1 - { - public System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods2 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_InternalClassPublicMethods2 - { - public System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods3 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_InternalClassPublicMethods3 - { - public System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods4 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_InternalClassPublicMethods4 - { - public bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods5 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_InternalClassPublicMethods5 - { - public bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - } -}"; - private const string Valid_SystemArray_InternalClassPublicMethods6 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_InternalClassPublicMethods6 - { - public System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty1 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_PrivateClassPublicProperty1 - { - public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty2 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_PrivateClassPublicProperty2 - { - public System.Array Arr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty3 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_PrivateClassPublicProperty3 - { - public int[] Arr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty4 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_PrivateClassPublicProperty4 - { - public System.Array Arr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty5 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_PrivateClassPublicProperty5 - { - private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty6 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_PrivateClassPublicProperty6 - { - private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty7 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_PrivateClassPublicProperty7 - { - private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArray_PrivateClassPublicProperty8 = @" -namespace Test -{ - internal sealed class Valid_SystemArray_PrivateClassPublicProperty8 - { - private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod1 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateMethod1 - { - private System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod2 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateMethod2 - { - private System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod3 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateMethod3 - { - private System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod4 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateMethod4 - { - private System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod5 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateMethod5 - { - private bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } - } -}"; - private const string Valid_SystemArrayPublicClassPrivateMethod6 = @" -namespace Test -{ - public sealed class Valid_SystemArrayPublicClassPrivateMethod6 - { - private bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } - } -}"; - private const string Valid_SystemArrayProperty = @" -namespace Test -{ - public sealed class SystemArrayProperty_Valid - { - private System.Array PrivArr { get; set; } - } -}"; - //// ReadOnlyArray / WriteOnlyArray - private const string Valid_ArrayParamAttrUnary_1 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public int GetSum([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } - } -}"; - private const string Valid_ArrayParamAttrUnary_2 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrUnary_3 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrUnary_4 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrUnary_5 = @" -namespace TestNamespace -{ - public sealed class OnlyParam - { - public void ArrayNotMarked_Valid(out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_1 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public int GetSum(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } - } -}"; - private const string Valid_ArrayParamAttrBinary_2 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void MarkedWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrBinary_3 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void MarkedOutAndWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_4 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void MarkedOutOnly_Valid(int i, out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_5 = @" -namespace TestNamespace -{ - public sealed class TwoParam - { - public void ArrayNotMarked_Valid(int i, out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_6 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedReadOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrBinary_7 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } - } -}"; - private const string Valid_ArrayParamAttrBinary_8 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } - } -}"; - private const string Valid_ArrayParamAttrBinary_9 = @" -namespace TestNamespace -{ - public sealed class TwoArray - { - public void MarkedOut_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, out int[] arr) { arr = new int[] { }; } - } -}"; - //// Struct field - private const string Valid_StructWithByteField = @" -namespace Test -{ - public struct StructWithByteField_Valid - { - public byte b; - } -}"; - private const string Valid_StructWithImportedStruct = @" -using System.Numerics; -namespace Test -{ - public struct StructWithWinRTStructField - { - public Matrix3x2 matrix; - } -}"; - private const string Valid_StructWithImportedStructQualified = @" -using System.Numerics; -namespace Test -{ - public struct StructWithWinRTStructField - { - public System.Numerics.Matrix3x2 matrix; - } -}"; - private const string Valid_StructWithPrimitiveTypes = @" -namespace Test -{ - public struct StructWithAllValidFields - { - public bool boolean; - public char character; - public decimal dec; - public double dbl; - public float flt; - public int i; - public uint nat; - public long lng; - public ulong ulng; - public short sh; - public ushort us; - public string str; - } -}"; - } + public sealed partial class UnitTesting + { + private const string Valid_RollYourOwnAsyncAction = @" +using System; +using Windows.Foundation; +namespace DiagnosticTests +{ + + public interface IAsyncAction + { + void GetResults(); + AsyncActionCompletedHandler Completed { get; set; } + void Cancel(); + void Close(); + Exception ErrorCode { get; } + uint Id { get; } + AsyncStatus Status { get; } + } + + public sealed class ClassAsyncAction : IAsyncAction + { + public void GetResults() { throw new NotImplementedException(); } + + public AsyncActionCompletedHandler Completed { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public void Cancel() { throw new NotImplementedException(); } + + public void Close() { throw new NotImplementedException(); } + + public Exception ErrorCode => throw new NotImplementedException(); + + public uint Id => throw new NotImplementedException(); + + public AsyncStatus Status => throw new NotImplementedException(); + } +}"; + + private const string Valid_CustomList = @" +using System; +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class DisposableClass : IDisposable + { + public bool IsDisposed { get; set; } + + public DisposableClass() + { + IsDisposed = false; + } + + public void Dispose() + { + IsDisposed = true; + } + } + + public sealed class CustomVector : IList + { + private IList _list; + + public CustomVector() + { + _list = new List(); + } + + public CustomVector(IList list) + { + _list = list; + } + + public DisposableClass this[int index] { get => _list[index]; set => _list[index] = value; } + + public int Count => _list.Count(); + + public bool IsReadOnly => false; + + public void Add(DisposableClass item) + { + _list.Add(item); + } + + public void Clear() + { + _list.Clear(); + } + + public bool Contains(DisposableClass item) + { + return _list.Contains(item); + } + + public void CopyTo(DisposableClass[] array, int arrayIndex) + { + _list.CopyTo(array, arrayIndex); + } + + public IEnumerator GetEnumerator() + { + return _list.GetEnumerator(); + } + + public int IndexOf(DisposableClass item) + { + return _list.IndexOf(item); + } + + public void Insert(int index, DisposableClass item) + { + _list.Insert(index, item); + } + + public bool Remove(DisposableClass item) + { + return _list.Remove(item); + } + + public void RemoveAt(int index) + { + _list.RemoveAt(index); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + } +} +"; + private const string Valid_CustomDictionary = @" +using System.Collections; +using System.Collections.Generic; +namespace DiagnosticTests +{ + public struct BasicStruct + { + public int X, Y; + public string Value; + } + + public sealed class CustomDictionary : IDictionary + { + private readonly Dictionary _dictionary; + + public CustomDictionary() + { + _dictionary = new Dictionary(); + } + + public BasicStruct this[string key] { + get => _dictionary[key]; + set => _dictionary[key] = value; + } + + public ICollection Keys => _dictionary.Keys; + + public ICollection Values => _dictionary.Values; + + public int Count => _dictionary.Count; + + public bool IsReadOnly => false; + + public void Add(string key, BasicStruct value) + { + _dictionary.Add(key, value); + } + + public void Add(KeyValuePair item) + { + _dictionary.Add(item.Key, item.Value); + } + + public void Clear() + { + _dictionary.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return _dictionary.ContainsKey(item.Key); + } + + public bool ContainsKey(string key) + { + return _dictionary.ContainsKey(key); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + } + + public IEnumerator> GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + + public bool Remove(string key) + { + return _dictionary.Remove(key); + } + + public bool Remove(KeyValuePair item) + { + return _dictionary.Remove(item.Key); + } + + public bool TryGetValue(string key, [MaybeNullWhen(false)] out BasicStruct value) + { + return _dictionary.TryGetValue(key, out value); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + } +}"; + private const string Valid_TwoNamespacesSameName = @" +namespace DiagnosticTests.Component +{ + public sealed class A + { + public static IReadOnlyList GetUris() + { + return new List() { + new Uri(""http://github.com""), + new Uri(""http://microsoft.com"") + }; + } + } +} + +namespace DiagnosticTests.Component +{ + public sealed class B + { + public static IReadOnlyList GetNums() + { + return new List() { 311, 313 }; + } + } +}"; + private const string Valid_ListUsage = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class A + { + public static IReadOnlyList GetUris() + { + return new List() { + new Uri(""http://github.com""), + new Uri(""http://microsoft.com"") + }; + } + } +}"; + + private const string Valid_ListUsage2 = @" +namespace DiagnosticTests +{ + public sealed class A + { + public static System.Collections.Generic.IReadOnlyList GetUris() + { + return new System.Collections.Generic.List() { + new Uri(""http://github.com""), + new Uri(""http://microsoft.com"") + }; + } + } +}"; + + // Namespaces + private const string Valid_NestedNamespace = @" +namespace DiagnosticTests +{ + public sealed class Blank { public Blank() { } } + namespace A + { + public sealed class Class4 { public Class4() { } } + } +}"; + private const string Valid_NestedNamespace2 = @" +namespace DiagnosticTests +{ + public sealed class Blank { public Blank() { } } + namespace A + { + public sealed class Class4 { public Class4() { } } + + namespace B + { + public sealed class F() { public F() {} } + } + } +}"; + private const string Valid_NestedNamespace3 = @" +namespace DiagnosticTests.Component +{ + public sealed Class1 { public int X { get; set; } } + + namespace InnerComponent + { + public sealed class Class2 { public int Y { get; } } + } +}"; + private const string Valid_NestedNamespace4 = @" +namespace DiagnosticTests +{ + public sealed class Blank { public Blank() {} } +} + +namespace DiagnosticTests.Component +{ + public sealed Class1 { public int X { get; set; } } + + namespace InnerComponent + { + public sealed class Class2 { public int Y { get; } } + } +}"; + private const string Valid_NestedNamespace5 = @" +namespace DiagnosticTests.Component +{ + namespace SubNamespace + { + public sealed class InnerClass { public InnerClass() {} } + } + public sealed class Blank { public Blank() {} } +} + +namespace DiagnosticTests.Component +{ + public sealed Class1 { public int X { get; set; } } + + namespace InnerComponent + { + public sealed class Class2 { public int Y { get; } } + } +}"; + private const string Valid_NamespacesDiffer = @" +namespace DiagnosticTests +{ + public sealed class Blank { public Blank() { } } + + namespace InnerA + { + public sealed class AnotherBlank { public AnotherBlank() { } } + } + + namespace InnerB + { + public sealed class AnotherBlank { public AnotherBlank() { } } + } +}"; + private const string Valid_NamespaceAndPrefixedNamespace = @" +namespace DiagnosticTests +{ + public sealed class Blank { public Blank() { } } +} + +namespace DiagnosticTests.A +{ + public sealed class AClass { public AClass() { } } +} +"; + // Dict + private const string Valid_ClassWithGenericDictReturnType_Private = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private Dictionary ReturnsDict(int length) { return new Dictionary(); } + } +}"; + private const string Valid_ClassWithGenericDictInput_Private = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private int ReturnsInt(Dictionary ls) { return 0; } + } +}"; + private const string Valid_ClassWithPrivateGenDictProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private System.Collections.Generic.Dictionary IntList { get; set; } + } +}"; + private const string Valid_IfaceWithPrivateGenDictProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + private Dictionary Dict { get; set; } + } +}"; + // RODict + private const string Valid_ClassWithGenericRODictReturnType_Private = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private ReadOnlyDictionary ReturnsRODict(int length) { return new ReadOnlyDictionary(); } + } +}"; + private const string Valid_ClassWithGenericRODictInput_Private = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private int ReturnsInt(ReadOnlyDictionary ls) { return 0; } + } +}"; + private const string Valid_ClassWithPrivateGenRODictProp = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private ReadOnlyDictionary RODict { get; set; } + } +}"; + private const string Valid_IfaceWithPrivateGenRODictProp = @" +using System.Collections.ObjectModel; +namespace DiagnosticTests +{ + public interface MyInterface + { + private ReadOnlyDictionary RODict { get; set; } + } +}"; + // KeyValuePair + private const string Valid_InterfaceWithGenericKVPairReturnType = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + KeyValuePair KVPair(int length); + } +}"; + private const string Valid_InterfaceWithGenericKVPairInput = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + int ReturnsInt(System.Collections.Generic.KeyValuePair kvp); + } +}"; + private const string Valid_ClassWithGenericKVPairReturnType = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public KeyValuePair ReturnsKVPair(int length); + } +}"; + private const string Valid_ClassWithGenericKVPairInput = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public int ReturnsInt(KeyValuePair ls) { return 0; } + } +}"; + private const string Valid_IfaceWithGenKVPairProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + public KeyValuePair KVpair { get; set; } + } +}"; + private const string Valid_ClassWithGenKVPairProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + public KeyValuePair KVpair { get; set; } + } +}"; + private const string Valid_ClassWithGenericKVPairReturnType_Private = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private KeyValuePair ReturnsKVPair(int length) { return new KeyValuePair(); } + } +}"; + private const string Valid_ClassWithGenericKVPairInput_Private = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private int ReturnsInt(KeyValuePair ls) { return 0; } + } +}"; + private const string Valid_ClassWithPrivateGenKVPairProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private KeyValuePair KVPair { get; set; } + } +}"; + private const string Valid_IfaceWithPrivateGenKVPairProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public interface MyInterface + { + private KeyValuePair KVPair { get; set; } + } +}"; + // Enumerable + private const string Valid_ClassWithGenericEnumerableReturnType_Private = @" +using System.Linq; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private Enumerable ReturnsIntList(int length) { return new Enumerable(); } + } +}"; + private const string Valid_ClassWithGenericEnumerableInput_Private = @" +using System.Linq; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private int ReturnsIntList(Enumerable ls) { return 0; } + } +}"; + private const string Valid_ClassWithPrivateGenEnumerableProp = @" +using System.Linq; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private Enumerable IntList { get; set; } + } +}"; + private const string Valid_IfaceWithPrivateGenEnumerableProp = @" +using System.Linq; +namespace DiagnosticTests +{ + public interface MyInterface + { + private Enumerable Enumer { get; set; } + } +}"; + // List + private const string Valid_ClassWithGenericListReturnType_Private = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private List ReturnsIntList(int length) { return List(); } + } +}"; + private const string Valid_ClassWithGenericListInput_Private = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private int ReturnsIntList(List ls) { return 0; } + } +}"; + private const string Valid_ClassWithPrivateGenListProp = @" +using System.Collections.Generic; +namespace DiagnosticTests +{ + public sealed class MyClass + { + private List IntList { get; set; } + } +}"; + private const string Valid_IfaceWithPrivateGenListProp = @" +namespace DiagnosticTests +{ + public interface MyInterface + { + private List IntList { get; set; } + } +}"; + //// DefaultOverload attribute + private const string Valid_InterfaceWithOverloadAttribute = @" +using Windows.Foundation.Metadata; +namespace DiagnosticTests +{ + public interface MyInterface + { + int Foo(int n); + [DefaultOverload] + int Foo(string s); + } +}"; + private const string Valid_TwoOverloads_DiffParamCount = @" +namespace DiagnosticTests +{ + public sealed class Valid_TwoOverloads_DiffParamCount + { + public string OverloadExample(string s) { return s; } + public int OverloadExample(int n, int m) { return n; } + } +}"; + private const string Valid_TwoOverloads_OneAttribute_OneInList = @" +namespace DiagnosticTests +{ + public sealed class Valid_TwoOverloads_OneAttribute_OneInList + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1), + Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } + +}"; + private const string Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute = @" +namespace DiagnosticTests +{ + public sealed class Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute + { + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + private const string Valid_TwoOverloads_OneAttribute_TwoLists = @" +namespace DiagnosticTests +{ + public sealed class Valid_TwoOverloads_OneAttribute_TwoLists + { + + [Windows.Foundation.Metadata.Deprecated(""deprecated"", Windows.Foundation.Metadata.DeprecationType.Deprecate, 1)] + [Windows.Foundation.Metadata.DefaultOverload()] + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + } +}"; + private const string Valid_ThreeOverloads_OneAttribute = @" +namespace DiagnosticTests +{ + public sealed class Valid_ThreeOverloads_OneAttribute + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + + public bool OverloadExample(bool b) { return b; } + } +}"; + private const string Valid_ThreeOverloads_OneAttribute_2 = @" +namespace DiagnosticTests +{ + public sealed class Valid_ThreeOverloads_OneAttribute_2 + { + public string OverloadExample(string s) { return s; } + + public int OverloadExample(int n) { return n; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public bool OverloadExample(bool b) { return b; } + } +}"; + private const string Valid_TwoOverloads_OneAttribute_3 = @" +namespace DiagnosticTests +{ + public sealed class Valid_TwoOverloads_OneAttribute_3 + { + public string OverloadExample(string s) { return s; } + + [Windows.Foundation.Metadata.DefaultOverload()] + public int OverloadExample(int n) { return n; } + } +}"; + //// Jagged array + private const string Valid_JaggedMix_PrivateClassPublicProperty = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_JaggedArray_PrivateClassPublicProperty + { + private int[][] Arr { get; set; } + public int[][] ArrP { get; set; } + public int[][][] Arr3 { get; set; } + private int[][][] Arr3P { get; set; } + } +}"; + private const string Valid_Jagged2D_PrivateClassPublicMethods = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_JaggedArray_PrivateClassPublicMethods + { + public int[][] J2_ReturnOnly() + { + int[][] arr = new int[2][]; + arr[0] = new int[1] { 1 }; + arr[1] = new int[1] { 2 }; + return arr; + } + public int[][] J2_ReturnAndInput1(int[][] arr) { return arr; } + public int[][] J2_ReturnAndInput2of2(bool a, int[][] arr) { return arr; } + public bool J2_NotReturnAndInput2of2(bool a, int[][] arr) { return a; } + public bool J2_NotReturnAndInput2of3(bool a, int[][] arr, bool b) { return a; } + public int[][] J2_ReturnAndInput2of3(bool a, int[][] arr, bool b) { return arr; } + } +}"; + private const string Valid_Jagged3D_PrivateClassPublicMethods = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_Jagged3D_PrivateClassPublicMethods + { + public int[][][] J3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + public int[][][] J3_ReturnAndInput1(int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + public int[][][] J3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + public bool J3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + public bool J3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + private const string Valid_Jagged3D_PublicClassPrivateMethods = @" +namespace DiagnosticTests +{ + public sealed class Valid_Jagged3D_PublicClassPrivateMethods + { + private int[][][] D3_ReturnOnly() + { + int[][] arr2 = new int[2][]; + arr2[0] = new int[1] { 1 }; + arr2[1] = new int[1] { 2 }; + + int[][][] arr = new int[1][][]; + arr[0] = arr2; + return arr; + } + private int[][][] D3_ReturnAndInput1(int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of2(bool a, int[][][] arr) { return arr; } + private int[][][] D3_ReturnAndInput2of3(bool a, int[][][] arr, bool b) { return arr; } + private bool D3_NotReturnAndInput2of2(bool a, int[][][] arr) { return a; } + private bool D3_NotReturnAndInput2of3(bool a, int[][][] arr, bool b) { return a; } + } +}"; + private const string Valid_Jagged2D_Property = @" +namespace DiagnosticTests +{ + public sealed class Jagged2D_Property1 + { + private int[][] ArrP { get; set; } + } +}"; + private const string Valid_Jagged3D_Property = @" +namespace DiagnosticTests +{ + public sealed class Jagged3D_Property2 + { + private int[][][] Arr3P { get; set; } + } +}"; + // prop + private const string Valid_MultiDimArray_PrivateClassPublicProperty1 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal class Valid_MultiDimArray_PrivateClassPublicProperty1 + { + public int[,] Arr_2d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PrivateClassPublicProperty2 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal class Valid_MultiDimArray_PrivateClassPublicProperty2 + { + public int[,,] Arr_3d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PrivateClassPublicProperty3 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal class Valid_MultiDimArray_PrivateClassPublicProperty3 + { + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PrivateClassPublicProperty4 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal class Valid_MultiDimArray_PrivateClassPublicProperty4 + { + private int[,,] PrivArr_3d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateProperty1 = @" +namespace DiagnosticTests +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 + { + private int[,] PrivArr_2d { get; set; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateProperty2 = @" +namespace DiagnosticTests +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 + { + private int[,,] PrivArr_3d { get; set; } + } +}"; + // 2d + private const string Valid_2D_PrivateClass_PublicMethod1 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_2D_PrivateClass_PublicMethod1 + { + public int[,] D2_ReturnOnly() { return new int[4, 2]; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod2 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_2D_PrivateClass_PublicMethod2 + { + public int[,] D2_ReturnAndInput1(int[,] arr) { return arr; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod3 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_2D_PrivateClass_PublicMethod3 + { + public int[,] D2_ReturnAndInput2of2(bool a, int[,] arr) { return arr; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod4 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_2D_PrivateClass_PublicMethod4 + { + public bool D2_NotReturnAndInput2of2(bool a, int[,] arr) { return a; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod5 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_2D_PrivateClass_PublicMethod5 + { + public bool D2_NotReturnAndInput2of3(bool a, int[,] arr, bool b) { return a; } + } +}"; + private const string Valid_2D_PrivateClass_PublicMethod6 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_2D_PrivateClass_PublicMethod6 + { + public int[,] D2_ReturnAndInput2of3(bool a, int[,] arr, bool b) { return arr; } + } +}"; + // 3d + private const string Valid_3D_PrivateClass_PublicMethod1 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_3D_PrivateClass_PublicMethod1 + { + public int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod2 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_3D_PrivateClass_PublicMethod2 + { + public int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod3 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_3D_PrivateClass_PublicMethod3 + { + public int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod4 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_3D_PrivateClass_PublicMethod4 + { + public int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod5 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_3D_PrivateClass_PublicMethod5 + { + public bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string Valid_3D_PrivateClass_PublicMethod6 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_3D_PrivateClass_PublicMethod6 + { + public bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + // methods + private const string Valid_MultiDimArray_PublicClassPrivateMethod1 = @" +namespace DiagnosticTests +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty1 + { + private int[,,] D3_ReturnOnly() { return new int[2, 1, 3] { { { 1, 1, 1 } }, { { 2, 2, 2 } } }; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod2 = @" +namespace DiagnosticTests +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty2 + { + private int[,,] D3_ReturnAndInput1(int[,,] arr) { return arr; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod3 = @" +namespace DiagnosticTests +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty3 + { + private int[,,] D3_ReturnAndInput2of2(bool a, int[,,] arr) { return arr; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod4 = @" +namespace DiagnosticTests +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty4 + { + private int[,,] D3_ReturnAndInput2of3(bool a, int[,,] arr, bool b) { return arr; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod5 = @" +namespace DiagnosticTests +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty5 + { + private bool D3_NotReturnAndInput2of2(bool a, int[,,] arr) { return a; } + } +}"; + private const string Valid_MultiDimArray_PublicClassPrivateMethod6 = @" +namespace DiagnosticTests +{ + public sealed class Valid_MultiDimArray_PublicClassPrivateProperty6 + { + private bool D3_NotReturnAndInput2of3(bool a, int[,,] arr, bool b) { return a; } + } +}"; + //// System.Array + private const string Valid_SystemArray_Interface1 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal interface Valid_SystemArray_Interface1 + { + System.Array Id(System.Array arr); + } +}"; + private const string Valid_SystemArray_Interface2 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal interface Valid_SystemArray_Interface2 + { + void Method2(System.Array arr); + } +}"; + private const string Valid_SystemArray_Interface3 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal interface Valid_SystemArray_Interface3 + { + System.Array Method3(); + } +}"; + private const string Valid_SystemArray_InternalClass1 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal class Valid_SystemArray_InternalClass1 + { + public System.Array Arr_2d { get; set; } + } +}"; + private const string Valid_SystemArray_InternalClass2 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal class Valid_SystemArray_InternalClass2 + { + + public System.Array Arr_3d { get; set; } + } +}"; + private const string Valid_SystemArray_InternalClass3 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal class Valid_SystemArray_InternalClass3 + { + private System.Array PrivArr_2d { get; set; } + } +}"; + private const string Valid_SystemArray_InternalClass4 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal class Valid_SystemArray_InternalClass4 + { + private System.Array PrivArr_3d { get; set; } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty1 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArray_PublicClassPrivateProperty1 + { + private System.Array PrivArr_2d { get; set; } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty2 = @" +using System; +namespace DiagnosticTests +{ + public sealed class Valid_SystemArray_PublicClassPrivateProperty2 + { + private Array PrivArr_3d { get; set; } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty3 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateProperty3 + { + private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty4 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateProperty4 + { + private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty5 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateProperty1 + { + private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PublicClassPrivateProperty6 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateProperty2 + { + private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods1 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_InternalClassPublicMethods1 + { + public System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods2 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_InternalClassPublicMethods2 + { + public System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods3 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_InternalClassPublicMethods3 + { + public System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods4 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_InternalClassPublicMethods4 + { + public bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods5 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_InternalClassPublicMethods5 + { + public bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string Valid_SystemArray_InternalClassPublicMethods6 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_InternalClassPublicMethods6 + { + public System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty1 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_PrivateClassPublicProperty1 + { + public int[] Arr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty2 = @" +namespace DiagnosticTests +{ public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_PrivateClassPublicProperty2 + { + public System.Array Arr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty3 = @" +namespace DiagnosticTests +{ public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_PrivateClassPublicProperty3 + { + public int[] Arr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty4 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_PrivateClassPublicProperty4 + { + public System.Array Arr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty5 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + + internal sealed class Valid_SystemArray_PrivateClassPublicProperty5 + { + private int[] PrivArr { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty6 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_PrivateClassPublicProperty6 + { + private System.Array PrivArr2 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }, new int[] { 1 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty7 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_PrivateClassPublicProperty7 + { + private int[] PrivArr3 { get { return (int[])Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArray_PrivateClassPublicProperty8 = @" +namespace DiagnosticTests +{ + public sealed class Blank + { + public Blank() {} + } + internal sealed class Valid_SystemArray_PrivateClassPublicProperty8 + { + private System.Array PrivArr4 { get { return Array.CreateInstance(typeof(int), new int[] { 4 }); } } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod1 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateMethod1 + { + private System.Array SysArr_ReturnOnly() { return Array.CreateInstance(typeof(int), new int[] { 4 }); } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod2 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateMethod2 + { + private System.Array SysArr_ReturnAndInput1(System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod3 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateMethod3 + { + private System.Array SysArr_ReturnAndInput2of2(bool a, System.Array arr) { return arr; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod4 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateMethod4 + { + private System.Array SysArr_ReturnAndInput2of3(bool a, System.Array arr, bool b) { return arr; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod5 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateMethod5 + { + private bool SysArr_NotReturnAndInput2of2(bool a, System.Array arr) { return a; } + } +}"; + private const string Valid_SystemArrayPublicClassPrivateMethod6 = @" +namespace DiagnosticTests +{ + public sealed class Valid_SystemArrayPublicClassPrivateMethod6 + { + private bool SysArr_NotReturnAndInput2of3(bool a, System.Array arr, bool b) { return a; } + } +}"; + private const string Valid_SystemArrayProperty = @" +namespace DiagnosticTests +{ + public sealed class SystemArrayProperty_Valid + { + private System.Array PrivArr { get; set; } + } +}"; + //// ReadOnlyArray / WriteOnlyArray + private const string Valid_ArrayParamAttrUnary_1 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public int GetSum([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } +}"; + private const string Valid_ArrayParamAttrUnary_2 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrUnary_3 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrUnary_4 = @" +namespace DiagnosticTests +{ + public sealed class OnlyParam + { + public void MarkedOutOnly_Valid(out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_1 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public int GetSum(int i, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { return 0; } + } +}"; + private const string Valid_ArrayParamAttrBinary_2 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void MarkedWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_3 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void MarkedOutAndWriteOnly_Valid(int i, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_4 = @" +namespace DiagnosticTests +{ + public sealed class TwoParam + { + public void MarkedOutOnly_Valid(int i, out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_5 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void MarkedReadOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_6 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void MarkedWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] arr) { } + } +}"; + private const string Valid_ArrayParamAttrBinary_7 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void MarkedOutAndWriteOnly_Valid([System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray] int[] xs, [System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] out int[] arr) { arr = new int[] { }; } + } +}"; + private const string Valid_ArrayParamAttrBinary_8 = @" +namespace DiagnosticTests +{ + public sealed class TwoArray + { + public void MarkedOut_Valid([System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray] int[] xs, out int[] arr) { arr = new int[] { }; } + } +}"; + //// Struct field + private const string Valid_StructWithByteField = @" +namespace DiagnosticTests +{ + public struct StructWithByteField_Valid + { + public byte b; + } +}"; + private const string Valid_StructWithImportedStruct = @" +using System.Numerics; +namespace DiagnosticTests +{ + public struct StructWithWinRTStructField + { + public Matrix3x2 matrix; + } +}"; + private const string Valid_StructWithImportedStructQualified = @" +using System.Numerics; +namespace DiagnosticTests +{ + public struct StructWithWinRTStructField + { + public System.Numerics.Matrix3x2 matrix; + } +}"; + private const string Valid_StructWithPrimitiveTypes = @" +namespace DiagnosticTests +{ + public struct StructWithAllValidFields + { + public bool boolean; + public char character; + public decimal dec; + public double dbl; + public float flt; + public int i; + public uint nat; + public long lng; + public ulong ulng; + public short sh; + public ushort us; + public string str; + } +}"; + } } + diff --git a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs b/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs deleted file mode 100644 index b13c8bdc2..000000000 --- a/src/Authoring/DiagnosticTests/UnitTestDiagnostics.cs +++ /dev/null @@ -1,415 +0,0 @@ -using NUnit.Framework; -using Microsoft.CodeAnalysis; -using WinRT.SourceGenerator; -using System.Collections.Immutable; -using System.Collections.Generic; -using System.Linq; - -namespace DiagnosticTests -{ - [TestFixture] - public partial class TestDiagnostics - { - /* UnitTests require the "IsCsWinRTComponent" check in Generator.cs to be commented out, - until we can pass AnalyzerConfigOptions in our TestHelpers.cs file - --- - Add unit tests by creating a source code like this: - private const string MyNewTest = @"namespace Test { ... }"; - - And have a DiagnosticDescriptor for the one to check for, they live in WinRT.SourceGenerator.DiagnosticRules - - Then go to the ValidCases/InvalidCases property here and add an entry for it - */ - - - /// - /// CheckNoDiagnostic asserts that no diagnostics are raised on the - /// compilation produced from the cswinrt source generator based on the given source code /// - /// - [Test, TestCaseSource(nameof(ValidCases))] - public void CheckNoDiagnostic(string source) - { - Compilation compilation = CreateCompilation(source); - RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); - var WinRTDiagnostics = diagnosticsFound.Where(diag => diag.Id.StartsWith("WME")); - Assert.That(!WinRTDiagnostics.Any()); - } - - /// - /// CodeHasDiagnostic takes some source code (string) and a Diagnostic descriptor, - /// it checks that a diagnostic with the same description was raised by the source generator - /// - [Test, TestCaseSource(nameof(InvalidCases))] - public void CodeHasDiagnostic(string testCode, DiagnosticDescriptor rule) - { - Compilation compilation = CreateCompilation(testCode); - RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); - HashSet diagDescsFound = MakeDiagnosticSet(diagnosticsFound); - Assert.That(diagDescsFound.Contains(rule)); - } - - #region InvalidTests - private static IEnumerable InvalidCases - { - get - { - // multi-dimensional array tests - yield return new TestCaseData(MultiDim_2DProp, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Array Property"); - yield return new TestCaseData(MultiDim_3DProp, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Array Property"); - yield return new TestCaseData(MultiDim_3DProp_Whitespace, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Array Property With whitespace"); - - yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 1"); - yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 2"); - yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 3"); - yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 4"); - yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 5"); - yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Class Method 6"); - - yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 1"); - yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 2"); - yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 3"); - yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 4"); - yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 5"); - yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Class Method 6"); - - yield return new TestCaseData(MultiDim_2D_Interface1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 1"); - yield return new TestCaseData(MultiDim_2D_Interface2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 2"); - yield return new TestCaseData(MultiDim_2D_Interface3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 3"); - yield return new TestCaseData(MultiDim_2D_Interface4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 4"); - yield return new TestCaseData(MultiDim_2D_Interface5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 5"); - yield return new TestCaseData(MultiDim_2D_Interface6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 2D Interface Method 6"); - - yield return new TestCaseData(MultiDim_3D_Interface1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 1"); - yield return new TestCaseData(MultiDim_3D_Interface2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 2"); - yield return new TestCaseData(MultiDim_3D_Interface3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 3"); - yield return new TestCaseData(MultiDim_3D_Interface4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 4"); - yield return new TestCaseData(MultiDim_3D_Interface5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 5"); - yield return new TestCaseData(MultiDim_3D_Interface6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule).SetName("MultiDim 3D Interface Method 6"); - yield return new TestCaseData(SubNamespaceInterface_D2Method1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 2D Subnamespace Interface Method 1"); - yield return new TestCaseData(SubNamespaceInterface_D2Method2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 2D Subnamespace Interface Method 2"); - yield return new TestCaseData(SubNamespaceInterface_D2Method3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 2D Subnamespace Interface Method 3"); - yield return new TestCaseData(SubNamespaceInterface_D2Method4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 2D Subnamespace Interface Method 4"); - yield return new TestCaseData(SubNamespaceInterface_D2Method5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 2D Subnamespace Interface Method 5"); - yield return new TestCaseData(SubNamespaceInterface_D2Method6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 2D Subnamespace Interface Method 6"); - yield return new TestCaseData(SubNamespaceInterface_D3Method1, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 3D Subnamespace Interface Method 1"); - yield return new TestCaseData(SubNamespaceInterface_D3Method2, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 3D Subnamespace Interface Method 2"); - yield return new TestCaseData(SubNamespaceInterface_D3Method3, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 3D Subnamespace Interface Method 3"); - yield return new TestCaseData(SubNamespaceInterface_D3Method4, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 3D Subnamespace Interface Method 4"); - yield return new TestCaseData(SubNamespaceInterface_D3Method5, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 3D Subnamespace Interface Method 5"); - yield return new TestCaseData(SubNamespaceInterface_D3Method6, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule) - .SetName("MultiDim 3D Subnamespace Interface Method 6"); - - - // jagged array tests - yield return new TestCaseData(Jagged2D_Property2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Property 2"); - yield return new TestCaseData(Jagged3D_Property1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Property 1"); - yield return new TestCaseData(Jagged2D_ClassMethod1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 1"); - yield return new TestCaseData(Jagged2D_ClassMethod2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 2"); - yield return new TestCaseData(Jagged2D_ClassMethod3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 3"); - yield return new TestCaseData(Jagged2D_ClassMethod4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 4"); - yield return new TestCaseData(Jagged2D_ClassMethod5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 5"); - yield return new TestCaseData(Jagged2D_ClassMethod6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Class Method 6"); - yield return new TestCaseData(Jagged3D_ClassMethod1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 1"); - yield return new TestCaseData(Jagged3D_ClassMethod2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 2"); - yield return new TestCaseData(Jagged3D_ClassMethod3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 3"); - yield return new TestCaseData(Jagged3D_ClassMethod4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 4"); - yield return new TestCaseData(Jagged3D_ClassMethod5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 5"); - yield return new TestCaseData(Jagged3D_ClassMethod6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Class Method 6"); - yield return new TestCaseData(Jagged2D_InterfaceMethod1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 1"); - yield return new TestCaseData(Jagged2D_InterfaceMethod2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 2"); - yield return new TestCaseData(Jagged2D_InterfaceMethod3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 3"); - yield return new TestCaseData(Jagged2D_InterfaceMethod4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 4"); - yield return new TestCaseData(Jagged2D_InterfaceMethod5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 5"); - yield return new TestCaseData(Jagged2D_InterfaceMethod6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array Interface Method 6"); - yield return new TestCaseData(Jagged3D_InterfaceMethod1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 1"); - yield return new TestCaseData(Jagged3D_InterfaceMethod2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 2"); - yield return new TestCaseData(Jagged3D_InterfaceMethod3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 3"); - yield return new TestCaseData(Jagged3D_InterfaceMethod4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 4"); - yield return new TestCaseData(Jagged3D_InterfaceMethod5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 5"); - yield return new TestCaseData(Jagged3D_InterfaceMethod6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array Interface Method 6"); - yield return new TestCaseData(SubNamespace_Jagged2DInterface1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 1"); - yield return new TestCaseData(SubNamespace_Jagged2DInterface2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 2"); - yield return new TestCaseData(SubNamespace_Jagged2DInterface3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 3"); - yield return new TestCaseData(SubNamespace_Jagged2DInterface4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 4"); - yield return new TestCaseData(SubNamespace_Jagged2DInterface5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 5"); - yield return new TestCaseData(SubNamespace_Jagged2DInterface6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 2D Array SubNamespace Interface Method 6"); - yield return new TestCaseData(SubNamespace_Jagged3DInterface1, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 1"); - yield return new TestCaseData(SubNamespace_Jagged3DInterface2, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 2"); - yield return new TestCaseData(SubNamespace_Jagged3DInterface3, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 3"); - yield return new TestCaseData(SubNamespace_Jagged3DInterface4, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 4"); - yield return new TestCaseData(SubNamespace_Jagged3DInterface5, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 5"); - yield return new TestCaseData(SubNamespace_Jagged3DInterface6, DiagnosticRules.ArraySignature_JaggedArrayRule).SetName("Jagged 3D Array SubNamespace Interface Method 6"); - - // overload attribute tests - yield return new TestCaseData(TwoOverloads_NoAttribute_NamesHaveNumber, DiagnosticRules.MethodOverload_NeedDefaultAttribute) - .SetName("DefaultOverload - Need Attribute 1 - Name has number"); - yield return new TestCaseData(TwoOverloads_NoAttribute, DiagnosticRules.MethodOverload_NeedDefaultAttribute) - .SetName("DefaultOverload - Need Attribute 1"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInList_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Two Overloads, Two Attributes, One in list - Unqualified"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInList_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Two Overloads, Two Attributes, Both in list - Unqualified"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_TwoLists_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Two Overloads, Two Attributes, Two lists - Unqualified"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Two Overloads, One in separate list, one not - Unqualified"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInSeparateList_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Two Overlodas, Two Attributes, Both in separate list - Unqualified"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Two Overloads, Two Attributes - Unqualified"); - yield return new TestCaseData(ThreeOverloads_TwoAttributes_Unqualified, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Three Overloads, Two Attributes - Unqualified"); - - yield return new TestCaseData(TwoOverloads_NoAttribute_NamesHaveNumber, DiagnosticRules.MethodOverload_NeedDefaultAttribute) - .SetName("DefaultOverload - Need Attribute 1 - Name has number"); - yield return new TestCaseData(TwoOverloads_NoAttribute, DiagnosticRules.MethodOverload_NeedDefaultAttribute) - .SetName("DefaultOverload - Need Attribute 1"); - yield return new TestCaseData(TwoOverloads_NoAttribute_OneIrrevAttr, DiagnosticRules.MethodOverload_NeedDefaultAttribute) - .SetName("DefaultOverload - Need Attribute 2"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInList, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Multiple Attribute 1"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInList, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Multiple Attribute 2"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_TwoLists, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Multiple Attribute 3"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInSeparateList_OneNot, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Multiple Attribute 4"); - yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInSeparateList, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Multiple Attribute 5"); - yield return new TestCaseData(TwoOverloads_TwoAttribute, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Multiple Attribute 6"); - yield return new TestCaseData(ThreeOverloads_TwoAttributes, DiagnosticRules.MethodOverload_MultipleDefaultAttribute) - .SetName("DefaultOverload - Multiple Attribute 7"); - - // ....................................................................................................................................... - // multiple class constructors of same arity - yield return new TestCaseData(ConstructorsOfSameArity, DiagnosticRules.ClassConstructorRule).SetName("Multiple constructors of same arity"); - // implementing async interface - - yield return new TestCaseData(InterfaceImplementsIAsyncOperation, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncOperation"); - yield return new TestCaseData(InterfaceImplementsIAsyncOperationWithProgress, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncOperationWithProgress"); - yield return new TestCaseData(InterfaceImplementsIAsyncAction, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncAction"); - yield return new TestCaseData(InterfaceImplementsIAsyncActionWithProgress, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncActionWithProgress"); - - yield return new TestCaseData(InterfaceImplementsIAsyncOperation2, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncOperation in full"); - yield return new TestCaseData(InterfaceImplementsIAsyncOperationWithProgress2, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncOperationWithProgress in full"); - yield return new TestCaseData(InterfaceImplementsIAsyncAction2, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncAction in full"); - yield return new TestCaseData(InterfaceImplementsIAsyncActionWithProgress2, DiagnosticRules.AsyncRule).SetName("Interface Implements IAsyncActionWithProgress in full"); - - yield return new TestCaseData(ClassImplementsIAsyncOperation, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperation"); - yield return new TestCaseData(ClassImplementsIAsyncOperationWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncOperationWithProgress"); - yield return new TestCaseData(ClassImplementsIAsyncAction, DiagnosticRules.AsyncRule).SetName("Implements IAsyncAction"); - yield return new TestCaseData(ClassImplementsIAsyncActionWithProgress, DiagnosticRules.AsyncRule).SetName("Implements IAsyncActionWithProgress"); - // readonly/writeonlyArray attribute - yield return new TestCaseData(TestArrayParamAttrUnary_1, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrUnary_1"); - yield return new TestCaseData(TestArrayParamAttrUnary_2, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrUnary_2"); - yield return new TestCaseData(TestArrayParamAttrUnary_3, DiagnosticRules.ArrayOutputParamMarkedRead).SetName("TestArrayParamAttrUnary_3"); - yield return new TestCaseData(TestArrayParamAttrUnary_4, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_4"); - yield return new TestCaseData(TestArrayParamAttrUnary_5, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_5"); - yield return new TestCaseData(TestArrayParamAttrUnary_6, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrUnary_6"); - yield return new TestCaseData(TestArrayParamAttrUnary_7, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrUnary_7"); - yield return new TestCaseData(TestArrayParamAttrUnary_8, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_8"); - yield return new TestCaseData(TestArrayParamAttrUnary_9, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_9"); - yield return new TestCaseData(TestArrayParamAttrUnary_10, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrUnary_10"); - yield return new TestCaseData(TestArrayParamAttrUnary_11, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_11"); - yield return new TestCaseData(TestArrayParamAttrUnary_12, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_12"); - yield return new TestCaseData(TestArrayParamAttrUnary_13, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_13"); - yield return new TestCaseData(TestArrayParamAttrUnary_14, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrUnary_14"); - yield return new TestCaseData(TestArrayParamAttrBinary_1, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_1"); - yield return new TestCaseData(TestArrayParamAttrBinary_2, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_2"); - yield return new TestCaseData(TestArrayParamAttrBinary_3, DiagnosticRules.ArrayOutputParamMarkedRead).SetName("TestArrayParamAttrBinary_3"); - yield return new TestCaseData(TestArrayParamAttrBinary_4, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_4"); - yield return new TestCaseData(TestArrayParamAttrBinary_5, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_5"); - yield return new TestCaseData(TestArrayParamAttrBinary_6, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_6"); - yield return new TestCaseData(TestArrayParamAttrBinary_7, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_7"); - yield return new TestCaseData(TestArrayParamAttrBinary_8, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_8"); - yield return new TestCaseData(TestArrayParamAttrBinary_9, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_9"); - yield return new TestCaseData(TestArrayParamAttrBinary_10, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrBinary_10"); - yield return new TestCaseData(TestArrayParamAttrBinary_11, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_11"); - yield return new TestCaseData(TestArrayParamAttrBinary_12, DiagnosticRules.ArrayParamMarkedBoth).SetName("TestArrayParamAttrBinary_12"); - yield return new TestCaseData(TestArrayParamAttrBinary_13, DiagnosticRules.ArrayOutputParamMarkedRead).SetName("TestArrayParamAttrBinary_13"); - yield return new TestCaseData(TestArrayParamAttrBinary_14, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_14"); - yield return new TestCaseData(TestArrayParamAttrBinary_15, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_15"); - yield return new TestCaseData(TestArrayParamAttrBinary_16, DiagnosticRules.ArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_16"); - yield return new TestCaseData(TestArrayParamAttrBinary_17, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrBinary_17"); - yield return new TestCaseData(TestArrayParamAttrBinary_18, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_18"); - yield return new TestCaseData(TestArrayParamAttrBinary_19, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_19"); - yield return new TestCaseData(TestArrayParamAttrBinary_20, DiagnosticRules.NonArrayMarked).SetName("TestArrayParamAttrBinary_20"); - yield return new TestCaseData(TestArrayParamAttrBinary_21, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_21"); - yield return new TestCaseData(TestArrayParamAttrBinary_22, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_22"); - yield return new TestCaseData(TestArrayParamAttrBinary_23, DiagnosticRules.NonArrayMarkedInOrOut).SetName("TestArrayParamAttrBinary_23"); - yield return new TestCaseData(TestArrayParamAttrBinary_24, DiagnosticRules.ArrayParamNotMarked).SetName("TestArrayParamAttrBinary_24"); - // name clash with params (__retval) - yield return new TestCaseData(DunderRetValParam, DiagnosticRules.ParameterNamedValueRule).SetName("Test Parameter Name Conflict (__retval)"); - // operator overloading - yield return new TestCaseData(OperatorOverload_Class, DiagnosticRules.OperatorOverloadedRule).SetName("Test Overload of Operator"); - // ref param - yield return new TestCaseData(RefParam_ClassMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Class"); - yield return new TestCaseData(RefParam_InterfaceMethod, DiagnosticRules.RefParameterFound).SetName("Test For Method With Ref Param - Interface"); - // struct field tests - yield return new TestCaseData(EmptyStruct, DiagnosticRules.StructWithNoFieldsRule).SetName("Empty struct"); - yield return new TestCaseData(StructWithClassField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Class Field"); - yield return new TestCaseData(StructWithClassField2, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Class Field2"); - yield return new TestCaseData(StructWithDelegateField, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Delegate Field"); - yield return new TestCaseData(StructWithIndexer, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Indexer Field"); - yield return new TestCaseData(StructWithMethods, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Method Field"); - yield return new TestCaseData(StructWithConst, DiagnosticRules.StructHasConstFieldRule).SetName("Struct with Const Field"); - yield return new TestCaseData(StructWithProperty, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Property Field"); - yield return new TestCaseData(StructWithPrivateField, DiagnosticRules.StructHasPrivateFieldRule).SetName("Struct with Private Field"); - yield return new TestCaseData(StructWithObjectField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Object Field"); - yield return new TestCaseData(StructWithDynamicField, DiagnosticRules.StructHasInvalidFieldRule).SetName("Struct with Dynamic Field"); - yield return new TestCaseData(StructWithConstructor, DiagnosticRules.StructHasInvalidFieldRule2).SetName("Struct with Constructor Field"); - yield return new TestCaseData(StructWithPrimitiveTypesMissingPublicKeyword, DiagnosticRules.StructHasPrivateFieldRule).SetName("Struct with missing public field"); - // system.array tests - yield return new TestCaseData(ArrayInstanceProperty1, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 1"); - yield return new TestCaseData(ArrayInstanceProperty2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 2"); - yield return new TestCaseData(ArrayInstanceProperty3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 3"); - yield return new TestCaseData(ArrayInstanceProperty4, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 4"); - yield return new TestCaseData(SystemArrayProperty5, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Property 5"); - yield return new TestCaseData(ArrayInstanceInterface1, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 1"); - yield return new TestCaseData(ArrayInstanceInterface2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 2"); - yield return new TestCaseData(ArrayInstanceInterface3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 3"); - yield return new TestCaseData(SystemArrayJustReturn, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Method - Return only"); - yield return new TestCaseData(SystemArrayUnaryAndReturn, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Method - Unary and return"); - yield return new TestCaseData(SystemArraySecondArgClass, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Method - Arg 2/2"); - yield return new TestCaseData(SystemArraySecondArg2Class, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Method - Arg 2/3"); - yield return new TestCaseData(SystemArraySecondArgAndReturnTypeClass, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Class 1"); - yield return new TestCaseData(SystemArraySecondArgAndReturnTypeClass2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Class 2"); - yield return new TestCaseData(SystemArrayNilArgsButReturnTypeInterface, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 4"); - yield return new TestCaseData(SystemArrayUnaryAndReturnTypeInterface, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 5"); - yield return new TestCaseData(SystemArraySecondArgAndReturnTypeInterface, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 6"); - yield return new TestCaseData(SystemArraySecondArgAndReturnTypeInterface2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 7"); - yield return new TestCaseData(SystemArraySecondArgInterface, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 8"); - yield return new TestCaseData(SystemArraySecondArgInterface2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Interface 9"); - yield return new TestCaseData(SystemArraySubNamespace_ReturnOnly, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 1/6"); - yield return new TestCaseData(SystemArraySubNamespace_ReturnAndInput1, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 2/6"); - yield return new TestCaseData(SystemArraySubNamespace_ReturnAndInput2of2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 3/6"); - yield return new TestCaseData(SystemArraySubNamespace_ReturnAndInput2of3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 4/6"); - yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of2, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 5/6"); - yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of3, DiagnosticRules.ArraySignature_SystemArrayRule).SetName("System.Array Subnamespace Interface 6/6"); - } - } - - #endregion - - #region ValidTests - - private static IEnumerable ValidCases - { - get - { - // ReadOnlyArray / WriteOnlyArray Attribute - yield return new TestCaseData(Valid_ArrayParamAttrUnary_1).SetName("Valid - Unary - Array marked read only"); - yield return new TestCaseData(Valid_ArrayParamAttrUnary_2).SetName("Valid - Unary - Array marked write only"); - yield return new TestCaseData(Valid_ArrayParamAttrUnary_3).SetName("Valid - Unary - Array marked out and write only"); - yield return new TestCaseData(Valid_ArrayParamAttrUnary_4).SetName("Valid - ArrayParamAttrUnary_4"); - yield return new TestCaseData(Valid_ArrayParamAttrUnary_5).SetName("Valid - ArrayParamAttrUnary_5"); - yield return new TestCaseData(Valid_ArrayParamAttrBinary_1).SetName("Valid - ArrayParamAttrBinary_1"); - yield return new TestCaseData(Valid_ArrayParamAttrBinary_2).SetName("Valid - ArrayParamAttrBinary_2"); - yield return new TestCaseData(Valid_ArrayParamAttrBinary_3).SetName("Valid - ArrayParamAttrBinary_3"); - yield return new TestCaseData(Valid_ArrayParamAttrBinary_4).SetName("Valid - ArrayParamAttrBinary_4"); - yield return new TestCaseData(Valid_ArrayParamAttrBinary_5).SetName("Valid - ArrayParamAttrBinary_5"); - yield return new TestCaseData(Valid_ArrayParamAttrBinary_6).SetName("Valid - ArrayParamAttrBinary_6"); - yield return new TestCaseData(Valid_ArrayParamAttrBinary_7).SetName("Valid - ArrayParamAttrBinary_7"); - yield return new TestCaseData(Valid_ArrayParamAttrBinary_8).SetName("Valid - ArrayParamAttrBinary_8"); - yield return new TestCaseData(Valid_ArrayParamAttrBinary_9).SetName("Valid - ArrayParamAttrBinary_9"); - // Struct field - yield return new TestCaseData(Valid_StructWithPrimitiveTypes).SetName("Valid - Struct with only fields of basic types"); - yield return new TestCaseData(Valid_StructWithImportedStruct).SetName("Valid - Struct with struct field"); - yield return new TestCaseData(Valid_StructWithImportedStructQualified).SetName("Valid - Struct with qualified struct field"); - // SystemArray - yield return new TestCaseData(Valid_SystemArrayProperty).SetName("Valid - System.Array private property"); - yield return new TestCaseData(Valid_SystemArray_Interface1).SetName("Valid - System.Array internal interface 1"); - yield return new TestCaseData(Valid_SystemArray_Interface2).SetName("Valid - System.Array internal interface 2"); - yield return new TestCaseData(Valid_SystemArray_Interface3).SetName("Valid - System.Array internal interface 3"); - yield return new TestCaseData(Valid_SystemArray_InternalClass1).SetName("Valid - System.Array internal class 1"); - yield return new TestCaseData(Valid_SystemArray_InternalClass2).SetName("Valid - System.Array internal class 2"); - yield return new TestCaseData(Valid_SystemArray_InternalClass3).SetName("Valid - System.Array internal class 3"); - yield return new TestCaseData(Valid_SystemArray_InternalClass4).SetName("Valid - System.Array internal class 4"); - yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty1).SetName("Valid - System.Array public class / private property 1"); - yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty2).SetName("Valid - System.Array public class / private property 2"); - yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty3).SetName("Valid - System.Array public class / private property 3"); - yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty4).SetName("Valid - System.Array public class / private property 4"); - yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty5).SetName("Valid - System.Array public class / private property 5"); - yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty6).SetName("Valid - System.Array public class / private property 6"); - yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods1).SetName("Valid - System.Array internal class / public method 1"); - yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods2).SetName("Valid - System.Array internal class / public method 2"); - yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods3).SetName("Valid - System.Array internal class / public method 3"); - yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods4).SetName("Valid - System.Array internal class / public method 4"); - yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods5).SetName("Valid - System.Array internal class / public method 5"); - yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods6).SetName("Valid - System.Array internal class / public method 6"); - yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty1).SetName("Valid - System.Array internal class / public property 1"); - yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty2).SetName("Valid - System.Array internal class / public property 2"); - yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty3).SetName("Valid - System.Array internal class / public property 3"); - yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty4).SetName("Valid - System.Array internal class / public property 4"); - yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty5).SetName("Valid - System.Array internal class / public property 5"); - yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty6).SetName("Valid - System.Array internal class / public property 6"); - yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty7).SetName("Valid - System.Array internal class / public property 7"); - yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty8).SetName("Valid - System.Array internal class / public property 8"); - yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod1).SetName("Valid - System.Array public class / private method 1"); - yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod2).SetName("Valid - System.Array public class / private method 2"); - yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod3).SetName("Valid - System.Array public class / private method 3"); - yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod4).SetName("Valid - System.Array public class / private method 4"); - yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod5).SetName("Valid - System.Array public class / private method 5"); - yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod6).SetName("Valid - System.Array public class / private method 6"); - // multi dim array tests - yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod1).SetName("Valid - MultiDim public class / private method 1"); - yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod2).SetName("Valid - MultiDim public class / private method 2"); - yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod3).SetName("Valid - MultiDim public class / private method 3"); - yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod4).SetName("Valid - MultiDim public class / private method 4"); - yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod5).SetName("Valid - MultiDim public class / private method 5"); - yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod6).SetName("Valid - MultiDim public class / private method 6"); - - yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod1).SetName("Valid - MultiDim 3D private class / public method 1"); - yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod2).SetName("Valid - MultiDim 3D private class / public method 2"); - yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod3).SetName("Valid - MultiDim 3D private class / public method 3"); - yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod4).SetName("Valid - MultiDim 3D private class / public method 4"); - yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod5).SetName("Valid - MultiDim 3D private class / public method 5"); - yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod6).SetName("Valid - MultiDim 3D private class / public method 6"); - - yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod1).SetName("Valid - MultiDim 2D private class / public method 1"); - yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod2).SetName("Valid - MultiDim 2D private class / public method 2"); - yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod3).SetName("Valid - MultiDim 2D private class / public method 3"); - yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod4).SetName("Valid - MultiDim 2D private class / public method 4"); - yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod5).SetName("Valid - MultiDim 2D private class / public method 5"); - yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod6).SetName("Valid - MultiDim 2D private class / public method 6"); - - yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty1).SetName("Valid - MultiDim 2D private class / public property 1"); - yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty2).SetName("Valid - MultiDim 2D private class / public property 2"); - yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty3).SetName("Valid - MultiDim 2D private class / public property 3"); - yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty4).SetName("Valid - MultiDim 2D private class / public property 4"); - yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateProperty1).SetName("Valid - MultiDim 2D public class / private property 1"); - yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateProperty2).SetName("Valid - MultiDim 2D public class / private property 2"); - // jagged array tests - yield return new TestCaseData(Valid_JaggedMix_PrivateClassPublicProperty).SetName("Valid - Jagged Array private class / private property"); - yield return new TestCaseData(Valid_Jagged2D_PrivateClassPublicMethods).SetName("Valid - Jagged Array private class / public method"); - yield return new TestCaseData(Valid_Jagged3D_PrivateClassPublicMethods).SetName("Valid - Jagged Array private class / public method"); - yield return new TestCaseData(Valid_Jagged3D_PublicClassPrivateMethods).SetName("Valid - Jagged Array public class / private method"); - yield return new TestCaseData(Valid_Jagged2D_Property).SetName("Valid - Jagged 2D Array public property"); - yield return new TestCaseData(Valid_Jagged3D_Property).SetName("Valid - Jagged 3D Array public property"); - // overload attributes - yield return new TestCaseData(Valid_TwoOverloads_DiffParamCount).SetName("Valid - DefaultOverload attribute 1"); - yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_OneInList).SetName("Valid - DefaultOverload attribute 2"); - yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute).SetName("Valid - DefaultOverload attribute 3"); - yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_TwoLists).SetName("Valid - DefaultOverload attribute 4"); - yield return new TestCaseData(Valid_ThreeOverloads_OneAttribute).SetName("Valid - DefaultOverload attribute 5"); - yield return new TestCaseData(Valid_ThreeOverloads_OneAttribute_2).SetName("Valid - DefaultOverload attribute 6"); - yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_3).SetName("Valid - DefaultOverload attribute 7"); - } - } - - #endregion - - } -} \ No newline at end of file diff --git a/src/Authoring/DiagnosticTests/UnitTesting.cs b/src/Authoring/DiagnosticTests/UnitTesting.cs new file mode 100644 index 000000000..ff85b3cb6 --- /dev/null +++ b/src/Authoring/DiagnosticTests/UnitTesting.cs @@ -0,0 +1,562 @@ +using NUnit.Framework; +using Microsoft.CodeAnalysis; +using WinRT.SourceGenerator; +using System.Collections.Immutable; +using System.Collections.Generic; +using System.Linq; + +namespace DiagnosticTests +{ + [TestFixture] + public sealed partial class UnitTesting + { + /* A unit test for CsWinRT Diagnostics is a string of source code stored in either `NegativeData.cs` or `PositiveData.cs` + * In either file, the test should be added as + + private const string = @" + // using statements + namespace DiagnosticTests + { + ... + }"; + + * If the scenario the test covers is positive (should generate winmd) then label the string variable "Valid_" instead of "" + * The assumption when viewing tests is that it is negative unless the name is prefixed with 'Valid" + + * For negative scenarios, there should be a DiagnosticDescriptor that matches the scenario + * The CsWinRT DiagnosticDescriptors live in `WinRTRules.cs`, check there and if there's none add a new one. + + * To include the unit test in a run, it needs to be in the corresponding section of this file `UnitTesting.cs` + + * The string given to `.SetName()` should try to describe the scenario succinctly. + * The first few words should classify the scenario and should be separated by periods. + * This makes it easy to group together tests of similar scenarios + * This is because the Visual Studio TestExplorer for NUnit tests uses this property to display the test + * and tries to be helpful by branching sections of tests based on "." in the name + + * For example, using List is not allowed, so all tests for it get prefixed "InvalidType." + + Note 1: The namespace must be DiagnosticTests, as we have rules about namespaces and the winmd filename + Note 2: UnitTests require the "IsCsWinRTComponent" check in Generator.cs to be commented out, + if all tests are failing except the valid ones, make sure that this check is disabled + [this is a workaround until we can pass AnalyzerConfigOptions in `Helpers.cs` file] + */ + + /// + /// CheckNoDiagnostic asserts that no diagnostics are raised on the compilation produced + /// from the cswinrt source generator based on the given source code + /// + [Test, TestCaseSource(nameof(ValidCases))] + public void CheckNoDiagnostic(string source) + { + Compilation compilation = CreateCompilation(source); + RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); + var WinRTDiagnostics = diagnosticsFound.Where(diag => diag.Id.StartsWith("WME")); + string builder = ""; + foreach (var d in WinRTDiagnostics) + { + builder += d.Descriptor.Description + "\n"; + } + if (WinRTDiagnostics.Count() != 0) + { + throw new System.Exception("Expected no diagnostics. But found:" + builder); + } + } + + /// + /// CodeHasDiagnostic takes some source code (string) and a Diagnostic descriptor, + /// it checks that a diagnostic with the same description was raised by the source generator + /// + [Test, TestCaseSource(nameof(InvalidCases))] + public void CodeHasDiagnostic(string testCode, DiagnosticDescriptor rule) + { + Compilation compilation = CreateCompilation(testCode); + RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); + HashSet diagDescsFound = MakeDiagnosticSet(diagnosticsFound); + string builder = ""; + if (!diagDescsFound.Contains(rule)) + { + foreach (var d in diagDescsFound) + { + builder += d.Description + "\n"; + } + if (diagDescsFound.Count != 0) + { + throw new System.Exception("Didn't find the expected diagnostic, found:\n" + builder); + } + else + { + throw new System.Exception("No diagnostics found."); + } + } + } + + #region InvalidTests + private static IEnumerable InvalidCases + { + get + { + // namespace tests + yield return new TestCaseData(SameNameNamespacesDisjoint, WinRTRules.DisjointNamespaceRule).SetName("Namespace. isn't accessible without Test prefix, doesn't use type"); + yield return new TestCaseData(NamespacesDifferByCase, WinRTRules.NamespacesDifferByCase).SetName("Namespace. names only differ by case"); + yield return new TestCaseData(DisjointNamespaces, WinRTRules.DisjointNamespaceRule).SetName("Namespace. isn't accessible without Test prefix, doesn't use type"); + yield return new TestCaseData(DisjointNamespaces2, WinRTRules.DisjointNamespaceRule).SetName("Namespace. using type from inaccessible namespace"); + yield return new TestCaseData(NoPublicTypes, WinRTRules.NoPublicTypesRule).SetName("Component has no public types"); + // the below tests are positive tests when the winmd is named "Test.winmd", and negative when it is "Test.A.winmd" + // they are examples of what it means for namespace to be "prefixed with the winmd file name" + yield return new TestCaseData(NamespaceDifferByDot, WinRTRules.DisjointNamespaceRule).SetName("Namespace Test.A and Test.B"); + yield return new TestCaseData(NamespaceDifferByDot2, WinRTRules.DisjointNamespaceRule).SetName("Namespace Test.A and Test"); + + // Unsealed classes, generic class/interfaces, invalid inheritance (System.Exception) + yield return new TestCaseData(UnsealedClass, WinRTRules.UnsealedClassRule).SetName("Unsealed class public field"); + yield return new TestCaseData(UnsealedClass2, WinRTRules.UnsealedClassRule).SetName("Unsealed class private field"); + yield return new TestCaseData(GenericClass, WinRTRules.GenericTypeRule).SetName("Class marked generic"); + yield return new TestCaseData(GenericInterface, WinRTRules.GenericTypeRule).SetName("Interface marked generic"); + + // Enumerable + yield return new TestCaseData(InterfaceWithGenericEnumerableReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Enumerable method return type, interface"); + yield return new TestCaseData(InterfaceWithGenericEnumerableInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Enumerable method parameter, interface"); + yield return new TestCaseData(ClassWithGenericEnumerableReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Enumerable method return type, class"); + yield return new TestCaseData(ClassWithGenericEnumerableInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Enumerable method parameter, class"); + yield return new TestCaseData(IfaceWithGenEnumerableProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Enumerable property, interface"); + yield return new TestCaseData(ClassWithGenEnumerableProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Enumerable property, class"); + + // KeyValuePair + yield return new TestCaseData(ClassWithGenericKVPairReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. KeyValuePair<> method return type, class"); + yield return new TestCaseData(ClassWithGenericKVPairInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. KeyValuePair<> method parameter, class"); + yield return new TestCaseData(ClassWithGenKVPairProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. KeyValuePair<> property, class "); + yield return new TestCaseData(IfaceWithGenKVPairProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. KeyValuePair<> property, interface "); + yield return new TestCaseData(InterfaceWithGenericKVPairReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. KeyValuePair<> method return type, interface "); + yield return new TestCaseData(InterfaceWithGenericKVPairInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. KeyValuePair<> method parameter, interface "); + + // readonlydict + yield return new TestCaseData(ClassWithGenericRODictReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. ReadOnlyDictionary<> method return type, class"); + yield return new TestCaseData(InterfaceWithGenericRODictReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. ReadOnlyDictionary<> method return type, interface"); + yield return new TestCaseData(InterfaceWithGenericRODictInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. ReadOnlyDictionary<> method parameter, interface"); + yield return new TestCaseData(ClassWithGenericRODictInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. ReadOnlyDictionary<> method parameter, class"); + yield return new TestCaseData(IfaceWithGenRODictProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. ReadOnlyDictionary<> method property, interface"); + yield return new TestCaseData(ClassWithGenRODictProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. ReadOnlyDictionary<> method property, class"); + + // dict + yield return new TestCaseData(IfaceWithGenDictProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Dictionary<> property, interface "); + yield return new TestCaseData(ClassWithGenDictProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Dictionary<> property, class "); + yield return new TestCaseData(ClassWithGenericDictInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Dictionary<> method parameter, class"); + yield return new TestCaseData(InterfaceWithGenericDictInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Dictionary<> method parameter, interface "); + yield return new TestCaseData(ClassWithGenericDictReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Dictionary<> method return type, class "); + yield return new TestCaseData(InterfaceWithGenericDictReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. Dictionary<> method return type, interface "); + + // list + yield return new TestCaseData(InterfaceWithGenericListReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. List<> method return type, interface"); + yield return new TestCaseData(ClassWithGenericListReturnType, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. List<> method return type, class"); + yield return new TestCaseData(InterfaceWithGenericListInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. List<> method parameter, interface"); + yield return new TestCaseData(ClassWithGenericListInput, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. List<> method parameter, class"); + yield return new TestCaseData(IfaceWithGenListProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. List<> property, interface"); + yield return new TestCaseData(ClassWithGenListProp, WinRTRules.UnsupportedTypeRule).SetName("NotValidType. List<> property, class"); + + // multi-dimensional array tests + yield return new TestCaseData(MultiDim_2DProp, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. 2D Property"); + yield return new TestCaseData(MultiDim_3DProp, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. 3D Property"); + yield return new TestCaseData(MultiDim_3DProp_Whitespace, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. 3D Property With whitespace"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod1, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. return type, class method signature"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod2, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. return and first input, class method signature"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod3, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. return and second input, class method signature"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod4, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. second input, class method signature"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod5, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. second of three inputs, class method signature"); + yield return new TestCaseData(MultiDim_2D_PublicClassPublicMethod6, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. return and second of three inputs, class method signature"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod1, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. return type, class method signature"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod2, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. return and first input, class method signature"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod3, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. return and second input, class method signature"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod4, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. second input, class method signature"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod5, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. second of three inputs, class method signature"); + yield return new TestCaseData(MultiDim_3D_PublicClassPublicMethod6, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. return and second of three inputs, class method signature"); + yield return new TestCaseData(MultiDim_2D_Interface1, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. return type, interface method signature"); + yield return new TestCaseData(MultiDim_2D_Interface2, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. return and first input, interface method signature"); + yield return new TestCaseData(MultiDim_2D_Interface3, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. return and second input, interface method signature"); + yield return new TestCaseData(MultiDim_2D_Interface4, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. second input, interface method signature"); + yield return new TestCaseData(MultiDim_2D_Interface5, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. second of three inputs, interface method signature"); + yield return new TestCaseData(MultiDim_2D_Interface6, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,]. return and second of three inputs, interface method signature"); + yield return new TestCaseData(MultiDim_3D_Interface1, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. return type, interface method signature"); + yield return new TestCaseData(MultiDim_3D_Interface2, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. return and first input, interface method signature"); + yield return new TestCaseData(MultiDim_3D_Interface3, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. return and second input, interface method signature"); + yield return new TestCaseData(MultiDim_3D_Interface4, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. second input, interface method signature"); + yield return new TestCaseData(MultiDim_3D_Interface5, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. second of three inputs, interface method signature"); + yield return new TestCaseData(MultiDim_3D_Interface6, WinRTRules.MultiDimensionalArrayRule).SetName("Array [,,]. return and second of three inputs, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D2Method1, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,] return type, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D2Method2, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,] return and first input, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D2Method3, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,] return and second input, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D2Method4, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,] second input, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D2Method5, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,] second of three inputs, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D2Method6, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,] return and second of three inputs, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D3Method1, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,,] return type, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D3Method2, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,,] return and first input, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D3Method3, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,,] return and second input, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D3Method4, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,,] second input, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D3Method5, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,,] second of three inputs, interface method signature"); + yield return new TestCaseData(SubNamespaceInterface_D3Method6, WinRTRules.MultiDimensionalArrayRule) .SetName("Subnamespace. Array [,,] return and second of three inputs, interface method signature"); + + #region JaggedArray + // jagged array tests + yield return new TestCaseData(Jagged2D_Property2, WinRTRules.JaggedArrayRule).SetName("Array [][]. Property 2"); + yield return new TestCaseData(Jagged3D_Property1, WinRTRules.JaggedArrayRule).SetName("Array [][][]. Property 1"); + yield return new TestCaseData(Jagged2D_ClassMethod1, WinRTRules.JaggedArrayRule).SetName("Array [][]. return type, class method signature"); + yield return new TestCaseData(Jagged2D_ClassMethod2, WinRTRules.JaggedArrayRule).SetName("Array [][]. return and first input, class method signature"); + yield return new TestCaseData(Jagged2D_ClassMethod3, WinRTRules.JaggedArrayRule).SetName("Array [][]. return and second input, class method signature"); + yield return new TestCaseData(Jagged2D_ClassMethod4, WinRTRules.JaggedArrayRule).SetName("Array [][]. second input, class method signature"); + yield return new TestCaseData(Jagged2D_ClassMethod5, WinRTRules.JaggedArrayRule).SetName("Array [][]. second of three inputs, class method signature"); + yield return new TestCaseData(Jagged2D_ClassMethod6, WinRTRules.JaggedArrayRule).SetName("Array [][]. return and second of three inputs, class method signature"); + yield return new TestCaseData(Jagged3D_ClassMethod1, WinRTRules.JaggedArrayRule).SetName("Array [][][]. return type, class method signature"); + yield return new TestCaseData(Jagged3D_ClassMethod2, WinRTRules.JaggedArrayRule).SetName("Array [][][]. return and first input, class method signature"); + yield return new TestCaseData(Jagged3D_ClassMethod3, WinRTRules.JaggedArrayRule).SetName("Array [][][]. return and second input, class method signature"); + yield return new TestCaseData(Jagged3D_ClassMethod4, WinRTRules.JaggedArrayRule).SetName("Array [][][]. second input, class method signature"); + yield return new TestCaseData(Jagged3D_ClassMethod5, WinRTRules.JaggedArrayRule).SetName("Array [][][]. second of three inputs, class method signature"); + yield return new TestCaseData(Jagged3D_ClassMethod6, WinRTRules.JaggedArrayRule).SetName("Array [][][]. return and second of three inputs, class method signature"); + yield return new TestCaseData(Jagged2D_InterfaceMethod1, WinRTRules.JaggedArrayRule).SetName("Array [][]. return type, interface method signature"); + yield return new TestCaseData(Jagged2D_InterfaceMethod2, WinRTRules.JaggedArrayRule).SetName("Array [][]. return and first input, interface method signature"); + yield return new TestCaseData(Jagged2D_InterfaceMethod3, WinRTRules.JaggedArrayRule).SetName("Array [][]. return and second input, interface method signature"); + yield return new TestCaseData(Jagged2D_InterfaceMethod4, WinRTRules.JaggedArrayRule).SetName("Array [][]. second input, interface method signature"); + yield return new TestCaseData(Jagged2D_InterfaceMethod5, WinRTRules.JaggedArrayRule).SetName("Array [][]. second of three inputs, interface method signature"); + yield return new TestCaseData(Jagged2D_InterfaceMethod6, WinRTRules.JaggedArrayRule).SetName("Array [][]. return and second of three inputs, interface method signature"); + yield return new TestCaseData(Jagged3D_InterfaceMethod1, WinRTRules.JaggedArrayRule).SetName("Array [][][]. return type, interface method signature"); + yield return new TestCaseData(Jagged3D_InterfaceMethod2, WinRTRules.JaggedArrayRule).SetName("Array [][][]. return and first input, interface method signature"); + yield return new TestCaseData(Jagged3D_InterfaceMethod3, WinRTRules.JaggedArrayRule).SetName("Array [][][]. return and second input, interface method signature"); + yield return new TestCaseData(Jagged3D_InterfaceMethod4, WinRTRules.JaggedArrayRule).SetName("Array [][][]. second input, interface method signature"); + yield return new TestCaseData(Jagged3D_InterfaceMethod5, WinRTRules.JaggedArrayRule).SetName("Array [][][]. second of three inputs, interface method signature"); + yield return new TestCaseData(Jagged3D_InterfaceMethod6, WinRTRules.JaggedArrayRule).SetName("Array [][][]. return and second of three inputs, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface1, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][]. return type, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface2, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][]. return and first input, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface3, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][]. return and second input, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface4, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][]. second input, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface5, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][]. second of three inputs, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged2DInterface6, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][]. return and second of three inputs, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface1, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][][]. return type, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface2, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][][]. return and first input, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface3, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][][]. return and second input, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface4, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][][]. second input, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface5, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][][]. second of three inputs, interface method signature"); + yield return new TestCaseData(SubNamespace_Jagged3DInterface6, WinRTRules.JaggedArrayRule).SetName("Subnamespace. Array [][][]. return and second of three inputs, interface method signature"); + #endregion + + #region overload_attribute_tests + yield return new TestCaseData(InterfaceWithOverloadNoAttribute, WinRTRules.NeedDefaultOverloadAttribute).SetName("DefaultOverload. Need attribute - Interface"); + yield return new TestCaseData(InterfaceWithOverloadAttributeTwice, WinRTRules.MultipleDefaultOverloadAttribute).SetName("DefaultOverload. Interface has too many attributes"); + yield return new TestCaseData(TwoOverloads_NoAttribute_NamesHaveNumber, WinRTRules.NeedDefaultOverloadAttribute) .SetName("DefaultOverload. Need attribute - Name has number"); + yield return new TestCaseData(TwoOverloads_NoAttribute, WinRTRules.NeedDefaultOverloadAttribute) .SetName("DefaultOverload. Need Attribute, unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInList_Unqualified, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, after attribute - unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInList_Unqualified, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes - Unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_TwoLists_Unqualified, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, two lists - unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInSeparateList_OneNot_Unqualified, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, one in separate list, one not - Unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInSeparateList_Unqualified, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, both in separate list - unqualified"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_Unqualified, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes - unqualified"); + yield return new TestCaseData(ThreeOverloads_TwoAttributes_Unqualified, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, three overlodas - unqualified"); + + yield return new TestCaseData(TwoOverloads_NoAttribute_NamesHaveNumber, WinRTRules.NeedDefaultOverloadAttribute) .SetName("DefaultOverload. Need Attribute - Name has number"); + yield return new TestCaseData(TwoOverloads_NoAttribute_OneIrrevAttr, WinRTRules.NeedDefaultOverloadAttribute) .SetName("DefaultOverload. Need attribute uses irrelevant attribute"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInList, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, after attribute"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInList, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, same list"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_TwoLists, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, two lists"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_OneInSeparateList_OneNot, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, one in separate list, one not"); + yield return new TestCaseData(TwoOverloads_TwoAttribute_BothInSeparateList, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, both in separate list"); + yield return new TestCaseData(TwoOverloads_TwoAttribute, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes"); + yield return new TestCaseData(ThreeOverloads_TwoAttributes, WinRTRules.MultipleDefaultOverloadAttribute) .SetName("DefaultOverload. Multiple attributes, three overlodas"); + + #endregion + + // multiple class constructors of same arity + yield return new TestCaseData(ConstructorsOfSameArity, WinRTRules.ClassConstructorRule).SetName("Misc. Multiple constructors of same arity"); + + #region InvalidInterfaceInheritance + yield return new TestCaseData(ClassInheritsException, WinRTRules.NonWinRTInterface).SetName("Inheritance. Class base type System.Exception"); + // implementing async interface + yield return new TestCaseData(ClassImplementsAsyncAndException, WinRTRules.NonWinRTInterface).SetName("Inheritance. Class implements Exception and IAsyncActionWithProgress"); + yield return new TestCaseData(ClassImplementsIAsyncActionWithProgress, WinRTRules.NonWinRTInterface).SetName("Inheritance. Class implements IAsyncActionWithProgress"); + yield return new TestCaseData(ClassImplementsIAsyncActionWithProgress_Qualified, WinRTRules.NonWinRTInterface).SetName("Inheritance. Qualified, class implements IAsyncActionWithProgress"); + yield return new TestCaseData(InterfaceImplementsIAsyncActionWithProgress, WinRTRules.NonWinRTInterface).SetName("Inheritance. Interface Implements IAsyncActionWithProgress"); + yield return new TestCaseData(InterfaceImplementsIAsyncActionWithProgress2, WinRTRules.NonWinRTInterface).SetName("Inheritance. Interface Implements IAsyncActionWithProgress in full"); + + yield return new TestCaseData(ClassImplementsIAsyncAction, WinRTRules.NonWinRTInterface).SetName("Inheritance. Class implements IAsyncAction"); + yield return new TestCaseData(InterfaceImplementsIAsyncAction, WinRTRules.NonWinRTInterface).SetName("Inheritance. Interface Implements IAsyncAction"); + yield return new TestCaseData(InterfaceImplementsIAsyncAction2, WinRTRules.NonWinRTInterface).SetName("Inheritance. Interface Implements IAsyncAction in full"); + + yield return new TestCaseData(ClassImplementsIAsyncOperation, WinRTRules.NonWinRTInterface).SetName("Inheritance. Class implements IAsyncOperation"); + yield return new TestCaseData(InterfaceImplementsIAsyncOperation, WinRTRules.NonWinRTInterface).SetName("Inheritance. Interface implements IAsyncOperation"); + yield return new TestCaseData(InterfaceImplementsIAsyncOperation2, WinRTRules.NonWinRTInterface).SetName("Inheritance. Interface Implements IAsyncOperation in full"); + + yield return new TestCaseData(ClassImplementsIAsyncOperationWithProgress, WinRTRules.NonWinRTInterface).SetName("Inheritance. Class implements IAsyncOperationWithProgress"); + yield return new TestCaseData(InterfaceImplementsIAsyncOperationWithProgress, WinRTRules.NonWinRTInterface).SetName("Inheritance. Interface Implements IAsyncOperationWithProgress"); + yield return new TestCaseData(InterfaceImplementsIAsyncOperationWithProgress2, WinRTRules.NonWinRTInterface).SetName("Inheritance. Interface Implements IAsyncOperationWithProgress in full"); + + #endregion + + #region InOutAttribute + yield return new TestCaseData(ArrayParamAttrUnary_4, WinRTRules.ArrayMarkedInOrOut).SetName("InOutAttribute. Array parameter marked [In]"); + yield return new TestCaseData(ArrayParamAttrUnary_5, WinRTRules.ArrayMarkedInOrOut).SetName("InOutAttribute. Array parameter marked [Out]"); + yield return new TestCaseData(ArrayParamAttrUnary_8, WinRTRules.NonArrayMarkedInOrOut).SetName("InOutAttribute. Non-array parameter marked [In] - unqualified"); + yield return new TestCaseData(ArrayParamAttrUnary_9, WinRTRules.NonArrayMarkedInOrOut).SetName("InOutAttribute. Non-array parameter marked [Out]"); + yield return new TestCaseData(ArrayParamAttrUnary_11, WinRTRules.NonArrayMarkedInOrOut).SetName("InOutAttribute. Non-array parameter marked [In]"); + yield return new TestCaseData(ArrayParamAttrUnary_12, WinRTRules.NonArrayMarkedInOrOut).SetName("InOutAttribute. TestArrayParamAttrUnary_12"); + yield return new TestCaseData(ArrayParamAttrUnary_13, WinRTRules.ArrayMarkedInOrOut).SetName("InOutAttribute. TestArrayParamAttrUnary_13"); + yield return new TestCaseData(ArrayParamAttrUnary_14, WinRTRules.ArrayMarkedInOrOut).SetName("InOutAttribute. TestArrayParamAttrUnary_14"); + yield return new TestCaseData(ArrayParamAttrBinary_4, WinRTRules.ArrayMarkedInOrOut).SetName("InOutAttribute. TestArrayParamAttrBinary_4"); + yield return new TestCaseData(ArrayParamAttrBinary_5, WinRTRules.ArrayMarkedInOrOut).SetName("InOutAttribute. TestArrayParamAttrBinary_5"); + yield return new TestCaseData(ArrayParamAttrBinary_8, WinRTRules.NonArrayMarkedInOrOut).SetName("InOutAttribute. TestArrayParamAttrBinary_8"); + yield return new TestCaseData(ArrayParamAttrBinary_9, WinRTRules.NonArrayMarkedInOrOut).SetName("InOutAttribute. TestArrayParamAttrBinary_9"); + yield return new TestCaseData(ArrayParamAttrBinary_14, WinRTRules.ArrayMarkedInOrOut).SetName("InOutAttribute. TestArrayParamAttrBinary_14"); + yield return new TestCaseData(ArrayParamAttrBinary_15, WinRTRules.ArrayMarkedInOrOut).SetName("InOutAttribute. Array marked [In] - second parameter"); + yield return new TestCaseData(ArrayParamAttrBinary_16, WinRTRules.ArrayMarkedInOrOut).SetName("InOutAttribute. Array marked [Out] - second parameter"); + yield return new TestCaseData(ArrayParamAttrBinary_21, WinRTRules.NonArrayMarkedInOrOut).SetName("InOutAttribute. Non array marked [In], with marked array"); + yield return new TestCaseData(ArrayParamAttrBinary_22, WinRTRules.NonArrayMarkedInOrOut).SetName("InOutAttribute. Non array marked [Out], with marked array, reverse"); + yield return new TestCaseData(ArrayParamAttrBinary_23, WinRTRules.NonArrayMarkedInOrOut).SetName("InOutAttribute. Non array marked [Out], with marked array"); + #endregion + + #region ArrayAccessAttribute + yield return new TestCaseData(ArrayParamAttrUnary_1, WinRTRules.ArrayParamMarkedBoth).SetName("ArrayAttribute. Both marked, separate lists"); + yield return new TestCaseData(ArrayParamAttrUnary_2, WinRTRules.ArrayParamMarkedBoth).SetName("ArrayAttribute. Both marked, same list"); + yield return new TestCaseData(ArrayParamAttrUnary_3, WinRTRules.ArrayOutputParamMarkedRead).SetName("ArrayAttribute. ReadOnlyArray attribute on array out parameter"); + yield return new TestCaseData(ArrayParamAttrUnary_6, WinRTRules.NonArrayMarked).SetName("ArrayAttribute. Non-array parameter marked ReadOnlyArray"); + yield return new TestCaseData(ArrayParamAttrUnary_7, WinRTRules.NonArrayMarked).SetName("ArrayAttribute. Non-array parameter marked WriteOnlyArray"); + yield return new TestCaseData(ArrayParamAttrUnary_10, WinRTRules.ArrayParamNotMarked).SetName("ArrayAttribute. Array parameter not marked ReadOnlyArray or WriteOnlyArray"); + yield return new TestCaseData(ArrayParamAttrBinary_1, WinRTRules.ArrayParamMarkedBoth).SetName("ArrayAttribute. Both marked, second parameter, same list"); + yield return new TestCaseData(ArrayParamAttrBinary_2, WinRTRules.ArrayParamMarkedBoth).SetName("ArrayAttribute. Both marked, second parameter, separate list"); + yield return new TestCaseData(ArrayParamAttrBinary_3, WinRTRules.ArrayOutputParamMarkedRead).SetName("ArrayAttribute. Array `out` var marked ReadOnly"); + yield return new TestCaseData(ArrayParamAttrBinary_6, WinRTRules.NonArrayMarked).SetName("ArrayAttribute. Non-array parameter marked ReadOnly, second argument"); + yield return new TestCaseData(ArrayParamAttrBinary_7, WinRTRules.NonArrayMarked).SetName("ArrayAttribute. Non-array parameter marked WriteOnly, second argument"); + yield return new TestCaseData(ArrayParamAttrBinary_10, WinRTRules.ArrayParamNotMarked).SetName("ArrayAttribute. Array not marked, second argument"); + yield return new TestCaseData(ArrayParamAttrBinary_11, WinRTRules.ArrayParamMarkedBoth).SetName("ArrayAttribute. Marked both, second array"); + yield return new TestCaseData(ArrayParamAttrBinary_12, WinRTRules.ArrayParamMarkedBoth).SetName("ArrayAttribute. Marked both, first array"); + yield return new TestCaseData(ArrayParamAttrBinary_13, WinRTRules.ArrayOutputParamMarkedRead).SetName("ArrayAttribute. Marked out and read only, second argument"); + yield return new TestCaseData(ArrayParamAttrBinary_17, WinRTRules.ArrayParamNotMarked).SetName("ArrayAttribute. Array not marked - second argument"); + yield return new TestCaseData(ArrayParamAttrBinary_18, WinRTRules.NonArrayMarked).SetName("ArrayAttribute. Non array marked ReadOnlyArray"); + yield return new TestCaseData(ArrayParamAttrBinary_19, WinRTRules.NonArrayMarked).SetName("ArrayAttribute. Non array marked WriteOnlyArray"); + yield return new TestCaseData(ArrayParamAttrBinary_20, WinRTRules.NonArrayMarked).SetName("ArrayAttribute. Non array marked [In], with marked array, reverse"); + yield return new TestCaseData(ArrayParamAttrBinary_24, WinRTRules.ArrayParamNotMarked).SetName("ArrayAttribute. Array missing attribute"); + #endregion + + // name clash with params (__retval) + yield return new TestCaseData(DunderRetValParam, WinRTRules.ParameterNamedValueRule).SetName("Misc. Parameter Name Conflict (__retval)"); + // operator overloading + yield return new TestCaseData(OperatorOverload_Class, WinRTRules.OperatorOverloadedRule).SetName("Misc. Overload of Operator"); + // ref param + yield return new TestCaseData(RefParam_ClassMethod, WinRTRules.RefParameterFound).SetName("Misc. Class Method With Ref Param"); + yield return new TestCaseData(RefParam_InterfaceMethod, WinRTRules.RefParameterFound).SetName("Misc. Interface Method With Ref Param"); + + #region struct_field_tests + yield return new TestCaseData(EmptyStruct, WinRTRules.StructWithNoFieldsRule).SetName("Struct. Empty struct"); + yield return new TestCaseData(StructWithInterfaceField, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Interface field"); + yield return new TestCaseData(StructWithClassField, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Class Field"); + yield return new TestCaseData(StructWithClassField2, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Class Field2"); + yield return new TestCaseData(StructWithDelegateField, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Delegate Field"); + yield return new TestCaseData(StructWithIndexer, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Indexer Field"); + yield return new TestCaseData(StructWithMethods, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Method Field"); + yield return new TestCaseData(StructWithConst, WinRTRules.StructHasConstFieldRule).SetName("Struct. with Const Field"); + yield return new TestCaseData(StructWithProperty, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Property Field"); + yield return new TestCaseData(StructWithPrivateField, WinRTRules.StructHasPrivateFieldRule).SetName("Struct. with Private Field"); + yield return new TestCaseData(StructWithObjectField, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Object Field"); + yield return new TestCaseData(StructWithDynamicField, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Dynamic Field"); + yield return new TestCaseData(StructWithConstructor, WinRTRules.StructHasInvalidFieldRule).SetName("Struct. with Constructor Field"); + yield return new TestCaseData(StructWithPrimitiveTypesMissingPublicKeyword, WinRTRules.StructHasPrivateFieldRule).SetName("Struct. with missing public field"); + #endregion + + #region InvalidType + // system.array tests + yield return new TestCaseData(ArrayInstanceProperty1, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array property"); + yield return new TestCaseData(ArrayInstanceProperty2, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array property 2"); + yield return new TestCaseData(SystemArrayProperty5, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array property 3"); + yield return new TestCaseData(ArrayInstanceInterface1, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array interface method return type and input"); + yield return new TestCaseData(ArrayInstanceInterface2, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array interface method input"); + yield return new TestCaseData(ArrayInstanceInterface3, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array interface method return type"); + yield return new TestCaseData(SystemArrayJustReturn, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array class method return type "); + yield return new TestCaseData(SystemArrayUnaryAndReturn, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array class method return and input"); + yield return new TestCaseData(SystemArraySecondArgClass, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array class method - Arg 2/2"); + yield return new TestCaseData(SystemArraySecondArg2Class, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array class method - Arg 2/3"); + yield return new TestCaseData(SystemArraySecondArgAndReturnTypeClass, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array class method second input and return type"); + yield return new TestCaseData(SystemArraySecondArgAndReturnTypeClass2, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array class method second input and return type 2"); + yield return new TestCaseData(SystemArraySecondArgAndReturnTypeInterface, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array second argument and return type"); + yield return new TestCaseData(SystemArraySecondArgAndReturnTypeInterface2, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array Interface 2nd of 3 and return type"); + yield return new TestCaseData(SystemArraySecondArgInterface, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array Interface 2nd of 2 arguments"); + yield return new TestCaseData(SystemArraySecondArgInterface2, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array Interface 2nd of 3 arguments"); + yield return new TestCaseData(SystemArraySubNamespace_ReturnOnly, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array Subnamespace Interface return only"); + yield return new TestCaseData(SystemArraySubNamespace_ReturnAndInput1, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array Subnamespace Interface return and only input"); + yield return new TestCaseData(SystemArraySubNamespace_ReturnAndInput2of2, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array Subnamespace Interface return type and 2nd arg of 2"); + yield return new TestCaseData(SystemArraySubNamespace_ReturnAndInput2of3, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array Subnamespace Interface return type and 2nd arg of 3rd"); + yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of2, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array Subnamespace 2nd arg of two"); + yield return new TestCaseData(SystemArraySubNamespace_NotReturnAndInput2of3, WinRTRules.UnsupportedTypeRule).SetName("InvalidType. System Array Subnamespace 2nd arg of third"); + #endregion + } + } + + #endregion + + #region ValidTests + + private static IEnumerable ValidCases + { + get + { + yield return new TestCaseData(Valid_RollYourOwnAsyncAction).SetName("Valid. AsyncInterfaces. Implementing your own IAsyncAction"); + yield return new TestCaseData(Valid_CustomDictionary).SetName("Valid. CustomProjection. IDictionary"); + yield return new TestCaseData(Valid_CustomList).SetName("Valid. CustomProjection. IList"); + yield return new TestCaseData(Valid_TwoNamespacesSameName).SetName("Valid. Namespaces with same name"); + yield return new TestCaseData(Valid_NestedNamespace).SetName("Valid. Nested namespaces are fine"); + yield return new TestCaseData(Valid_NestedNamespace2).SetName("Valid. Twice nested namespaces are fine"); + yield return new TestCaseData(Valid_NestedNamespace3).SetName("Valid. Namespace. Test[dot]Component with an inner namespace InnerComponent"); + yield return new TestCaseData(Valid_NestedNamespace4).SetName("Valid. Namespace. Test and Test[dot]Component namespaces, latter with an inner namespace"); + yield return new TestCaseData(Valid_NestedNamespace5).SetName("Valid. Namespace. ABCType in ABwinmd"); + yield return new TestCaseData(Valid_NamespacesDiffer).SetName("Valid. Similar namespace but different name (not just case)"); + yield return new TestCaseData(Valid_NamespaceAndPrefixedNamespace).SetName("Valid. Two top-level namespaces, one prefixed with the other"); + + #region InvalidTypes_Signatures + yield return new TestCaseData(Valid_ListUsage).SetName("Valid. Internally uses List<>"); + yield return new TestCaseData(Valid_ListUsage2).SetName("Valid. Internally uses List<> (qualified)"); + yield return new TestCaseData(Valid_ClassWithGenericDictReturnType_Private).SetName("Valid. Dictionary<> Private Method - ReturnType"); + yield return new TestCaseData(Valid_ClassWithGenericDictInput_Private).SetName("Valid. Dictionary<> Private Method - parameter"); + yield return new TestCaseData(Valid_ClassWithPrivateGenDictProp).SetName("Valid. Dictionary<> Private Property Class"); + yield return new TestCaseData(Valid_IfaceWithPrivateGenDictProp).SetName("Valid. Dictionary<> Private Property Interface"); + + yield return new TestCaseData(Valid_ClassWithGenericRODictInput_Private).SetName("Valid. ReadOnlyDictionary<> Private Method ReturnType"); + yield return new TestCaseData(Valid_ClassWithGenericRODictReturnType_Private).SetName("Valid. ReadOnlyDictionary<> Private Method parameter"); + yield return new TestCaseData(Valid_ClassWithPrivateGenRODictProp).SetName("Valid. ReadOnlyDictionary<> Private Property Class"); + yield return new TestCaseData(Valid_IfaceWithPrivateGenRODictProp).SetName("Valid. ReadOnlyDictionary<> Private Property Interface"); + + yield return new TestCaseData(Valid_InterfaceWithGenericKVPairReturnType).SetName("Valid. KeyValuePair<> as return type of signature in interface"); + yield return new TestCaseData(Valid_InterfaceWithGenericKVPairInput).SetName("Valid. KeyValuePair<> interface with Generic KeyValuePair parameter"); + yield return new TestCaseData(Valid_ClassWithGenericKVPairReturnType).SetName("Valid. KeyValuePair<> class with Generic KeyValuePair return type"); + yield return new TestCaseData(Valid_ClassWithGenericKVPairInput).SetName("Valid. KeyValuePair<> class with Generic KeyValuePair parameter"); + yield return new TestCaseData(Valid_IfaceWithGenKVPairProp).SetName("Valid. KeyValuePair<> interface with Generic KeyValuePair property"); + yield return new TestCaseData(Valid_ClassWithGenKVPairProp).SetName("Valid. KeyValuePair<> class with Generic KeyValuePair return property"); + + yield return new TestCaseData(Valid_ClassWithGenericKVPairInput_Private).SetName("Valid. KeyValuePair<> as parameter to private method"); + yield return new TestCaseData(Valid_ClassWithGenericKVPairReturnType_Private).SetName("Valid. KeyValuePair<> as return type of private method"); + yield return new TestCaseData(Valid_ClassWithPrivateGenKVPairProp).SetName("Valid. KeyValuePair<> as private prop to class"); + yield return new TestCaseData(Valid_IfaceWithPrivateGenKVPairProp).SetName("Valid. KeyValuePair<> as private prop to interface"); + + yield return new TestCaseData(Valid_ClassWithGenericEnumerableInput_Private).SetName("Valid. Enumerable as parameter to private method"); + yield return new TestCaseData(Valid_ClassWithGenericEnumerableReturnType_Private).SetName("Valid. Enumerable as return type of private method"); + yield return new TestCaseData(Valid_ClassWithPrivateGenEnumerableProp).SetName("Valid. Enumerable as private prop to class"); + yield return new TestCaseData(Valid_IfaceWithPrivateGenEnumerableProp).SetName("Valid. Enumerable as private prop to interface"); + + yield return new TestCaseData(Valid_ClassWithGenericListInput_Private).SetName("Valid. List<> as parameter to private method"); + yield return new TestCaseData(Valid_ClassWithGenericListReturnType_Private).SetName("Valid. List<> as return type of private method"); + yield return new TestCaseData(Valid_ClassWithPrivateGenListProp).SetName("Valid. List<> as private prop to class"); + yield return new TestCaseData(Valid_IfaceWithPrivateGenListProp).SetName("Valid. List<> as private prop to interface"); + + #endregion + + #region ArrayAccessAttribute + // ReadOnlyArray / WriteOnlyArray Attribute + yield return new TestCaseData(Valid_ArrayParamAttrUnary_1).SetName("Valid. ArrayAttribute, Array marked read only"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_2).SetName("Valid. ArrayAttribute, Array marked write only"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_3).SetName("Valid. ArrayAttribute, Array marked out and write only"); + yield return new TestCaseData(Valid_ArrayParamAttrUnary_4).SetName("Valid. ArrayAttribute, Array marked out"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_1).SetName("Valid. ArrayAttribute, Array marked read only, second parameter"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_2).SetName("Valid. ArrayAttribute, Array marked write only, second parameter"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_3).SetName("Valid. ArrayAttribute, Array marked write only and out, second parameter"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_4).SetName("Valid. ArrayAttribute, Array marked out, second parameter"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_5).SetName("Valid. ArrayAttribute, Two arrays, both marked read"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_6).SetName("Valid. ArrayAttribute, Two arrays, one marked read, one marked write"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_7).SetName("Valid. ArrayAttribute, Two arrays, one marked read, one marked write and out"); + yield return new TestCaseData(Valid_ArrayParamAttrBinary_8).SetName("Valid. ArrayAttribute, Two arrays, one marked write, one marked out"); + + #endregion + + #region StructField + yield return new TestCaseData(Valid_StructWithByteField).SetName("Valid. struct with byte field"); + yield return new TestCaseData(Valid_StructWithPrimitiveTypes).SetName("Valid. Struct with only fields of basic types"); + yield return new TestCaseData(Valid_StructWithImportedStruct).SetName("Valid. Struct with struct field"); + yield return new TestCaseData(Valid_StructWithImportedStructQualified).SetName("Valid. Struct with qualified struct field"); + #endregion + + #region InvalidArrayTypes_Signatures + + // SystemArray + yield return new TestCaseData(Valid_SystemArrayProperty).SetName("Valid. SystemArray private property"); + yield return new TestCaseData(Valid_SystemArray_Interface1).SetName("Valid. System Array internal interface 1"); + yield return new TestCaseData(Valid_SystemArray_Interface2).SetName("Valid. System Array internal interface 2"); + yield return new TestCaseData(Valid_SystemArray_Interface3).SetName("Valid. System Array internal interface 3"); + yield return new TestCaseData(Valid_SystemArray_InternalClass1).SetName("Valid. System Array internal class 1"); + yield return new TestCaseData(Valid_SystemArray_InternalClass2).SetName("Valid. System Array internal class 2"); + yield return new TestCaseData(Valid_SystemArray_InternalClass3).SetName("Valid. System Array internal class 3"); + yield return new TestCaseData(Valid_SystemArray_InternalClass4).SetName("Valid. System Array internal class 4"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty1).SetName("Valid. System Array public class / private property 1"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty2).SetName("Valid. System Array public class / private property 2"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty3).SetName("Valid. System Array public class / private property 3"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty4).SetName("Valid. System Array public class / private property 4"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty5).SetName("Valid. System Array public class / private property 5"); + yield return new TestCaseData(Valid_SystemArray_PublicClassPrivateProperty6).SetName("Valid. System Array public class / private property 6"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods1).SetName("Valid. System Array internal class / public method 1"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods2).SetName("Valid. System Array internal class / public method 2"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods3).SetName("Valid. System Array internal class / public method 3"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods4).SetName("Valid. System Array internal class / public method 4"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods5).SetName("Valid. System Array internal class / public method 5"); + yield return new TestCaseData(Valid_SystemArray_InternalClassPublicMethods6).SetName("Valid. System Array internal class / public method 6"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty1).SetName("Valid. System Array internal class / public property 1"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty2).SetName("Valid. System Array internal class / public property 2"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty3).SetName("Valid. System Array internal class / public property 3"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty4).SetName("Valid. System Array internal class / public property 4"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty5).SetName("Valid. System Array internal class / public property 5"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty6).SetName("Valid. System Array internal class / public property 6"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty7).SetName("Valid. System Array internal class / public property 7"); + yield return new TestCaseData(Valid_SystemArray_PrivateClassPublicProperty8).SetName("Valid. System Array internal class / public property 8"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod1).SetName("Valid. System Array public class / private method 1"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod2).SetName("Valid. System Array public class / private method 2"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod3).SetName("Valid. System Array public class / private method 3"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod4).SetName("Valid. System Array public class / private method 4"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod5).SetName("Valid. System Array public class / private method 5"); + yield return new TestCaseData(Valid_SystemArrayPublicClassPrivateMethod6).SetName("Valid. System Array public class / private method 6"); + // multi dim array tests + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod1).SetName("Valid. array [,] public class / private method 1"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod2).SetName("Valid. array [,] public class / private method 2"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod3).SetName("Valid. array [,] public class / private method 3"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod4).SetName("Valid. array [,] public class / private method 4"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod5).SetName("Valid. array [,,] public class / private method 5"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateMethod6).SetName("Valid. array [,,] public class / private method 6"); + + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod1).SetName("Valid. MultiDim 3D private class / public method 1"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod2).SetName("Valid. MultiDim 3D private class / public method 2"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod3).SetName("Valid. MultiDim 3D private class / public method 3"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod4).SetName("Valid. MultiDim 3D private class / public method 4"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod5).SetName("Valid. MultiDim 3D private class / public method 5"); + yield return new TestCaseData(Valid_3D_PrivateClass_PublicMethod6).SetName("Valid. MultiDim 3D private class / public method 6"); + + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod1).SetName("Valid. MultiDim 2D private class / public method 1"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod2).SetName("Valid. MultiDim 2D private class / public method 2"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod3).SetName("Valid. MultiDim 2D private class / public method 3"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod4).SetName("Valid. MultiDim 2D private class / public method 4"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod5).SetName("Valid. MultiDim 2D private class / public method 5"); + yield return new TestCaseData(Valid_2D_PrivateClass_PublicMethod6).SetName("Valid. MultiDim 2D private class / public method 6"); + + yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty1).SetName("Valid. MultiDim 2D private class / public property 1"); + yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty2).SetName("Valid. MultiDim 2D private class / public property 2"); + yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty3).SetName("Valid. MultiDim 2D private class / public property 3"); + yield return new TestCaseData(Valid_MultiDimArray_PrivateClassPublicProperty4).SetName("Valid. MultiDim 2D private class / public property 4"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateProperty1).SetName("Valid. MultiDim 2D public class / private property 1"); + yield return new TestCaseData(Valid_MultiDimArray_PublicClassPrivateProperty2).SetName("Valid. MultiDim 2D public class / private property 2"); + // jagged array tests + yield return new TestCaseData(Valid_JaggedMix_PrivateClassPublicProperty).SetName("Valid. Jagged Array private class / private property"); + yield return new TestCaseData(Valid_Jagged2D_PrivateClassPublicMethods).SetName("Valid. Jagged Array private class / public method"); + yield return new TestCaseData(Valid_Jagged3D_PrivateClassPublicMethods).SetName("Valid. Jagged Array private class / public method"); + yield return new TestCaseData(Valid_Jagged3D_PublicClassPrivateMethods).SetName("Valid. Jagged Array public class / private method"); + yield return new TestCaseData(Valid_Jagged2D_Property).SetName("Valid. Jagged 2D Array public property"); + yield return new TestCaseData(Valid_Jagged3D_Property).SetName("Valid. Jagged 3D Array public property"); + + #endregion + + #region DefaultOverloadAttribute + + // overload attributes + yield return new TestCaseData(Valid_InterfaceWithOverloadAttribute).SetName("Valid. interface with overloads and one marked as default"); + yield return new TestCaseData(Valid_TwoOverloads_DiffParamCount).SetName("Valid. DefaultOverload attribute 1"); + yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_OneInList).SetName("Valid. DefaultOverload attribute 2"); + yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_OneIrrelevatAttribute).SetName("Valid. DefaultOverload attribute 3"); + yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_TwoLists).SetName("Valid. DefaultOverload attribute 4"); + yield return new TestCaseData(Valid_ThreeOverloads_OneAttribute).SetName("Valid. DefaultOverload attribute 5"); + yield return new TestCaseData(Valid_ThreeOverloads_OneAttribute_2).SetName("Valid. DefaultOverload attribute 6"); + yield return new TestCaseData(Valid_TwoOverloads_OneAttribute_3).SetName("Valid. DefaultOverload attribute 7"); + + #endregion + } + } + + #endregion + + } +} \ No newline at end of file diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs new file mode 100644 index 000000000..3148c7366 --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs @@ -0,0 +1,436 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using WinRT.SourceGenerator; + +namespace Generator +{ + // Helper Class, makes for clean collection of types and namespaces, needed for checking + internal class TypeCollector + { + private HashSet types; + private HashSet structs; + private HashSet namespaces; + + public TypeCollector() + { + types = new HashSet(); + structs = new HashSet(); + namespaces = new HashSet(); + } + + public void AddType(INamedTypeSymbol newType) { types.Add(newType); } + public void AddStruct(INamedTypeSymbol newType) { structs.Add(newType); } + public void AddNamespace(INamespaceSymbol newType) { namespaces.Add(newType); } + + public HashSet GetTypes() { return types; } + public HashSet GetStructs() { return structs; } + public HashSet GetNamespaces() { return namespaces; } + } + + public partial class WinRTComponentScanner + { + private void Flag() { _flag |= true; } + /// Raise the flag so we don't make a winmd, and add a diagnostic to the sourcegenerator + /// + private void Report(DiagnosticDescriptor d, Location loc, params object[] args) + { + Flag(); + _context.ReportDiagnostic(Diagnostic.Create(d, loc, args)); + } + private void ReportDiagnostic(Diagnostic d) + { + Flag(); + _context.ReportDiagnostic(d); + } + private SemanticModel GetModel(SyntaxTree t) { return _context.Compilation.GetSemanticModel(t); } + + private INamedTypeSymbol GetTypeByMetadataName(string fullyQualifiedMetadataName) + { + return _context.Compilation.GetTypeByMetadataName(fullyQualifiedMetadataName); + } + + private bool SymEq(ISymbol sym1, ISymbol sym2) { return SymbolEqualityComparer.Default.Equals(sym1, sym2); } + + /// + /// Returns true if the class represented by the symbol + /// implements any of the interfaces defined in ProhibitedAsyncInterfaces (e.g., IAsyncAction, ...) + /// The class/interface type symbolThe containing class/interface declaration + /// True iff the given class implements any of the IAsync interfaces that are not valid in Windows Runtime + private void ImplementsInvalidInterface(INamedTypeSymbol typeSymbol, TypeDeclarationSyntax typeDeclaration) + { + bool AsyncActionCase(INamedTypeSymbol sym) + { + // using Windows.Foundation.IAsyncAction ? + bool isWindowsFoundation = sym.ContainingNamespace.IsGlobalNamespace || sym.ContainingNamespace.Name == "Windows.Foundation"; + bool isAsyncAction = sym.MetadataName == "IAsyncAction"; + return isWindowsFoundation && isAsyncAction; + } + + if (typeSymbol.BaseType != null && typeSymbol.BaseType.ContainingNamespace != null) + { + if (AsyncActionCase(typeSymbol.BaseType)) + { + Report(WinRTRules.NonWinRTInterface, typeDeclaration.GetLocation(), typeDeclaration.Identifier, "IAsyncAction"); + } + } + + foreach (var implementedInterface in typeSymbol.AllInterfaces) + { + if (AsyncActionCase(implementedInterface)) + { + Report(WinRTRules.NonWinRTInterface, typeDeclaration.GetLocation(), typeDeclaration.Identifier, "IAsyncAction"); + } + } + + foreach (string prohibitedInterface in nonWindowsRuntimeInterfaces) + { + // check here if typesymbol's basetype is invalid ? but interfaces are also base types? + if (ImplementsInterface(typeSymbol, prohibitedInterface)) + { + Report(WinRTRules.NonWinRTInterface, typeDeclaration.GetLocation(), typeDeclaration.Identifier, prohibitedInterface); + } + } + } + + /// + /// See if this class/interfaces inherits the given type + /// + /// type that might inherit + /// Inherited interface or class + private bool ImplementsInterface(INamedTypeSymbol typeSymbol, string typeToCheck) + { + if (typeSymbol == null) + { + return false; + } + + // for interface type symbols + foreach (var implementedInterface in typeSymbol.AllInterfaces) + { + if (implementedInterface.MetadataName == typeToCheck) + { + return true; + } + } + + // class type symbols might have a BaseType, like System.Exception + if (typeSymbol.BaseType != null) + { + foreach (var x in typeSymbol.BaseType.AllInterfaces) + { + if (x.MetadataName == typeToCheck) + { + return true; + } + } + var typeToCheckSymbol = GetTypeByMetadataName(typeToCheck); + if (SymEq(typeSymbol.BaseType, typeToCheckSymbol)) + { + return true; + } + // Type -> Type`n + if (typeSymbol.BaseType.MetadataName != null) + { + return typeSymbol.BaseType.MetadataName == typeToCheck; + } + } + + return false; + } + + private bool IsPublic(MemberDeclarationSyntax member) { return member.Modifiers.Where(m => m.IsKind(SyntaxKind.PublicKeyword)).Any(); } + + #region Attributes + + /// Attributes can come in one list or many, e.g. [A(),B()] vs. [A()][B()] + /// look at all possible attributes and see if any match the given string + /// attribute names need to be fully qualified, e.g. DefaultOverload is really Windows.Foundation.Metadata.DefaultOverload + /// all the syntax nodes that correspond to an attribute list + /// true iff the given attribute is in the list + private bool MatchesAnyAttribute(string attrName, SyntaxList ls) + { + foreach (var attrList in ls) + { + foreach (var attr in attrList.Attributes) + { + // no declared symbol for AttributeSyntax... + if (attr.Name.ToString() == attrName) + { + return true; + } + } + } + return false; + } + + /// + /// Checks to see if an array parameter has been marked with both Write and Read attributes + /// Does extra work, by catching `ref` params, done here since this code can be used by class or interface related methods + /// Method declared + /// true if array attributes are invalid (see summary) + private void ParameterHasAttributeErrors(MethodDeclarationSyntax method) + { + // helper function, used to see if param has Ref or Out keyword + bool HasModifier(ParameterSyntax param, SyntaxKind kind) { return param.Modifiers.Where(m => m.IsKind(kind)).Any(); } + + foreach (ParameterSyntax param in method.ParameterList.Parameters) + { + var isArrayType = param.Type.IsKind(SyntaxKind.ArrayType); + bool hasReadOnlyArray = ParamHasReadOnlyAttribute(param); + bool hasWriteOnlyArray = ParamHasWriteOnlyAttribute(param); + + // Nothing can be marked `ref` + if (HasModifier(param, SyntaxKind.RefKeyword)) + { + Report(WinRTRules.RefParameterFound, method.GetLocation(), param.Identifier); + } + + if (ParamHasInOrOutAttribute(param)) + { + // recommend using ReadOnlyArray or WriteOnlyArray instead of In/Out + if (isArrayType) + { + Report(WinRTRules.ArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier); + } + // if not array type, stil can't use [In] or [Out] + else + { + Report(WinRTRules.NonArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier); + } + } + + if (isArrayType) + { + bool isOutputParam = HasModifier(param, SyntaxKind.OutKeyword); + // can't be both ReadOnly and WriteOnly + if (hasReadOnlyArray && hasWriteOnlyArray) + { + Report(WinRTRules.ArrayParamMarkedBoth, method.GetLocation(), method.Identifier, param.Identifier); + } + // can't be both output (writeonly) and marked read only + else if (hasReadOnlyArray && isOutputParam) + { + Report(WinRTRules.ArrayOutputParamMarkedRead, method.GetLocation(), method.Identifier, param.Identifier); + } + // must have some indication of ReadOnly or WriteOnly + else if (!hasWriteOnlyArray && !hasReadOnlyArray && !isOutputParam) + { + Report(WinRTRules.ArrayParamNotMarked, method.GetLocation(), method.Identifier, param.Identifier); + } + } + // Non-array types shouldn't have attributes meant for arrays + else if (hasWriteOnlyArray || hasReadOnlyArray) + { + Report(WinRTRules.NonArrayMarked, method.GetLocation(), method.Identifier, param.Identifier); + } + } + } + + /// Looks at all possible attributes on a given parameter declaration + /// returns true iff any are (string) equal to the given attribute name + private bool ParamHasAttribute(ParameterSyntax param, string attrName) { return MatchesAnyAttribute(attrName, param.AttributeLists); } + + /// Check for qualified and unqualified [In] and [Out] attribute on the parameter + /// + /// True if any attribute is the In or Out attribute + private bool ParamHasInOrOutAttribute(ParameterSyntax param) { return InAndOutAttributeNames.Where(str => ParamHasAttribute(param, str)).Any(); } + private bool ParamHasReadOnlyAttribute(ParameterSyntax param) { return ReadOnlyArrayAttributeNames.Where(str => ParamHasAttribute(param, str)).Any(); } + private bool ParamHasWriteOnlyAttribute(ParameterSyntax param) { return WriteOnlyArrayAttributeNames.Where(str => ParamHasAttribute(param, str)).Any(); } + + /// Check for qualified and unqualified [DefaultOverload] attribute on the parameter< + /// + /// True if any attribute is the DefaultOverload attribute + private bool HasDefaultOverloadAttribute(MethodDeclarationSyntax method) { return OverloadAttributeNames.Where(str => MatchesAnyAttribute(str, method.AttributeLists)).Any(); } + + /// + /// Keeps track of repeated declarations of a method (overloads) and raises diagnostics according to the rule that exactly one overload should be attributed the default + /// Look for overloads of this method, checking the attributes as well attributes for + /// + /// The strings are unique names for each method -- made by its name and arity + /// Some methods may get the attribute, some may not, we keep track of this in the map. + /// + /// Once we have seen an overload and the method still has no attribute, we make a diagnostic for it + /// If we see the method again but this time with the attribute, we remove it (and its diagnostic) from the map + /// The class the method lives in -- used for creating the diagnostic + /// True iff multiple overloads of a method are found, where more than one has been designated as the default overload + private void CheckOverloadAttributes(MethodDeclarationSyntax method, + Dictionary methodHasAttributeMap, + Dictionary overloadsWithoutAttributeMap, + SyntaxToken classId) + { + int methodArity = method.ParameterList.Parameters.Count; + string methodNameWithArity = method.Identifier.Text + methodArity; + + // look at all the attributes on this method and see if any of them is the DefaultOverload attribute + bool hasDefaultOverloadAttribute = HasDefaultOverloadAttribute(method); + bool seenMethodBefore = methodHasAttributeMap.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); + + // Do we have an overload ? + if (seenMethodBefore) + { + if (hasDefaultOverloadAttribute && !methodHasAttrAlready) + { + // we've seen it, but it didnt have the attribute, so mark that it has it now + methodHasAttributeMap[methodNameWithArity] = true; + // We finally got an attribute, so dont raise a diagnostic for this method + overloadsWithoutAttributeMap.Remove(methodNameWithArity); + } + else if (hasDefaultOverloadAttribute && methodHasAttrAlready) + { + // Special case in that multiple instances of the DefaultAttribute being used on the method + Report(WinRTRules.MultipleDefaultOverloadAttribute, method.GetLocation(), methodArity, method.Identifier, classId); + } + else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) + { + // we could see this method later with the attribute, + // so hold onto the diagnostic for it until we know it doesn't have the attribute + overloadsWithoutAttributeMap[methodNameWithArity] = Diagnostic.Create( + WinRTRules.NeedDefaultOverloadAttribute, + method.GetLocation(), + methodArity, + method.Identifier, + classId); + } + } + else + { + // first time we're seeing the method, add a pair in the map for its name and whether it has the attribute + methodHasAttributeMap[methodNameWithArity] = hasDefaultOverloadAttribute; + } + } + + #endregion + + /// Gather the type symbols for all classes, interfaces and structs + /// Context used for syntax treesA TypeCollector populated with the type symbols + private TypeCollector CollectDefinedTypes(GeneratorExecutionContext context) + { + TypeCollector collectedTypes = new TypeCollector(); + + foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) + { + var model = context.Compilation.GetSemanticModel(tree); + + var classes = tree.GetRoot().DescendantNodes().OfType().Where(IsPublic); + foreach (var @class in classes) + { + collectedTypes.AddType(model.GetDeclaredSymbol(@class)); + } + + var interfaces = tree.GetRoot().DescendantNodes().OfType().Where(IsPublic); + foreach (var @interface in interfaces) + { + collectedTypes.AddType(model.GetDeclaredSymbol(@interface)); + } + + var structs = tree.GetRoot().DescendantNodes().OfType().Where(IsPublic); + foreach (var @struct in structs) + { + collectedTypes.AddStruct(model.GetDeclaredSymbol(@struct)); + } + + var namespaces = tree.GetRoot().DescendantNodes().OfType(); + foreach (var @namespace in namespaces) + { + collectedTypes.AddNamespace(model.GetDeclaredSymbol(@namespace)); + } + } + return collectedTypes; + } + + /// Make a suggestion for types to use instead of the given type + /// A type that is not valid in Windows Runtime + /// string of types that the given type implements and are valid Windows Runtime types + private string SuggestType(string type) + { + switch (type) + { + case "System.Collections.Generic.Dictionary`2": + return "IDictionary, IReadOnlyDictionary, IEnumerable>"; + case "System.Collections.ObjectModel.ReadOnlyDictionary`2": + return "IReadOnlyDictionary, IEnumerable>, IDictionary"; + case "System.Collections.Generic.List`1": + return "IList, IReadOnlyList, IEnumerable"; + case "System.Linq.Enumerable`1": + return "IEnumerable"; + case "System.Collections.Generic.KeyValuePair": + return "KeyValuePair"; + case "System.Array": + return "T[]"; + default: return "No suggestions for type"; + } + } + + /// + /// the common term for the given syntax type + private string SimplifySyntaxTypeString(string syntaxType) + { + switch (syntaxType) + { + case "EventFieldDeclarationSyntax": return "event"; + case "ConstructorDeclarationSyntax": return "constructor"; + case "DelegateDeclarationSyntax": return "delegate"; + case "IndexerDeclarationSyntax": return "indexer"; + case "MethodDeclarationSyntax": return "method"; + case "OperatorDeclarationSyntax": return "operator"; + case "PropertyDeclarationSyntax": return "property"; + default: return "unknown syntax type: " + syntaxType; + } + } + + private SpecialType[] ValidStructFieldTypes = new SpecialType[] + { + SpecialType.System_Boolean, + SpecialType.System_String, + SpecialType.System_Single, + SpecialType.System_Double, + SpecialType.System_UInt16, + SpecialType.System_UInt32, + SpecialType.System_UInt64, + SpecialType.System_Int16, + SpecialType.System_Int32, + SpecialType.System_Int64, + SpecialType.System_Enum, + }; + + private static readonly HashSet nonWindowsRuntimeInterfaces = new HashSet() + { + "System.Exception", + "IAsyncActionWithProgress`1", + "IAsyncOperation`1", + "IAsyncOperationWithProgress`2", + }; + + private readonly static HashSet NotValidTypes = new HashSet() + { + "System.Array", + "System.Collections.Generic.Dictionary`2", + "System.Collections.Generic.List`1", + "System.Collections.Generic.KeyValuePair" + }; + + private readonly static HashSet WIPNotValidTypes = new HashSet() + { + "System.Linq.Enumerable", + "Enumerable", + "System.Collections.ObjectModel.ReadOnlyDictionary`2", + "ReadOnlyDictionary`2" + }; + + private static readonly HashSet InAndOutAttributeNames = new HashSet() + { "In", "Out", "System.Runtime.InteropServices.In", "System.Runtime.InteropServices.Out" }; + private static readonly HashSet OverloadAttributeNames = new HashSet() + { "DefaultOverload", "Windows.Foundation.Metadata.DefaultOverload" }; + private static readonly HashSet ReadOnlyArrayAttributeNames = new HashSet() + { "System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray", "ReadOnlyArray" }; + private static readonly HashSet WriteOnlyArrayAttributeNames = new HashSet() + { "System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray", "WriteOnlyArray" }; + + private static readonly string GeneratedReturnValueName = "__retval"; + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index 69b235736..ea8665486 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -1,494 +1,400 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System.Collections.Generic; -using System.Linq; -using WinRT.SourceGenerator; - -namespace Generator -{ - public class WinRTRules - { - private void Report(ref GeneratorExecutionContext context, DiagnosticDescriptor d, Location loc, params object[] args) - { - context.ReportDiagnostic(Diagnostic.Create(d, loc, args)); - } - - private bool SymbolSetHasString(HashSet typeNames, string typeStr) - { - return typeNames.Where(sym => sym.ToString().Contains(typeStr)).Any(); - } - - private bool SyntaxTokenIs(SyntaxToken stx, string str) { return stx.Value.Equals(str); } - - private bool ModifiersContains(SyntaxTokenList modifiers, string str) { return modifiers.Any(modifier => modifier.ValueText == str); } - - public bool IsPublic(T p) where T : MemberDeclarationSyntax { return ModifiersContains(p.Modifiers, "public"); } - - private static bool ImplementsInterface(INamedTypeSymbol typeSymbol, string typeToCheck) - { - if (typeSymbol == null) - { - return false; - } - - if (typeSymbol.BaseType != null && typeSymbol.BaseType.MetadataName == typeToCheck) - { - return true; - } - - foreach (var implementedInterface in typeSymbol.AllInterfaces) - { - if (implementedInterface.MetadataName == typeToCheck) - { - return true; - } - } - return false; - } - - /// - /// Attributes can come in one list or many, e.g. [A()][B()] vs. [A(),B()] - /// look at all possible attributes and see if any match the given string - /// attribute names need to be fully qualified, e.g. DefaultOverload is really Windows.Foundation.Metadata.DefaultOverload - /// all the syntax nodes that correspond to an attribute list - /// true iff the given attribute is in the list - private bool MatchesAnyAttribute(string attrName, SyntaxList ls) - { - foreach (var attrList in ls) - { - foreach (var attr in attrList.Attributes) - { - if (attr.Name.ToString().Equals(attrName)) - { - return true; - } - } - } - return false; - } - - /// - /// Looks at all possible attributes on a given parameter declaration - /// - /// - /// returns true iff any are (string) equal to the given attribute name - /// - private bool ParamHasAttribute(string attrName, ParameterSyntax param) { return MatchesAnyAttribute(attrName, param.AttributeLists); } - - private static readonly string[] InAndOutAttributeNames = { "In", "Out", "System.Runtime.InteropServices.In", "System.Runtime.InteropServices.Out" }; - private static readonly string[] OverloadAttributeNames = { "Windows.Foundation.Metadata.DefaultOverload", "DefaultOverload" }; - - private bool ParamHasInOrOutAttribute(ParameterSyntax param) - { - return InAndOutAttributeNames.Where(str => ParamHasAttribute(str, param)).Any(); - } - - private bool MethodHasDefaultOverloadAttribute(MethodDeclarationSyntax method) - { - return OverloadAttributeNames.Where(str => MatchesAnyAttribute(str, method.AttributeLists)).Any(); - } - - /// e.g. `int foo(out int i) { ... }` /// - /// True if the parameter has the `ref` modifier - private bool ParamMarkedOutput(ParameterSyntax param) { return ModifiersContains(param.Modifiers, "out"); } - - /// e.g. `int foo(ref int i) { ... }` - /// the parameter to look for the ref keyword on - /// True if the parameter has the `ref` modifier - private bool ParamMarkedRef(ParameterSyntax param) { return ModifiersContains(param.Modifiers, "ref"); } - - /* SimplifySyntaxTypeString - * returns the more common term for the given kind of syntax; used when creating a diagnostic for an invalid field in a struct */ - private string SimplifySyntaxTypeString(string syntaxType) - { - switch (syntaxType) - { - case "EventFieldDeclarationSyntax": return "event"; - case "ConstructorDeclarationSyntax": return "constructor"; - case "DelegateDeclarationSyntax": return "delegate"; - case "IndexerDeclarationSyntax": return "indexer"; - case "MethodDeclarationSyntax": return "method"; - case "OperatorDeclarationSyntax": return "operator"; - case "PropertyDeclarationSyntax": return "property"; - default: return "unknown syntax type: " + syntaxType; - } - } - - /// - /// Keeps track of repeated declarations of a method (overloads) and raises diagnostics according to the rule that exactly one overload should be attributed the default - /// Look for overloads of this method, checking the attributes as well attributes for - /// - /// Keeps track of the method (via qualified name + arity) and whether it was declared with the DefaultOverload attribute - /// this variable is ref because we are mutating this map with each method, so we only look at a method a second time if it has an overload but no attribute - /// - /// Keeps track of the methods that are overloads but don't have the DefaultOverload attribute (yet) - /// Used after this function executes, hence the reference parameter - /// The class the method lives in -- used for creating the diagnostic - /// True iff multiple overloads of a method are found, where more than one has been designated as the default overload - private bool CheckOverloadAttributes(ref GeneratorExecutionContext context, - MethodDeclarationSyntax method, - ref Dictionary methodHasAttributeMap, - ref Dictionary overloadsWithoutAttributeMap, - SyntaxToken classId) - { - bool found = false; - int methodArity = method.ParameterList.Parameters.Count; - string methodNameWithArity = method.Identifier.Text + methodArity.ToString(); - - // look at all the attributes on this method and see if any of them is the DefaultOverload attribute - bool hasDefaultOverloadAttribute = MethodHasDefaultOverloadAttribute(method); - bool seenMethodBefore = methodHasAttributeMap.TryGetValue(methodNameWithArity, out bool methodHasAttrAlready); - - // Do we have an overload ? - if (seenMethodBefore) - { - if (hasDefaultOverloadAttribute && !methodHasAttrAlready) - { - // we've seen it, but it didnt have the attribute, so mark that it has it now - methodHasAttributeMap[methodNameWithArity] = true; - overloadsWithoutAttributeMap.Remove(methodNameWithArity); - } - else if (hasDefaultOverloadAttribute && methodHasAttrAlready) - { - // raise the "can't have multiple default attributes" diagnostic - Report(ref context, DiagnosticRules.MethodOverload_MultipleDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classId); - found |= true; - } - else if (!hasDefaultOverloadAttribute && !methodHasAttrAlready) - { - // we could see this method later with the attribute, so hold onto the diagnostic for it until we know it doesn't have the attribute - overloadsWithoutAttributeMap[methodNameWithArity] = Diagnostic.Create(DiagnosticRules.MethodOverload_NeedDefaultAttribute, method.GetLocation(), methodArity, method.Identifier, classId); - } - } - else - { - // first time we're seeing the method, add a pair in the map for its name and whether it has the attribute - methodHasAttributeMap[methodNameWithArity] = hasDefaultOverloadAttribute; - } - - return found; - } - - private static readonly string[] ProhibitedAsyncInterfaces = { - "IAsyncAction", - "IAsyncActionWithProgress`1", - "IAsyncOperation`1", - "IAsyncOperationWithProgress`2" - }; - - /// - /// Returns true if the class represented by the symbol - /// implements any of the interfaces defined in ProhibitedAsyncInterfaces (e.g., IAsyncAction, ...) /// - /// - /// True iff the given class implements any of the IAsync interfaces that are not valid in Windows Runtime - public bool ImplementsAsyncInterface(ref GeneratorExecutionContext context, INamedTypeSymbol typeSymbol, T typeDeclaration) - where T : TypeDeclarationSyntax - { - foreach (string prohibitedInterface in ProhibitedAsyncInterfaces) - { - if (ImplementsInterface(typeSymbol, prohibitedInterface)) - { - Report(ref context, DiagnosticRules.AsyncRule, typeDeclaration.GetLocation(), typeDeclaration.Identifier, prohibitedInterface); - return true; - } - } - return false; - } - - /// - /// Raises a diagnostic when multiple constructors for a class are defined with the same arity. - /// look for constructors of this class - /// True if multiple constructors of the same arity exist for the given class - public bool HasMultipleConstructorsOfSameArity(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - IEnumerable constructors = classDeclaration.ChildNodes().OfType().Where(IsPublic); - - HashSet aritiesSeenSoFar = new HashSet(); - - foreach (ConstructorDeclarationSyntax constructor in constructors) - { - int arity = constructor.ParameterList.Parameters.Count; - if (aritiesSeenSoFar.Contains(arity)) - { - Report(ref context, DiagnosticRules.ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity); - return true; - } - else - { - aritiesSeenSoFar.Add(arity); - } - } - return false; - } - - /// Checks each type in the given list of types and sees if any are equal to the given type name - /// - /// A list of the descendent nodes that are of the given type, possibly empty. - /// empty example: this property doesnt have any qualified types in its signature - /// check to see if this type appears in the signaturediagnostic to report if we see the typeName - /// true if the given type is the same as the one in the list - private bool SignatureContainsTypeName(ref GeneratorExecutionContext context, IEnumerable typesInSignature, string typeName, Diagnostic diag) - { - foreach (T name in typesInSignature) - { - if (name.ToString().Equals(typeName)) - { - context.ReportDiagnostic(diag); - return true; - } - } - return false; - } - - /// Checks to see if the class declares any operators (overloading them) - /// - /// Class to check for operator declarations - /// operator declarations are just like method declarations except they use the `operator` keyword - /// True iff an operator is overloaded by the given class - public bool OverloadsOperator(ref GeneratorExecutionContext context, ClassDeclarationSyntax classDeclaration) - { - var operatorDeclarations = classDeclaration.DescendantNodes().OfType(); - foreach (var op in operatorDeclarations) { Report(ref context, DiagnosticRules.OperatorOverloadedRule, op.GetLocation(), op.OperatorToken); } - return operatorDeclarations.Count() != 0; - } - - /// Looks at all the properties of the given class and checks them for improper array types (System.Array instances, multidimensional, jagged) - /// - /// True iff any of the invalid array types are used in any of the propertyy signatures in the given class - public bool CheckPropertySignature(ref GeneratorExecutionContext context, IEnumerable props, SyntaxToken typeId) - { - bool found = false; - foreach (var prop in props) - { - var loc = prop.GetLocation(); - var propId = prop.Identifier; - - var qualifiedTypes = prop.DescendantNodes().OfType(); - var d = Diagnostic.Create(DiagnosticRules.ArraySignature_SystemArrayRule, loc, typeId, propId); - found |= SignatureContainsTypeName(ref context, qualifiedTypes, "System.Array", d); - - var types = prop.DescendantNodes().OfType(); - var d2 = Diagnostic.Create(DiagnosticRules.ArraySignature_SystemArrayRule, loc, typeId, propId); - found |= SignatureContainsTypeName(ref context, types, "Array", d2); - - found |= ArrayIsntOneDim(prop.DescendantNodes().OfType(), ref context, typeId, propId, loc); - } - return found; - } - - /// - /// Look at all the array types and if any are of the form [][]+ or [,+] then raise the corresponding diagnostic and return true - /// The type the array lives in - /// The code the array is a part of the signature for; e.g. property or method - /// True iff any of the array types given are multidimensional or jagged - private bool ArrayIsntOneDim(IEnumerable arrTypes, - ref GeneratorExecutionContext context, - SyntaxToken typeIdentifier, - SyntaxToken fieldId, - Location loc) - { - foreach (var arrType in arrTypes) - { - var brackets = arrType.DescendantNodes().OfType(); - // [][]+ ? - if (brackets.Count() > 1) - { - Report(ref context, DiagnosticRules.ArraySignature_JaggedArrayRule, loc, fieldId, typeIdentifier); - return true; - } - // [,+] ? - else if (brackets.Count() == 1 && brackets.First().ToString().Contains(",")) - { - Report(ref context, DiagnosticRules.ArraySignature_MultiDimensionalArrayRule, loc, fieldId, typeIdentifier); - return true; - } - } - return false; - } - - /// - /// The code generation process makes functions with output param `__retval`, - /// we will shadow a user variable named the same thing -- so raise a diagnostic instead - /// compilation unit to raise diagnostic onthe method whose parameteres we are inspecting - /// True if any parameter is named "__retval" - public bool HasConflictingParameterName(ref GeneratorExecutionContext context, MethodDeclarationSyntax method) - { - var hasInvalidParams = method.ParameterList.Parameters.Where(param => SyntaxTokenIs(param.Identifier, "__retval")).Any(); - if (hasInvalidParams) - { - Report(ref context, DiagnosticRules.ParameterNamedValueRule, method.GetLocation(), method.Identifier); - } - return hasInvalidParams; - } - - /// - /// Checks to see if an array parameter has been marked with both Write and Read attributes - /// Does extra work, by catching `ref` params, done here since this code can be used by class or interface related methods - /// - /// true if array attributes are invalid (see summary) - private bool CheckParamsForArrayAttributes(MethodDeclarationSyntax method, ref GeneratorExecutionContext context) - { - bool found = false; - foreach (ParameterSyntax param in method.ParameterList.Parameters) - { - var isArrayType = param.ChildNodes().OfType().Any(); - bool hasReadOnlyArray = ParamHasAttribute("System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray", param); - bool hasWriteOnlyArray = ParamHasAttribute("System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray", param); - bool isOutputParam = ParamMarkedOutput(param); - - // Nothing can be marked `ref` - if (ParamMarkedRef(param)) - { - Report(ref context, DiagnosticRules.RefParameterFound, method.GetLocation(), param.Identifier); - found |= true; - } - - if (ParamHasInOrOutAttribute(param)) - { - // recommend using ReadOnlyArray or WriteOnlyArray - if (isArrayType) - { - Report(ref context, DiagnosticRules.ArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier); - found |= true; - } - // if not array type, stil can't use [In] or [Out] - else - { - Report(ref context, DiagnosticRules.NonArrayMarkedInOrOut, method.GetLocation(), method.Identifier, param.Identifier); - found |= true; - } - } - - if (isArrayType) - { - // can't be both ReadOnly and WriteOnly - if (hasReadOnlyArray && hasWriteOnlyArray) - { - Report(ref context, DiagnosticRules.ArrayParamMarkedBoth, method.GetLocation(), method.Identifier, param.Identifier); - found |= true; - } - // can't be both output (writeonly) and marked read only - else if (hasReadOnlyArray && isOutputParam) - { - Report(ref context, DiagnosticRules.ArrayOutputParamMarkedRead, method.GetLocation(), method.Identifier, param.Identifier); - found |= true; - } - // must have some indication of ReadOnly or WriteOnly - else if (!hasWriteOnlyArray && !hasReadOnlyArray && !isOutputParam) - { - Report(ref context, DiagnosticRules.ArrayParamNotMarked, method.GetLocation(), method.Identifier, param.Identifier); - found |= true; - } - } - // Non-array types shouldn't have attributes meant for arrays - else if (hasWriteOnlyArray || hasReadOnlyArray) - { - Report(ref context, DiagnosticRules.NonArrayMarked, method.GetLocation(), method.Identifier, param.Identifier); - found |= true; - } - } - - return found; - } - - public bool HasInvalidMethods(ref GeneratorExecutionContext context, IEnumerable methodDeclarations, SyntaxToken typeId) - where T : TypeDeclarationSyntax - { - bool found = false; - Dictionary methodsHasAttributeMap = new Dictionary(); - - /* we can't throw the diagnostic as soon as we see a second overload without an attribute, - * as there could be a third overload with the default attribute - * So store a diagnostic in case we see all methods and none of this overload have the attribute */ - Dictionary overloadsWithoutAttributeMap = new Dictionary(); - - // var methodDeclarations = interfaceDeclaration.DescendantNodes().OfType(); - foreach (MethodDeclarationSyntax method in methodDeclarations) - { - found |= CheckOverloadAttributes(ref context, method, ref methodsHasAttributeMap, ref overloadsWithoutAttributeMap, typeId); - found |= HasConflictingParameterName(ref context, method); - found |= CheckMethod(ref context, method, typeId); - } - /* Finishes up the work started by `CheckOverloadAttributes` */ - foreach (var thing in overloadsWithoutAttributeMap) - { - context.ReportDiagnostic(thing.Value); - found |= true; - } - return found; - } - private bool CheckMethod(ref GeneratorExecutionContext context, MethodDeclarationSyntax method, SyntaxToken parentNodeId) - { - bool found = false; - Location loc = method.GetLocation(); - SyntaxToken methodId = method.Identifier; - IEnumerable qualifiedTypes = method.DescendantNodes().OfType(); - IEnumerable types = method.DescendantNodes().OfType(); - IEnumerable arrays = method.DescendantNodes().OfType(); - - var d = Diagnostic.Create(DiagnosticRules.ArraySignature_SystemArrayRule, loc, parentNodeId, methodId); - found |= SignatureContainsTypeName(ref context, qualifiedTypes, "System.Array", d); - found |= SignatureContainsTypeName(ref context, types, "Array", d); - found |= ArrayIsntOneDim(arrays, ref context, parentNodeId, methodId, loc); - found |= CheckParamsForArrayAttributes(method, ref context); - return found; - } - - /// - /// returns true iff there is a field of the given type in the given struct - /// e.g., if T is PropertyDeclarationSyntax, then if the struct has a property, we report a diagnostic and return true - /// T can vary over MethodDeclartion, EventDeclaration, etc... - /// - /// - /// - public bool StructHasFieldOfType(ref GeneratorExecutionContext context, StructDeclarationSyntax structDeclaration) - { - if (structDeclaration.DescendantNodes().OfType().Any()) - { - Report(ref context, DiagnosticRules.StructHasInvalidFieldRule2, structDeclaration.GetLocation(), structDeclaration.Identifier, SimplifySyntaxTypeString(typeof(T).Name)); - return true; - } - return false; - } - - /// - /// returns true if there is a field declared private, - /// or (inclusive) declared with a type that is a class or one of object, byte or dynamic - /// The field to inspectThe name of the struct the field belongs to - /// A list of qualified class and interface names, which are invalid types to use in a struct for WinRT Component - /// True if the struct has a field of an type that is not supported in Windows Runtime - public bool CheckFieldValidity(ref GeneratorExecutionContext context, - FieldDeclarationSyntax field, - SyntaxToken structId, - HashSet typeNames) - { - bool found = false; - - /* No private fields allowed in Windows Runtime components */ - if (!IsPublic(field)) - { - Report(ref context, DiagnosticRules.StructHasPrivateFieldRule, field.GetLocation(), structId); - found |= true; - } - - if (ModifiersContains(field.Modifiers, "const")) - { - Report(ref context, DiagnosticRules.StructHasConstFieldRule, field.GetLocation(), structId); - found |= true; - } - - foreach (var variable in field.DescendantNodes().OfType()) - { - var typeStr = variable.Type.ToString(); - - HashSet invalidTypes = new HashSet { "object", "dynamic" }; - if (SymbolSetHasString(typeNames, typeStr) || invalidTypes.Contains(typeStr)) - { - Report(ref context, DiagnosticRules.StructHasInvalidFieldRule, variable.GetLocation(), structId, field.ToString(), typeStr); - found |= true; - } - } - return found; - } - } -} +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using WinRT.SourceGenerator; + +namespace Generator +{ + public partial class WinRTComponentScanner + { + public WinRTComponentScanner(GeneratorExecutionContext context, string assemblyName) + { + _assemblyName = assemblyName; + _context = context; + _flag = false; + _typeHolder = CollectDefinedTypes(context); + } + + private string _assemblyName; + private GeneratorExecutionContext _context; + private bool _flag; + private TypeCollector _typeHolder; + + public bool Found() { return _flag; } + + /// + /// Gather information on all classes, interfaces and structs + /// Perform code analysis to find scenarios that are erroneous in Windows Runtime + public void FindDiagnostics() + { + HasInvalidNamespace(); + HasSomePublicTypes(); + + foreach (SyntaxTree tree in _context.Compilation.SyntaxTrees) + { + var model = _context.Compilation.GetSemanticModel(tree); + var nodes = tree.GetRoot().DescendantNodes(); + + var classes = nodes.OfType().Where(IsPublic); + foreach (ClassDeclarationSyntax @class in classes) + { + var classId = @class.Identifier; + var classSymbol = model.GetDeclaredSymbol(@class); + var publicMethods = @class.ChildNodes().OfType().Where(IsPublic); + var props = @class.DescendantNodes().OfType().Where(IsPublic); + + // filter out methods and properties that will be replaced with our custom type mappings + IgnoreCustomTypeMappings(classSymbol, ref publicMethods, ref props); + + if (!classSymbol.IsSealed) + { + Report(WinRTRules.UnsealedClassRule, @class.GetLocation(), classId); + } + + OverloadsOperator(@class); + HasMultipleConstructorsOfSameArity(@class); + + if (classSymbol.IsGenericType) + { + Report(WinRTRules.GenericTypeRule, @class.GetLocation(), classId); + } + + // check for things in nonWindowsRuntimeInterfaces + ImplementsInvalidInterface(classSymbol, @class); + + CheckPropertySignature(props, classId); + + CheckMethods(publicMethods, classId); + } + + var interfaces = nodes.OfType().Where(IsPublic); + foreach (InterfaceDeclarationSyntax @interface in interfaces) + { + var interfaceSym = model.GetDeclaredSymbol(@interface); + var methods = @interface.DescendantNodes().OfType(); + var props = @interface.DescendantNodes().OfType().Where(IsPublic); + + // filter out methods and properties that will be replaced with our custom type mappings + IgnoreCustomTypeMappings(interfaceSym, ref methods, ref props); + + if (interfaceSym.IsGenericType) + { + Report(WinRTRules.GenericTypeRule, @interface.GetLocation(), @interface.Identifier); + } + + ImplementsInvalidInterface(interfaceSym, @interface); + + CheckPropertySignature(props, @interface.Identifier); + + CheckMethods(methods, @interface.Identifier); + } + + var structs = nodes.OfType(); + foreach (StructDeclarationSyntax @struct in structs) + { + CheckStructFields(@struct); + } + } + } + + private void IgnoreCustomTypeMappings(INamedTypeSymbol typeSymbol, + ref IEnumerable methods, + ref IEnumerable properties) + { + string QualifiedName(INamedTypeSymbol sym) + { + return sym.OriginalDefinition.ContainingNamespace + "." + sym.OriginalDefinition.MetadataName; + } + + HashSet classMethods = new HashSet(); + + foreach (var @interface in typeSymbol.AllInterfaces. + Where(symbol => WinRTTypeWriter.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)) || + WinRTTypeWriter.ImplementedInterfacesWithoutMapping.Contains(QualifiedName(symbol)))) + { + foreach (var interfaceMember in @interface.GetMembers()) + { + classMethods.Add(typeSymbol.FindImplementationForInterfaceMember(interfaceMember)); + } + } + methods = methods.Where(m => !classMethods.Contains(GetModel(m.SyntaxTree).GetDeclaredSymbol(m))); + properties = properties.Where(p => !classMethods.Contains(GetModel(p.SyntaxTree).GetDeclaredSymbol(p))); + } + + /// Checks to see if the class declares any operators (overloading them) + ///Class to check + /// Class to check for operator declarations + /// operator declarations are just like method declarations except they use the `operator` keyword + /// True iff an operator is overloaded by the given class + private bool OverloadsOperator(ClassDeclarationSyntax classDeclaration) + { + var operatorDeclarations = classDeclaration.DescendantNodes().OfType(); + foreach (var op in operatorDeclarations) { Report(WinRTRules.OperatorOverloadedRule, op.GetLocation(), op.OperatorToken); } + return operatorDeclarations.Count() != 0; + } + + /// Raise a diagnostic if there are no public types in the namespace + private void HasSomePublicTypes() + { + // types are interfaces, classes and structs + if (!_typeHolder.GetTypes().Any() && !_typeHolder.GetStructs().Any()) + { + Report(WinRTRules.NoPublicTypesRule, null); + } + } + + /// + /// Raises a diagnostic when multiple constructors for a class are defined with the same arity. + /// Look at constructors of this class + private void HasMultipleConstructorsOfSameArity(ClassDeclarationSyntax classDeclaration) + { + IEnumerable constructors = classDeclaration.ChildNodes().OfType().Where(IsPublic); + + HashSet aritiesSeenSoFar = new HashSet(); + + foreach (ConstructorDeclarationSyntax constructor in constructors) + { + int arity = constructor.ParameterList.Parameters.Count; + if (aritiesSeenSoFar.Contains(arity)) + { + Report(WinRTRules.ClassConstructorRule, constructor.GetLocation(), classDeclaration.Identifier, arity); + } + else + { + aritiesSeenSoFar.Add(arity); + } + } + } + + /// + /// The code generation process makes functions with output param `__retval`, + /// we will shadow a user variable named the same thing -- so raise a diagnostic instead + /// the method whose parameteres we are inspecting + private void HasConflictingParameterName(MethodDeclarationSyntax method) + { + // check if the identifier is our special name GeneratedReturnValueName + bool IsInvalidParameterName(ParameterSyntax stx) { return stx.Identifier.Value.Equals(GeneratedReturnValueName); } + + var hasInvalidParams = method.ParameterList.Parameters.Where(IsInvalidParameterName).Any(); + if (hasInvalidParams) + { + Report(WinRTRules.ParameterNamedValueRule, method.GetLocation(), method.Identifier); + } + } + + /// + /// Look for overloads/defaultoverload attribute, conflicting parameter names, + /// parameter attribute errors, invalid types + /// Collection of methodsContaining class or interface + private void CheckMethods(IEnumerable methodDeclarations, SyntaxToken typeId) + { + Dictionary methodsHasAttributeMap = new Dictionary(); + Dictionary overloadsWithoutAttributeMap = new Dictionary(); + + // var methodDeclarations = interfaceDeclaration.DescendantNodes().OfType(); + foreach (MethodDeclarationSyntax method in methodDeclarations) + { + /* Gather information on which methods have overloads, and if any method has the DefaultOverload attribute */ + CheckOverloadAttributes(method, methodsHasAttributeMap, overloadsWithoutAttributeMap, typeId); + /* Has parameter named __retval */ + HasConflictingParameterName(method); + /* Check signature for invalid types */ + ParameterHasAttributeErrors(method); + + var methodSym = GetModel(method.SyntaxTree).GetDeclaredSymbol(method); + + ReportIfInvalidType(methodSym.ReturnType, method.GetLocation(), method.Identifier, typeId); + foreach (var arg in methodSym.Parameters) + { + ReportIfInvalidType(arg.Type, method.GetLocation(), method.Identifier, typeId); + } + } + /* Finishes up the work started by `CheckOverloadAttributes` */ + foreach (var thing in overloadsWithoutAttributeMap) + { + ReportDiagnostic(thing.Value); + } + } + + /// Looks at all the properties of the given class and checks them for improper array types (System.Array instances, multidimensional, jagged) + ///collection of propertiescontaining class/interface + /// True iff any of the invalid array types are used in any of the propertyy signatures in the given class + private void CheckPropertySignature(IEnumerable props, SyntaxToken typeId) + { + foreach (var prop in props) + { + var propSym = GetModel(prop.SyntaxTree).GetDeclaredSymbol(prop); + var loc = prop.GetLocation(); + + ReportIfInvalidType(propSym.Type, loc, prop.Identifier, typeId); + foreach (var arg in propSym.Parameters) + { + ReportIfInvalidType(arg.Type, loc, prop.Identifier, typeId); + } + } + } + + /// All struct fields must be public, of basic types, and not const + /// struct declaration + private void CheckStructFields(StructDeclarationSyntax @struct) + { + // delegates not allowed + if (@struct.DescendantNodes().OfType().Any()) + { + Report(WinRTRules.StructHasInvalidFieldRule, @struct.GetLocation(), @struct.Identifier, SimplifySyntaxTypeString(typeof(DelegateDeclarationSyntax).Name)); + } + // methods not allowed + if (@struct.DescendantNodes().OfType().Any()) + { + Report(WinRTRules.StructHasInvalidFieldRule, @struct.GetLocation(), @struct.Identifier, SimplifySyntaxTypeString(typeof(MethodDeclarationSyntax).Name)); + } + + var structSym = GetModel(@struct.SyntaxTree).GetDeclaredSymbol(@struct); + + // constructors not allowed + if (structSym.Constructors.Length > 1) + { + Report(WinRTRules.StructHasInvalidFieldRule, @struct.GetLocation(), @struct.Identifier, SimplifySyntaxTypeString(typeof(ConstructorDeclarationSyntax).Name)); + } + + var fields = @struct.DescendantNodes().OfType(); + foreach (var field in fields) + { + // all fields must be public + if (!IsPublic(field)) + { + Report(WinRTRules.StructHasPrivateFieldRule, field.GetLocation(), @struct.Identifier); + } + + // const fields not allowed + if (field.Modifiers.Where(m => m.IsKind(SyntaxKind.ConstKeyword)).Any()) + { + Report(WinRTRules.StructHasConstFieldRule, field.GetLocation(), @struct.Identifier); + } + // see what type the field is, it must be an allowed type or another struct + foreach (var variable in field.Declaration.Variables) + { + IFieldSymbol varFieldSym = (IFieldSymbol)GetModel(variable.SyntaxTree).GetDeclaredSymbol(variable); + + if (ValidStructFieldTypes.Contains(varFieldSym.Type.SpecialType) || varFieldSym.Type.TypeKind == TypeKind.Struct) + { + break; + } + else + { + Report(WinRTRules.StructHasInvalidFieldRule, variable.GetLocation(), @struct.Identifier, varFieldSym.Name); + } + } + } + // Structs must have some public fields + if (!fields.Any()) + { + Report(WinRTRules.StructWithNoFieldsRule, @struct.GetLocation(), @struct.Identifier); + } + } + + /// Namespaces can't only differ by cases, also check if the name is invalid for the winmd being made + private void HasInvalidNamespace() + { + // instead of this, see if != but are equal when ignoring case + HashSet simplifiedNames = new HashSet(); + + foreach (var namespaceSymbol in _typeHolder.GetNamespaces()) + { + string upperNamed = namespaceSymbol.Name.ToUpper(); + if (simplifiedNames.Contains(upperNamed)) + { + Report(WinRTRules.NamespacesDifferByCase, namespaceSymbol.Locations.First(), namespaceSymbol.Name); + } + else + { + simplifiedNames.Add(upperNamed); + } + + if (IsInvalidNamespace(namespaceSymbol, _assemblyName)) + { + Report(WinRTRules.DisjointNamespaceRule, namespaceSymbol.Locations.First(), _assemblyName, namespaceSymbol.Name); + } + } + } + + /// Make sure any namespace defined is the same as the winmd or a subnamespace of it + /// If component is A.B, e.g. A.B.winmd , then D.Class1 is invalid, as well as A.C.Class2 + /// + /// the authored namesapce to checkthe name of the component/winmd + /// True iff namespace is disjoint from the assembly name + private bool IsInvalidNamespace(INamespaceSymbol @namespace, string assemblyName) + { + // get the outermost containing namespace + var topLevel = @namespace; + while (!topLevel.ContainingNamespace.IsGlobalNamespace) + { + topLevel = topLevel.ContainingNamespace; + } + + return assemblyName != @namespace.Name && assemblyName != topLevel.Name; + } + + ///Array types can only be one dimensional and not System.Array, + ///and there are some types not usable in the Windows Runtime, like KeyValuePair + ///The type to checkwhere the type is + ///The method or property with this type in its signature + /// the type this member (method/prop) lives in + private void ReportIfInvalidType(ITypeSymbol typeSymbol, Location loc, SyntaxToken memberId, SyntaxToken typeId) + { + // If it's of the form int[], it has to be one dimensional + if (typeSymbol.TypeKind == TypeKind.Array) + { + IArrayTypeSymbol arrTypeSym = (IArrayTypeSymbol)typeSymbol; + + // [,,]? + if (arrTypeSym.Rank > 1) + { + Report(WinRTRules.MultiDimensionalArrayRule, loc, memberId, typeId); + return; + } + // [][]? + if (arrTypeSym.ElementType.TypeKind == TypeKind.Array) + { + Report(WinRTRules.JaggedArrayRule, loc, memberId, typeId); + return; + } + } + + // NotValidTypes is an array of types that don't exist in Windows Runtime, so can't be passed between functions in Windows Runtime + foreach (var typeName in NotValidTypes) + { + var notValidTypeSym = GetTypeByMetadataName(typeName); + if (SymEq(typeSymbol.OriginalDefinition, notValidTypeSym)) + { + Report(WinRTRules.UnsupportedTypeRule, loc, memberId, typeName, SuggestType(typeName)); + return; + } + } + + // construct the qualified name for this type + string qualifiedName = ""; + if (typeSymbol.ContainingNamespace != null && !typeSymbol.ContainingNamespace.IsGlobalNamespace) + { + // ContainingNamespace for Enumerable is just System, but we need System.Linq which is the ContainingSymbol + qualifiedName += typeSymbol.ContainingSymbol + "."; + } + // instead of TypeName, TypeName`1 + qualifiedName += typeSymbol.MetadataName; + + // GetTypeByMetadataName fails on "System.Linq.Enumerable" & "System.Collections.ObjectModel.ReadOnlyDictionary`2" + // Would be fixed by issue #678 on the dotnet/roslyn-sdk repo + foreach (var notValidType in WIPNotValidTypes) + { + if (qualifiedName == notValidType) + { + Report(WinRTRules.UnsupportedTypeRule, loc, memberId, notValidType, SuggestType(notValidType)); + return; + } + } + } + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index c3c8d6a3f..50e2bd56a 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -1,327 +1,247 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Text; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection.Metadata; -using System.Reflection.Metadata.Ecma335; -using System.Reflection.PortableExecutable; -using System.Text; -using WinRT.SourceGenerator; - -namespace Generator -{ - [Generator] - public class SourceGenerator : ISourceGenerator - { - private static readonly string ArrayAttributes = @" -namespace System.Runtime.InteropServices.WindowsRuntime -{ - [global::System.AttributeUsage(System.AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] - internal sealed class ReadOnlyArrayAttribute : global::System.Attribute - { - } - - [global::System.AttributeUsage(System.AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] - internal sealed class WriteOnlyArrayAttribute : global::System.Attribute - { - } -}"; - - private string _tempFolder; - - private static string GetAssemblyName(GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName); - return assemblyName; - } - - private static string GetAssemblyVersion(GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyVersion", out var assemblyVersion); - return assemblyVersion; - } - - internal static string GetGeneratedFilesDir(GeneratorExecutionContext context) - { - // TODO: determine correct location to write to. - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.GeneratedFilesDir", out var generatedFilesDir); - Directory.CreateDirectory(generatedFilesDir); - return generatedFilesDir; - } - - private static bool IsCsWinRTComponent(GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) - { - return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; - } - - return false; - } - - private static string GetCsWinRTExe(GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExe", out var cswinrtExe); - return cswinrtExe; - } - - private static bool GetKeepGeneratedSources(GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTKeepGeneratedSources", out var keepGeneratedSourcesStr); - return keepGeneratedSourcesStr != null && bool.TryParse(keepGeneratedSourcesStr, out var keepGeneratedSources) && keepGeneratedSources; - } - - private static string GetCsWinRTWindowsMetadata(GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWindowsMetadata", out var cswinrtWindowsMetadata); - return cswinrtWindowsMetadata; - } - - private string GetTempFolder(bool clearSourceFilesFromFolder = false) - { - if(_tempFolder == null || !File.Exists(_tempFolder)) - { - string outputDir = Path.Combine(Path.GetTempPath(), "CsWinRT", Path.GetRandomFileName()).TrimEnd('\\'); - Directory.CreateDirectory(outputDir); - _tempFolder = outputDir; - Logger.Log("Created temp folder: " + _tempFolder); - } - - if (clearSourceFilesFromFolder) - { - foreach (var file in Directory.GetFiles(_tempFolder, "*.cs", SearchOption.TopDirectoryOnly)) - { - Logger.Log("Clearing " + file); - File.Delete(file); - } - } - - return _tempFolder; - } - - private void GenerateSources(GeneratorExecutionContext context) - { - string cswinrtExe = GetCsWinRTExe(context); - string assemblyName = GetAssemblyName(context); - string winmdFile = GetWinmdOutputFile(context); - string outputDir = GetTempFolder(true); - string windowsMetadata = GetCsWinRTWindowsMetadata(context); - // TODO: support additional WinMD files from other projections. - - string arguments = string.Format("-component -input \"{0}\" -input {1} -include {2} -output \"{3}\" -verbose", winmdFile, windowsMetadata, assemblyName, outputDir); - Logger.Log("Running " + cswinrtExe + " " + arguments); - - var processInfo = new ProcessStartInfo - { - FileName = cswinrtExe, - Arguments = arguments, - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - WindowStyle = ProcessWindowStyle.Hidden, - CreateNoWindow = true - }; - - try - { - using var cswinrtProcess = Process.Start(processInfo); - Logger.Log(cswinrtProcess.StandardOutput.ReadToEnd()); - Logger.Log(cswinrtProcess.StandardError.ReadToEnd()); - cswinrtProcess.WaitForExit(); - - if (cswinrtProcess.ExitCode != 0) - { - throw new Win32Exception(cswinrtProcess.ExitCode); - } - - foreach (var file in Directory.GetFiles(outputDir, "*.cs", SearchOption.TopDirectoryOnly)) - { - Logger.Log("Adding " + file); - context.AddSource(Path.GetFileNameWithoutExtension(file), SourceText.From(File.ReadAllText(file), Encoding.UTF8)); - } - } - finally - { - if (!GetKeepGeneratedSources(context)) - { - Directory.Delete(outputDir, true); - } - } - } - - private string GetWinmdOutputFile(GeneratorExecutionContext context) - { - return Path.Combine(GetGeneratedFilesDir(context), GetAssemblyName(context) + ".winmd"); - } - - private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) - { - Logger.Log("Writing " + outputFile); - var managedPeBuilder = new ManagedPEBuilder( - new PEHeaderBuilder( - machine: Machine.I386, - imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll | Characteristics.Bit32Machine), - new MetadataRootBuilder(metadataBuilder, "WindowsRuntime 1.4"), - new BlobBuilder(), - flags: CorFlags.ILOnly); - - var peBlob = new BlobBuilder(); - managedPeBuilder.Serialize(peBlob); - - using var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write); - peBlob.WriteContentTo(fs); - } - - private HashSet CollectDefinedTypes(GeneratorExecutionContext context) - { - WinRTRules winrtRules = new WinRTRules(); - HashSet userCreatedTypes = new HashSet(); - foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) - { - var model = context.Compilation.GetSemanticModel(tree); - var classes = tree.GetRoot().DescendantNodes().OfType().Where(winrtRules.IsPublic); - var interfaces = tree.GetRoot().DescendantNodes().OfType().Where(winrtRules.IsPublic); - foreach (var @class in classes) - { - userCreatedTypes.Add(model.GetDeclaredSymbol(@class)); - } - foreach (var @interface in interfaces) - { - userCreatedTypes.Add(model.GetDeclaredSymbol(@interface)); - } - } - return userCreatedTypes; - } - - private bool CatchWinRTDiagnostics(ref GeneratorExecutionContext context) - { - bool found = false; - WinRTRules winrtRules = new WinRTRules(); - - HashSet userCreatedTypes = CollectDefinedTypes(context); - - foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) - { - var model = context.Compilation.GetSemanticModel(tree); - var nodes = tree.GetRoot().DescendantNodes(); - - var classes = nodes.OfType().Where(winrtRules.IsPublic); - var interfaces = nodes.OfType().Where(winrtRules.IsPublic); - var structs = nodes.OfType(); - - foreach (ClassDeclarationSyntax classDeclaration in classes) - { - found |= winrtRules.OverloadsOperator(ref context, classDeclaration); - found |= winrtRules.HasMultipleConstructorsOfSameArity(ref context, classDeclaration); - found |= winrtRules.ImplementsAsyncInterface(ref context, model.GetDeclaredSymbol(classDeclaration), classDeclaration); - - var props = classDeclaration.DescendantNodes().OfType().Where(winrtRules.IsPublic); - found |= winrtRules.CheckPropertySignature(ref context, props, classDeclaration.Identifier); - - var publicMethods = classDeclaration.ChildNodes().OfType().Where(winrtRules.IsPublic); - found |= winrtRules.HasInvalidMethods(ref context, publicMethods,classDeclaration.Identifier); - } - - foreach (InterfaceDeclarationSyntax interfaceDeclaration in interfaces) - { - found |= winrtRules.ImplementsAsyncInterface(ref context, model.GetDeclaredSymbol(interfaceDeclaration), interfaceDeclaration); - - var props = interfaceDeclaration.DescendantNodes().OfType(); - found |= winrtRules.CheckPropertySignature(ref context, props, interfaceDeclaration.Identifier); - - var methods = interfaceDeclaration.DescendantNodes().OfType(); - found |= winrtRules.HasInvalidMethods(ref context, methods, interfaceDeclaration.Identifier); - } - - /* Check all structs */ - foreach (StructDeclarationSyntax structDeclaration in structs) - { - found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); - found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); - found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); - found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); - found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); - found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); - found |= winrtRules.StructHasFieldOfType(ref context, structDeclaration); - - var fields = structDeclaration.DescendantNodes().OfType(); - foreach (var field in fields) - { - found |= winrtRules.CheckFieldValidity(ref context, field, structDeclaration.Identifier, userCreatedTypes); - } - if (!fields.Any()) - { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticRules.StructWithNoFieldsRule, structDeclaration.GetLocation(), model.GetDeclaredSymbol(structDeclaration))); - found |= true; - } - } - } - return found; - } - - public void Execute(GeneratorExecutionContext context) - { - if (!IsCsWinRTComponent(context)) - { - return; - } - - Logger.Initialize(context); - - if (CatchWinRTDiagnostics(ref context)) - { - Logger.Log("Exiting early -- found errors in authored runtime component."); - Logger.Close(); - return; - } - - try - { - context.AddSource("System.Runtime.InteropServices.WindowsRuntime", SourceText.From(ArrayAttributes, Encoding.UTF8)); - - string assembly = GetAssemblyName(context); - string version = GetAssemblyVersion(context); - MetadataBuilder metadataBuilder = new MetadataBuilder(); - - var writer = new WinRTTypeWriter( - assembly, - version, - metadataBuilder); - foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) - { - writer.Model = context.Compilation.GetSemanticModel(tree); - writer.Visit(tree.GetRoot()); - } - writer.FinalizeGeneration(); - - string winmdFile = GetWinmdOutputFile(context); - - GenerateWinMD(metadataBuilder, winmdFile); - GenerateSources(context); - } - catch(Exception e) - { - Logger.Log(e.ToString()); - if(e.InnerException != null) - { - Logger.Log(e.InnerException.ToString()); - } - Logger.Close(); - throw; - } - - Logger.Log("Done"); - Logger.Close(); - } - - public void Initialize(GeneratorInitializationContext context) - { - } - } -} +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Reflection.PortableExecutable; +using System.Text; + +namespace Generator +{ + [Generator] + public class SourceGenerator : ISourceGenerator + { + private static readonly string ArrayAttributes = @" +namespace System.Runtime.InteropServices.WindowsRuntime +{ + [global::System.AttributeUsage(System.AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] + internal sealed class ReadOnlyArrayAttribute : global::System.Attribute + { + } + + [global::System.AttributeUsage(System.AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] + internal sealed class WriteOnlyArrayAttribute : global::System.Attribute + { + } +}"; + + private string _tempFolder; + + private static string GetAssemblyName(GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName); + return assemblyName; + } + + private static string GetAssemblyVersion(GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyVersion", out var assemblyVersion); + return assemblyVersion; + } + + internal static string GetGeneratedFilesDir(GeneratorExecutionContext context) + { + // TODO: determine correct location to write to. + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.GeneratedFilesDir", out var generatedFilesDir); + Directory.CreateDirectory(generatedFilesDir); + return generatedFilesDir; + } + + private static bool IsCsWinRTComponent(GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) + { + return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; + } + + return false; + } + + private static string GetCsWinRTExe(GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExe", out var cswinrtExe); + return cswinrtExe; + } + + private static bool GetKeepGeneratedSources(GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTKeepGeneratedSources", out var keepGeneratedSourcesStr); + return keepGeneratedSourcesStr != null && bool.TryParse(keepGeneratedSourcesStr, out var keepGeneratedSources) && keepGeneratedSources; + } + + private static string GetCsWinRTWindowsMetadata(GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWindowsMetadata", out var cswinrtWindowsMetadata); + return cswinrtWindowsMetadata; + } + + private string GetTempFolder(bool clearSourceFilesFromFolder = false) + { + if(_tempFolder == null || !File.Exists(_tempFolder)) + { + string outputDir = Path.Combine(Path.GetTempPath(), "CsWinRT", Path.GetRandomFileName()).TrimEnd('\\'); + Directory.CreateDirectory(outputDir); + _tempFolder = outputDir; + Logger.Log("Created temp folder: " + _tempFolder); + } + + if (clearSourceFilesFromFolder) + { + foreach (var file in Directory.GetFiles(_tempFolder, "*.cs", SearchOption.TopDirectoryOnly)) + { + Logger.Log("Clearing " + file); + File.Delete(file); + } + } + + return _tempFolder; + } + + private void GenerateSources(GeneratorExecutionContext context) + { + string cswinrtExe = GetCsWinRTExe(context); + string assemblyName = GetAssemblyName(context); + string winmdFile = GetWinmdOutputFile(context); + string outputDir = GetTempFolder(true); + string windowsMetadata = GetCsWinRTWindowsMetadata(context); + // TODO: support additional WinMD files from other projections. + + string arguments = string.Format("-component -input \"{0}\" -input {1} -include {2} -output \"{3}\" -verbose", winmdFile, windowsMetadata, assemblyName, outputDir); + Logger.Log("Running " + cswinrtExe + " " + arguments); + + var processInfo = new ProcessStartInfo + { + FileName = cswinrtExe, + Arguments = arguments, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + WindowStyle = ProcessWindowStyle.Hidden, + CreateNoWindow = true + }; + + try + { + using var cswinrtProcess = Process.Start(processInfo); + Logger.Log(cswinrtProcess.StandardOutput.ReadToEnd()); + Logger.Log(cswinrtProcess.StandardError.ReadToEnd()); + cswinrtProcess.WaitForExit(); + + if (cswinrtProcess.ExitCode != 0) + { + throw new Win32Exception(cswinrtProcess.ExitCode); + } + + foreach (var file in Directory.GetFiles(outputDir, "*.cs", SearchOption.TopDirectoryOnly)) + { + Logger.Log("Adding " + file); + context.AddSource(Path.GetFileNameWithoutExtension(file), SourceText.From(File.ReadAllText(file), Encoding.UTF8)); + } + } + finally + { + if (!GetKeepGeneratedSources(context)) + { + Directory.Delete(outputDir, true); + } + } + } + + private string GetWinmdOutputFile(GeneratorExecutionContext context) + { + return Path.Combine(GetGeneratedFilesDir(context), GetAssemblyName(context) + ".winmd"); + } + + private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile) + { + Logger.Log("Writing " + outputFile); + var managedPeBuilder = new ManagedPEBuilder( + new PEHeaderBuilder( + machine: Machine.I386, + imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll | Characteristics.Bit32Machine), + new MetadataRootBuilder(metadataBuilder, "WindowsRuntime 1.4"), + new BlobBuilder(), + flags: CorFlags.ILOnly); + + var peBlob = new BlobBuilder(); + managedPeBuilder.Serialize(peBlob); + + using var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write); + peBlob.WriteContentTo(fs); + } + + private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) + { + // "DiagnosticTests" is a workaround, GetAssemblyName returns null when used by unit tests + // shouldn't need workaround once we can pass AnalyzerConfigOptionsProvider in DiagnosticTests.Helpers.cs + string assemblyName = GetAssemblyName(context) ?? "DiagnosticTests"; + WinRTComponentScanner winrtScanner = new WinRTComponentScanner(context, assemblyName); + winrtScanner.FindDiagnostics(); + return winrtScanner.Found(); + } + + public void Execute(GeneratorExecutionContext context) + { + /* + if (!IsCsWinRTComponent(context)) + { + return; + } + */ + + Logger.Initialize(context); + + + if (CatchWinRTDiagnostics(context)) + { + Logger.Log("Exiting early -- found errors in authored runtime component."); + Logger.Close(); + return; + } + + try + { + context.AddSource("System.Runtime.InteropServices.WindowsRuntime", SourceText.From(ArrayAttributes, Encoding.UTF8)); + string assembly = GetAssemblyName(context); + string version = GetAssemblyVersion(context); + MetadataBuilder metadataBuilder = new MetadataBuilder(); + + var writer = new WinRTTypeWriter( + assembly, + version, + metadataBuilder); + foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) + { + writer.Model = context.Compilation.GetSemanticModel(tree); + writer.Visit(tree.GetRoot()); + } + writer.FinalizeGeneration(); + + string winmdFile = GetWinmdOutputFile(context); + + GenerateWinMD(metadataBuilder, winmdFile); + GenerateSources(context); + } + catch(Exception e) + { + Logger.Log(e.ToString()); + if(e.InnerException != null) + { + Logger.Log(e.InnerException.ToString()); + } + Logger.Close(); + throw; + } + + Logger.Log("Done"); + Logger.Close(); + } + + public void Initialize(GeneratorInitializationContext context) + { + } + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs similarity index 75% rename from src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs rename to src/Authoring/WinRT.SourceGenerator/WinRTRules.cs index 37afd84b9..bd79e8c5b 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs @@ -1,150 +1,177 @@ -using Microsoft.CodeAnalysis; - -namespace WinRT.SourceGenerator -{ - public class DiagnosticRules - { - /// Helper function that does most of the boilerplate information needed for Diagnostics - /// string, a short identifier for the diagnostic - /// string, a few words generally describing the diagnostic - /// string, describes the diagnostic -- formatted with {0}, ... -- - /// such that data can be passed in for the code the diagnostic is reported for - private static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) - { - return new DiagnosticDescriptor( - id: id, - title: title, - messageFormat: messageFormat, - category: "Usage", - /* Warnings dont fail command line build; winmd generation is prevented regardless of severity. - * Make this error when making final touches on this deliverable. */ - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - helpLinkUri: "https://docs.microsoft.com/en-us/previous-versions/hh977010(v=vs.110)"); - } - - public static DiagnosticDescriptor StructWithNoFieldsRule = MakeRule( - "WME1060", - "Empty struct rule", - "Structure {0} contains no public fields. Windows Runtime structures must contain at least one public field."); - - public static DiagnosticDescriptor AsyncRule = MakeRule( - "WME1084", - "Async Interfaces Rule", - "Runtime component class {0} cannot implement async interface {1}; use AsyncInfo class methods instead of async interfaces"); - - public static DiagnosticDescriptor ClassConstructorRule = MakeRule( - "WME1099", - "Class Constructor Rule", - "Runtime component class {0} cannot have multiple constructors of the same arity {1}"); - - public static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( - "WME1092", - "Parameter Named Value Rule", - "The method {0} has a parameter named {1} which is the same as the default return value name. " - + "Consider using another name for the parameter or use the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute " - + "to explicitly specify the name of the return value."); - - public static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( - "WME1060(b)", - "Private field in struct", - "Structure {0} has non-public field. All fields must be public for Windows Runtime structures."); - - public static DiagnosticDescriptor StructHasConstFieldRule = MakeRule( - "WME1060(b)", - "Const field in struct", - "Structure {0} has const field. Constants can only appear on Windows Runtime enumerations."); - - public static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( - "WME1060", - "Invalid field in struct", - "Structure {0} has field '{1}' of type {2}; {2} is not a valid Windows Runtime field type. Each field " - + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure."); - - public static DiagnosticDescriptor StructHasInvalidFieldRule2 = MakeRule( - "WME1060", - "Invalid field in struct", - "Structure {0} has a field of type {1}; {1} is not a valid Windows Runtime field type. Each field " - + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure."); - - public static DiagnosticDescriptor OperatorOverloadedRule = MakeRule( - "WME1087", - "Operator overload exposed", - "{0} is an operator overload. Managed types cannot expose operator overloads in the Windows Runtime"); - - public static DiagnosticDescriptor MethodOverload_MultipleDefaultAttribute = MakeRule( - "WME1059", - "Only one overload should be designated default", - "In class {2}: Multiple {0}-parameter overloads of '{1}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute. The attribute may only be applied to one overload of the method."); - - public static DiagnosticDescriptor MethodOverload_NeedDefaultAttribute = MakeRule( - "WME1085", - "Multiple overloads seen, one needs a default", // todo better msg - "In class {2}: The {0}-parameter overloads of {1} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); - - public static DiagnosticDescriptor ArraySignature_JaggedArrayRule = MakeRule( - "WME1036", - "Array signature found with jagged array, which is not a valid WinRT type", - "Method {0} has a nested array of type {1} in its signature. Arrays in Windows Runtime method signature cannot be nested."); - - public static DiagnosticDescriptor ArraySignature_MultiDimensionalArrayRule = MakeRule( - "WME1035", - "Array signature found with multi-dimensional array, which is not a valid WinRT type", - "Method '{0}' has a multi-dimensional array of type '{1}' in its signature. Arrays in Windows Runtime method signatures must be one dimensional."); - - public static DiagnosticDescriptor ArraySignature_SystemArrayRule = MakeRule( - "WME1034", - "Array signature found with System.Array instance, which is not a valid WinRT type", - "In type {0}: the method {1} has signature that contains a System.Array instance; SystemArray is not a valid Windows Runtime type. Try using a different type like IList"); - - public static DiagnosticDescriptor RefParameterFound = MakeRule( - "WME", - "Parameter passed by reference", - "Method '{0}' has parameter '{1}' marked `ref`. Reference parameters are not allowed in Windows Runtime."); - - public static DiagnosticDescriptor ArrayMarkedInOrOut = MakeRule( - "WME1103", - "Array parameter marked InAttribute or OutAttribute", - "Method '{0}' has parameter '{1}' which is an array, and which has either a " - + "System.Runtime.InteropServices.InAttribute or a System.Runtime.InteropServices.OutAttribute. " - + "In the Windows Runtime, array parameters must have either ReadOnlyArray or WriteOnlyArray. " - + "Please remove these attributes or replace them with the appropriate Windows " - + "Runtime attribute if necessary."); - - public static DiagnosticDescriptor NonArrayMarkedInOrOut = MakeRule( - "WME1105", - "Parameter (not array type) marked InAttribute or OutAttribute", - "Method '{0}' has parameter '{1}' with a System.Runtime.InteropServices.InAttribute " - + "or System.Runtime.InteropServices.OutAttribute.Windows Runtime does not support " - + "marking parameters with System.Runtime.InteropServices.InAttribute or " - + "System.Runtime.InteropServices.OutAttribute. Please consider removing " - + "System.Runtime.InteropServices.InAttribute and replace " - + "System.Runtime.InteropServices.OutAttribute with 'out' modifier instead."); - - public static DiagnosticDescriptor ArrayParamMarkedBoth = MakeRule( - "WME1101", - "Array paramter marked both ReadOnlyArray and WriteOnlyArray", - "Method '{0}' has parameter '{1}' which is an array, and which has both ReadOnlyArray and WriteOnlyArray. " - + "In the Windows Runtime, the contents array parameters must be either readable " - + "or writable.Please remove one of the attributes from '{1}'."); - - public static DiagnosticDescriptor ArrayOutputParamMarkedRead = MakeRule( - "WME1102", - "Array parameter marked `out` and ReadOnlyArray", - "Method '{0}' has an output parameter '{1}' which is an array, but which has ReadOnlyArray attribute. In the Windows Runtime, " - + "the contents of output arrays are writable.Please remove the attribute from '{1}'."); - - public static DiagnosticDescriptor ArrayParamNotMarked = MakeRule( - "WME1106", - "Array parameter not marked ReadOnlyArray or WriteOnlyArray way", - "Method '{0}' has parameter '{1}' which is an array. In the Windows Runtime, the " - + "contents of array parameters must be either readable or writable.Please apply either ReadOnlyArray or WriteOnlyArray to '{1}'."); - - public static DiagnosticDescriptor NonArrayMarked = MakeRule( - "WME1104", - "Non-array parameter marked with ReadOnlyArray or WriteOnlyArray", - "Method '{0}' has parameter '{1}' which is not an array, and which has either a " - + "ReadOnlyArray attribute or a WriteOnlyArray attribute . Windows Runtime does " - + "not support marking non-array parameters with ReadOnlyArray or WriteOnlyArray."); - } -} +using Microsoft.CodeAnalysis; + +namespace WinRT.SourceGenerator +{ + public class WinRTRules + { + /// Helper function that does most of the boilerplate information needed for Diagnostics + /// string, a short identifier for the diagnostic + /// string, a few words generally describing the diagnostic + /// string, describes the diagnostic -- formatted with {0}, ... -- + /// such that data can be passed in for the code the diagnostic is reported for + private static DiagnosticDescriptor MakeRule(string id, string title, string messageFormat) + { + return new DiagnosticDescriptor( + id: id, + title: title, + messageFormat: messageFormat, + category: "Usage", + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true, + helpLinkUri: "https://docs.microsoft.com/en-us/previous-versions/hh977010(v=vs.110)"); + } + + public static DiagnosticDescriptor DisjointNamespaceRule = MakeRule( + "WME1044", + "Namespace is disjoint from main (winmd) namespace", + "A public type has a namespace ('{1}') that shares no common prefix with other namespaces ('{0}'). " + + "All types within a Windows Metadata file must exist in a sub namespace of the namespace that is " + + "implied by the file name."); + + public static DiagnosticDescriptor NamespacesDifferByCase = MakeRule( + "WME1067", + "Namespace names cannot differ only by case", + "Multiple namespaces found with the name '{0}', namespace names cannot differ only by case."); + + public static DiagnosticDescriptor NoPublicTypesRule = MakeRule( + "WME1042", + "No public types defined", + "Windows Runtime components must have at least one public type"); + + public static DiagnosticDescriptor GenericTypeRule = MakeRule( + "WME", + "Class (or interface) is generic", + "Type {0} is generic. Windows Runtime types cannot be generic."); + + + public static DiagnosticDescriptor UnsealedClassRule = MakeRule( + "WME", + "Class is unsealed", + "Exporting unsealed types is not supported. Please mark type {0} as sealed."); + + public static DiagnosticDescriptor UnsupportedTypeRule = MakeRule( + "WME", + "Exposing unsupported type", + "The member '{0}' has the type '{1}' in its signature. The type '{1}' is not a valid Windows Runtime type\n" + + "Yet, the type (or its generic parameters) implement interfaces that are valid Windows Runtime types\n" + + "Consider changing the type '{1} in the member signature to one of the following types from System.Collections.Generic:\n{2}"); + + public static DiagnosticDescriptor StructWithNoFieldsRule = MakeRule( + "WME1060", + "Empty struct rule", + "Structure {0} contains no public fields. Windows Runtime structures must contain at least one public field."); + + public static DiagnosticDescriptor NonWinRTInterface = MakeRule( + "WME1084", + "Invalid Interface Inherited", + "Runtime component class {0} cannot implement interface {1}, as the interface is not a valid Windows Runtime interface"); + + public static DiagnosticDescriptor ClassConstructorRule = MakeRule( + "WME1099", + "Class Constructor Rule", + "Runtime component class {0} cannot have multiple constructors of the same arity {1}"); + + public static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( + "WME1092", + "Parameter Named Value Rule", + "The method {0} has a parameter named {1} which is the same as the default return value name. " + + "Consider using another name for the parameter or use the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute " + + "to explicitly specify the name of the return value."); + + public static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( + "WME1060(b)", + "Private field in struct", + "Structure {0} has non-public field. All fields must be public for Windows Runtime structures."); + + public static DiagnosticDescriptor StructHasConstFieldRule = MakeRule( + "WME1060(b)", + "Const field in struct", + "Structure {0} has const field. Constants can only appear on Windows Runtime enumerations."); + + public static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( + "WME1060", + "Invalid field in struct", + "Structure {0} has field of type {1}; {1} is not a valid Windows Runtime field type. Each field " + + "in a Windows Runtime structure can only be UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, or itself a structure."); + + public static DiagnosticDescriptor OperatorOverloadedRule = MakeRule( + "WME1087", + "Operator overload exposed", + "{0} is an operator overload. Managed types cannot expose operator overloads in the Windows Runtime"); + + public static DiagnosticDescriptor MultipleDefaultOverloadAttribute = MakeRule( + "WME1059", + "Only one overload should be designated default", + "In class {2}: Multiple {0}-parameter overloads of '{1}' are decorated with Windows.Foundation.Metadata.DefaultOverloadAttribute. The attribute may only be applied to one overload of the method."); + + public static DiagnosticDescriptor NeedDefaultOverloadAttribute = MakeRule( + "WME1085", + "Multiple overloads seen, one needs a default", // todo better msg + "In class {2}: The {0}-parameter overloads of {1} must have exactly one method specified as the default overload by decorating it with Windows.Foundation.Metadata.DefaultOverloadAttribute."); + + public static DiagnosticDescriptor JaggedArrayRule = MakeRule( + "WME1036", + "Array signature found with jagged array, which is not a valid WinRT type", + "Method {0} has a nested array of type {1} in its signature. Arrays in Windows Runtime method signature cannot be nested."); + + public static DiagnosticDescriptor MultiDimensionalArrayRule = MakeRule( + "WME1035", + "Array signature found with multi-dimensional array, which is not a valid WinRT type", + "Method '{0}' has a multi-dimensional array of type '{1}' in its signature. Arrays in Windows Runtime method signatures must be one dimensional."); + + public static DiagnosticDescriptor ArraySignature_SystemArrayRule = MakeRule( + "WME1034", + "Array signature found with System.Array instance, which is not a valid WinRT type", + "In type {0}: the method {1} has signature that contains a System.Array instance; SystemArray is not a valid Windows Runtime type. Try using a different type like IList"); + + public static DiagnosticDescriptor RefParameterFound = MakeRule( + "WME", + "Parameter passed by reference", + "Method '{0}' has parameter '{1}' marked `ref`. Reference parameters are not allowed in Windows Runtime."); + + public static DiagnosticDescriptor ArrayMarkedInOrOut = MakeRule( + "WME1103", + "Array parameter marked InAttribute or OutAttribute", + "Method '{0}' has parameter '{1}' which is an array, and which has either a " + + "System.Runtime.InteropServices.InAttribute or a System.Runtime.InteropServices.OutAttribute. " + + "In the Windows Runtime, array parameters must have either ReadOnlyArray or WriteOnlyArray. " + + "Please remove these attributes or replace them with the appropriate Windows " + + "Runtime attribute if necessary."); + + public static DiagnosticDescriptor NonArrayMarkedInOrOut = MakeRule( + "WME1105", + "Parameter (not array type) marked InAttribute or OutAttribute", + "Method '{0}' has parameter '{1}' with a System.Runtime.InteropServices.InAttribute " + + "or System.Runtime.InteropServices.OutAttribute.Windows Runtime does not support " + + "marking parameters with System.Runtime.InteropServices.InAttribute or " + + "System.Runtime.InteropServices.OutAttribute. Please consider removing " + + "System.Runtime.InteropServices.InAttribute and replace " + + "System.Runtime.InteropServices.OutAttribute with 'out' modifier instead."); + + public static DiagnosticDescriptor ArrayParamMarkedBoth = MakeRule( + "WME1101", + "Array paramter marked both ReadOnlyArray and WriteOnlyArray", + "Method '{0}' has parameter '{1}' which is an array, and which has both ReadOnlyArray and WriteOnlyArray. " + + "In the Windows Runtime, the contents array parameters must be either readable " + + "or writable.Please remove one of the attributes from '{1}'."); + + public static DiagnosticDescriptor ArrayOutputParamMarkedRead = MakeRule( + "WME1102", + "Array parameter marked `out` and ReadOnlyArray", + "Method '{0}' has an output parameter '{1}' which is an array, but which has ReadOnlyArray attribute. In the Windows Runtime, " + + "the contents of output arrays are writable.Please remove the attribute from '{1}'."); + + public static DiagnosticDescriptor ArrayParamNotMarked = MakeRule( + "WME1106", + "Array parameter not marked ReadOnlyArray or WriteOnlyArray way", + "Method '{0}' has parameter '{1}' which is an array. In the Windows Runtime, the " + + "contents of array parameters must be either readable or writable.Please apply either ReadOnlyArray or WriteOnlyArray to '{1}'."); + + public static DiagnosticDescriptor NonArrayMarked = MakeRule( + "WME1104", + "Non-array parameter marked with ReadOnlyArray or WriteOnlyArray", + "Method '{0}' has parameter '{1}' which is not an array, and which has either a " + + "ReadOnlyArray attribute or a WriteOnlyArray attribute . Windows Runtime does " + + "not support marking non-array parameters with ReadOnlyArray or WriteOnlyArray."); + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs index fc1d5bd49..d6b94f48a 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs @@ -232,7 +232,7 @@ public void AddInterfaceImpl(ISymbol node, InterfaceImplementationHandle handle) class WinRTTypeWriter : CSharpSyntaxWalker { - private struct MappedType + internal struct MappedType { private readonly string @namespace; private readonly string name; @@ -269,7 +269,7 @@ public MappedType(Func multipleMa } // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. - private static readonly Dictionary MappedCSharpTypes = new Dictionary() + internal static readonly Dictionary MappedCSharpTypes = new Dictionary() { { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true) }, { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true) }, @@ -311,7 +311,7 @@ public MappedType(Func multipleMa { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, }; - private static readonly List ImplementedInterfacesWithoutMapping = new List() + internal static readonly List ImplementedInterfacesWithoutMapping = new List() { "System.Collections.Generic.ICollection`1", "System.Collections.Generic.IReadOnlyCollection`1", @@ -963,7 +963,7 @@ private TypeDefinitionHandle AddTypeDefinition( // Based on whether System.Type is used in an attribute declaration or elsewhere, we need to choose the correct custom mapping // as attributes don't use the TypeName mapping. - private static (string, string, string, bool, bool) GetSystemTypeCustomMapping(ISymbol containingSymbol) + internal static (string, string, string, bool, bool) GetSystemTypeCustomMapping(ISymbol containingSymbol) { bool isDefinedInAttribute = containingSymbol != null && (containingSymbol as INamedTypeSymbol).BaseType?.ToString() == "System.Attribute"; From 0c8d7544cd7d1073e470b41443ad7d0e9c981a46 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Wed, 30 Dec 2020 15:44:08 -0800 Subject: [PATCH 40/41] uncomment cswinrt component --- src/Authoring/WinRT.SourceGenerator/Generator.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index 50e2bd56a..00c5e7328 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -185,12 +185,10 @@ private bool CatchWinRTDiagnostics(GeneratorExecutionContext context) public void Execute(GeneratorExecutionContext context) { - /* if (!IsCsWinRTComponent(context)) { return; } - */ Logger.Initialize(context); From d91f1f589bd746dfb06288dee72b2c252931fc48 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Wed, 30 Dec 2020 15:54:18 -0800 Subject: [PATCH 41/41] cruft --- src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs | 5 ++--- src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs index 3148c7366..6fd4869b8 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs @@ -65,7 +65,7 @@ private void ImplementsInvalidInterface(INamedTypeSymbol typeSymbol, TypeDeclara { bool AsyncActionCase(INamedTypeSymbol sym) { - // using Windows.Foundation.IAsyncAction ? + // are we using Windows.Foundation.IAsyncAction ? bool isWindowsFoundation = sym.ContainingNamespace.IsGlobalNamespace || sym.ContainingNamespace.Name == "Windows.Foundation"; bool isAsyncAction = sym.MetadataName == "IAsyncAction"; return isWindowsFoundation && isAsyncAction; @@ -89,7 +89,6 @@ bool AsyncActionCase(INamedTypeSymbol sym) foreach (string prohibitedInterface in nonWindowsRuntimeInterfaces) { - // check here if typesymbol's basetype is invalid ? but interfaces are also base types? if (ImplementsInterface(typeSymbol, prohibitedInterface)) { Report(WinRTRules.NonWinRTInterface, typeDeclaration.GetLocation(), typeDeclaration.Identifier, prohibitedInterface); @@ -314,7 +313,7 @@ private TypeCollector CollectDefinedTypes(GeneratorExecutionContext context) foreach (SyntaxTree tree in context.Compilation.SyntaxTrees) { - var model = context.Compilation.GetSemanticModel(tree); + var model = GetModel(tree); var classes = tree.GetRoot().DescendantNodes().OfType().Where(IsPublic); foreach (var @class in classes) diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index ea8665486..da3f0fa19 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -299,7 +299,6 @@ private void CheckStructFields(StructDeclarationSyntax @struct) /// Namespaces can't only differ by cases, also check if the name is invalid for the winmd being made private void HasInvalidNamespace() { - // instead of this, see if != but are equal when ignoring case HashSet simplifiedNames = new HashSet(); foreach (var namespaceSymbol in _typeHolder.GetNamespaces())