From 7a31b0b5ab7424ae91f63db0a90cba963332b7fa Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 19 Jan 2021 14:35:18 -0800 Subject: [PATCH 1/9] update diagnostic messages --- .../WinRT.SourceGenerator/WinRTRules.cs | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs index 9c9050cea..13cffc447 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs @@ -21,10 +21,16 @@ 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 ImplementerUseSameVariableName = MakeRule( + "WME1113", + "Class implementaiton method should use same paramter as interface method", + "Class '{0}' implements method '{1}' with parameter '{2}', but '{1}' was declared in interface '{3}' with parameter '{4}'." + + "Parameter names must match exactly in the Windows Runtime."); + public static DiagnosticDescriptor PrivateGetterRule = MakeRule( "WME", "Property must have public getter", - "Property '{0}' does not have a public getter method. Windows Metadata does not support setter-only properties."); + "Property '{0}' does not have a public getter method. Windows Runtime does not support setter-only properties."); public static DiagnosticDescriptor DisjointNamespaceRule = MakeRule( "WME1044", @@ -36,7 +42,7 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes 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."); + "Multiple namespaces found with the name '{0}'; namespace names cannot differ only by case in the Windows Runtime."); public static DiagnosticDescriptor NoPublicTypesRule = MakeRule( "WME1042", @@ -52,7 +58,7 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor UnsealedClassRule = MakeRule( "WME", "Class is unsealed", - "Exporting unsealed types is not supported. Please mark type {0} as sealed."); + "Exporting unsealed types is not supported in Windows Runtime. Please mark type {0} as sealed."); public static DiagnosticDescriptor UnsupportedTypeRule = MakeRule( "WME", @@ -69,19 +75,19 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes 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"); + "Windows 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}"); + "Classes cannot have multiple constructors of the same arity in the Windows Runtime, class {0} has multiple {1}-arity constructors"); 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."); + "The method {0} is used in the Windows Runtime and has a parameter named {1}." + + "This is the same as the return value name used in the C#/WinRT interop. " + + "Consider using another name for the parameter or the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute"); public static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( "WME1060(b)", @@ -107,12 +113,14 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes 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."); + "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."); + "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", @@ -121,13 +129,14 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor MultiDimensionalArrayRule = MakeRule( "WME1035", - "Array signature found with multi-dimensional array, which is not a valid WinRT type", + "Array signature found with multi-dimensional array, which is not a valid Windows Runtime 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"); + "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", @@ -176,7 +185,7 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes "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 " + + "ReadOnlyArray attribute or a WriteOnlyArray attribute. Windows Runtime does " + "not support marking non-array parameters with ReadOnlyArray or WriteOnlyArray."); } } From ea2ac3261a6f14f232772287ba501c02653d0ded Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Thu, 21 Jan 2021 16:03:20 -0800 Subject: [PATCH 2/9] change wme to cswinrt --- .../WinRT.SourceGenerator/WinRTRules.cs | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs index 13cffc447..c2d646ef7 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs @@ -22,129 +22,129 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes } public static DiagnosticDescriptor ImplementerUseSameVariableName = MakeRule( - "WME1113", + "CsWinRT1113", "Class implementaiton method should use same paramter as interface method", "Class '{0}' implements method '{1}' with parameter '{2}', but '{1}' was declared in interface '{3}' with parameter '{4}'." + "Parameter names must match exactly in the Windows Runtime."); public static DiagnosticDescriptor PrivateGetterRule = MakeRule( - "WME", + "CsWinRT", "Property must have public getter", "Property '{0}' does not have a public getter method. Windows Runtime does not support setter-only properties."); public static DiagnosticDescriptor DisjointNamespaceRule = MakeRule( - "WME1044", + "CsWinRT1044", "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", + "CsWinRT1067", "Namespace names cannot differ only by case", "Multiple namespaces found with the name '{0}'; namespace names cannot differ only by case in the Windows Runtime."); public static DiagnosticDescriptor NoPublicTypesRule = MakeRule( - "WME1042", + "CsWinRT1042", "No public types defined", "Windows Runtime components must have at least one public type"); public static DiagnosticDescriptor GenericTypeRule = MakeRule( - "WME", + "CsWinRT", "Class (or interface) is generic", "Type {0} is generic. Windows Runtime types cannot be generic."); public static DiagnosticDescriptor UnsealedClassRule = MakeRule( - "WME", + "CsWinRT", "Class is unsealed", "Exporting unsealed types is not supported in Windows Runtime. Please mark type {0} as sealed."); public static DiagnosticDescriptor UnsupportedTypeRule = MakeRule( - "WME", + "CsWinRT", "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", + "CsWinRT1060", "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", + "CsWinRT1084", "Invalid Interface Inherited", "Windows Runtime component class {0} cannot implement interface {1}, as the interface is not a valid Windows Runtime interface"); public static DiagnosticDescriptor ClassConstructorRule = MakeRule( - "WME1099", + "CsWinRT1099", "Class Constructor Rule", "Classes cannot have multiple constructors of the same arity in the Windows Runtime, class {0} has multiple {1}-arity constructors"); public static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( - "WME1092", + "CsWinRT1092", "Parameter Named Value Rule", "The method {0} is used in the Windows Runtime and has a parameter named {1}." + "This is the same as the return value name used in the C#/WinRT interop. " + "Consider using another name for the parameter or the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute"); public static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( - "WME1060(b)", + "CsWinRT1060(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)", + "CsWinRT1060(b)", "Const field in struct", "Structure {0} has const field. Constants can only appear on Windows Runtime enumerations."); public static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( - "WME1060", + "CsWinRT1060", "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", + "CsWinRT1087", "Operator overload exposed", "{0} is an operator overload. Managed types cannot expose operator overloads in the Windows Runtime"); public static DiagnosticDescriptor MultipleDefaultOverloadAttribute = MakeRule( - "WME1059", + "CsWinRT1059", "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", + "CsWinRT1085", "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", + "CsWinRT1036", "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", + "CsWinRT1035", "Array signature found with multi-dimensional array, which is not a valid Windows Runtime 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", + "CsWinRT1034", "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", + "CsWinRT", "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", + "CsWinRT1103", "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. " @@ -153,7 +153,7 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes + "Runtime attribute if necessary."); public static DiagnosticDescriptor NonArrayMarkedInOrOut = MakeRule( - "WME1105", + "CsWinRT1105", "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 " @@ -163,26 +163,26 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes + "System.Runtime.InteropServices.OutAttribute with 'out' modifier instead."); public static DiagnosticDescriptor ArrayParamMarkedBoth = MakeRule( - "WME1101", + "CsWinRT1101", "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", + "CsWinRT1102", "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", + "CsWinRT1106", "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", + "CsWinRT1104", "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 " From fc2f2b63c0431dc84a3f2eb949fa984fa2c427ac Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 22 Jan 2021 07:15:58 -0800 Subject: [PATCH 3/9] feedback --- .../WinRT.SourceGenerator/WinRTRules.cs | 72 +++++++++---------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs index c2d646ef7..ee2569e9a 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs @@ -21,130 +21,122 @@ 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 ImplementerUseSameVariableName = MakeRule( - "CsWinRT1113", - "Class implementaiton method should use same paramter as interface method", - "Class '{0}' implements method '{1}' with parameter '{2}', but '{1}' was declared in interface '{3}' with parameter '{4}'." - + "Parameter names must match exactly in the Windows Runtime."); - public static DiagnosticDescriptor PrivateGetterRule = MakeRule( - "CsWinRT", + "CsWinRT1000", "Property must have public getter", "Property '{0}' does not have a public getter method. Windows Runtime does not support setter-only properties."); public static DiagnosticDescriptor DisjointNamespaceRule = MakeRule( - "CsWinRT1044", + "CsWinRT1001", "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( - "CsWinRT1067", + "CsWinRT1002", "Namespace names cannot differ only by case", "Multiple namespaces found with the name '{0}'; namespace names cannot differ only by case in the Windows Runtime."); public static DiagnosticDescriptor NoPublicTypesRule = MakeRule( - "CsWinRT1042", + "CsWinRT1003", "No public types defined", "Windows Runtime components must have at least one public type"); public static DiagnosticDescriptor GenericTypeRule = MakeRule( - "CsWinRT", + "CsWinRT1004", "Class (or interface) is generic", "Type {0} is generic. Windows Runtime types cannot be generic."); - public static DiagnosticDescriptor UnsealedClassRule = MakeRule( - "CsWinRT", + "CsWinRT1005", "Class is unsealed", - "Exporting unsealed types is not supported in Windows Runtime. Please mark type {0} as sealed."); + "Exporting unsealed types is not supported in CsWinRT. Please mark type {0} as sealed."); public static DiagnosticDescriptor UnsupportedTypeRule = MakeRule( - "CsWinRT", + "CsWinRT1006", "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( - "CsWinRT1060", + "CsWinRT1007", "Empty struct rule", "Structure {0} contains no public fields. Windows Runtime structures must contain at least one public field."); public static DiagnosticDescriptor NonWinRTInterface = MakeRule( - "CsWinRT1084", + "CsWinRT1008", "Invalid Interface Inherited", "Windows Runtime component class {0} cannot implement interface {1}, as the interface is not a valid Windows Runtime interface"); public static DiagnosticDescriptor ClassConstructorRule = MakeRule( - "CsWinRT1099", + "CsWinRT1009", "Class Constructor Rule", "Classes cannot have multiple constructors of the same arity in the Windows Runtime, class {0} has multiple {1}-arity constructors"); public static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( - "CsWinRT1092", + "CsWinRT1010", "Parameter Named Value Rule", "The method {0} is used in the Windows Runtime and has a parameter named {1}." + - "This is the same as the return value name used in the C#/WinRT interop. " - + "Consider using another name for the parameter or the System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute"); + "The parameter name {1} is the same as the return value name used in the generated C#/WinRT interop; use a different parameter name."); public static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( - "CsWinRT1060(b)", + "CsWinRT1011", "Private field in struct", "Structure {0} has non-public field. All fields must be public for Windows Runtime structures."); public static DiagnosticDescriptor StructHasConstFieldRule = MakeRule( - "CsWinRT1060(b)", + "CsWinRT1012", "Const field in struct", "Structure {0} has const field. Constants can only appear on Windows Runtime enumerations."); public static DiagnosticDescriptor StructHasInvalidFieldRule = MakeRule( - "CsWinRT1060", + "CsWinRT1013", "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( - "CsWinRT1087", + "CsWinRT1014", "Operator overload exposed", "{0} is an operator overload. Managed types cannot expose operator overloads in the Windows Runtime"); public static DiagnosticDescriptor MultipleDefaultOverloadAttribute = MakeRule( - "CsWinRT1059", + "CsWinRT1015", "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( - "CsWinRT1085", + "CsWinRT1016", "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 " + "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( - "CsWinRT1036", + "CsWinRT1017", "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( - "CsWinRT1035", + "CsWinRT1018", "Array signature found with multi-dimensional array, which is not a valid Windows Runtime 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( - "CsWinRT1034", + "CsWinRT1019", "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( - "CsWinRT", + "CsWinRT1020", "Parameter passed by reference", "Method '{0}' has parameter '{1}' marked `ref`. Reference parameters are not allowed in Windows Runtime."); public static DiagnosticDescriptor ArrayMarkedInOrOut = MakeRule( - "CsWinRT1103", + "CsWinRT1021", "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. " @@ -153,7 +145,7 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes + "Runtime attribute if necessary."); public static DiagnosticDescriptor NonArrayMarkedInOrOut = MakeRule( - "CsWinRT1105", + "CsWinRT1022", "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 " @@ -163,29 +155,29 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes + "System.Runtime.InteropServices.OutAttribute with 'out' modifier instead."); public static DiagnosticDescriptor ArrayParamMarkedBoth = MakeRule( - "CsWinRT1101", + "CsWinRT1023", "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( - "CsWinRT1102", + "CsWinRT1024", "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( - "CsWinRT1106", + "CsWinRT1025", "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( - "CsWinRT1104", + "CsWinRT1026", "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."); - } -} + } +} From fd9d6acb4f6d4c2460fb4a75e94a6326ba986afc Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 22 Jan 2021 07:53:02 -0800 Subject: [PATCH 4/9] update gitignore, add analyzer release files, update unittests for new diagnostic identifer (wme -> cswinrt) --- .gitignore | 3 +- .../AnalyzerReleases.Shipped.md | 3 + .../AnalyzerReleases.Unshipped.md | 33 +++++ .../WinRT.SourceGenerator.csproj | 8 +- src/Tests/DiagnosticTests/UnitTesting.cs | 131 +++++++++--------- 5 files changed, 111 insertions(+), 67 deletions(-) create mode 100644 src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Shipped.md create mode 100644 src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Unshipped.md diff --git a/.gitignore b/.gitignore index 1f60a7cac..8af89441e 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ global.json nuget/Microsoft.Windows.CsWinRT.Prerelease.targets *.binlog vs_buildtools.exe -.buildtools \ No newline at end of file +.buildtools +**(Package)* diff --git a/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Shipped.md b/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Shipped.md new file mode 100644 index 000000000..a15fff7ab --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Shipped.md @@ -0,0 +1,3 @@ +; Shipped analyzer releases +; https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md + diff --git a/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Unshipped.md b/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Unshipped.md new file mode 100644 index 000000000..33e12fae4 --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Unshipped.md @@ -0,0 +1,33 @@ +; Unshipped analyzer release +; https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md + +### New Rules +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +CsWinRT1000 | Usage | Error | WinRTRules +CsWinRT1001 | Usage | Error | WinRTRules +CsWinRT1002 | Usage | Error | WinRTRules +CsWinRT1003 | Usage | Error | WinRTRules +CsWinRT1004 | Usage | Error | WinRTRules +CsWinRT1005 | Usage | Error | WinRTRules +CsWinRT1006 | Usage | Error | WinRTRules +CsWinRT1007 | Usage | Error | WinRTRules +CsWinRT1008 | Usage | Error | WinRTRules +CsWinRT1009 | Usage | Error | WinRTRules +CsWinRT1010 | Usage | Error | WinRTRules +CsWinRT1011 | Usage | Error | WinRTRules +CsWinRT1012 | Usage | Error | WinRTRules +CsWinRT1013 | Usage | Error | WinRTRules +CsWinRT1014 | Usage | Error | WinRTRules +CsWinRT1015 | Usage | Error | WinRTRules +CsWinRT1016 | Usage | Error | WinRTRules +CsWinRT1017 | Usage | Error | WinRTRules +CsWinRT1018 | Usage | Error | WinRTRules +CsWinRT1019 | Usage | Error | WinRTRules +CsWinRT1020 | Usage | Error | WinRTRules +CsWinRT1021 | Usage | Error | WinRTRules +CsWinRT1022 | Usage | Error | WinRTRules +CsWinRT1023 | Usage | Error | WinRTRules +CsWinRT1024 | Usage | Error | WinRTRules +CsWinRT1025 | Usage | Error | WinRTRules +CsWinRT1026 | Usage | Error | WinRTRules \ No newline at end of file diff --git a/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj b/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj index 89e272957..833b07029 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj +++ b/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj @@ -21,5 +21,11 @@ - + + + + + + + diff --git a/src/Tests/DiagnosticTests/UnitTesting.cs b/src/Tests/DiagnosticTests/UnitTesting.cs index e60f6d056..18e93248e 100644 --- a/src/Tests/DiagnosticTests/UnitTesting.cs +++ b/src/Tests/DiagnosticTests/UnitTesting.cs @@ -10,36 +10,36 @@ 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] + /* 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] */ /// @@ -47,19 +47,20 @@ [this is a workaround until we can pass AnalyzerConfigOptions in `Helpers.cs` fi /// from the cswinrt source generator based on the given source code /// [Test, TestCaseSource(nameof(ValidCases))] - public void CheckNoDiagnostic(string source) + private 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); + + var WinRTDiagnostics = diagnosticsFound.Where(diag => diag.Id.StartsWith("CsWinRT")); + if (WinRTDiagnostics.Count() != 0) + { + string foundDiagnostics = ""; + foreach (var d in WinRTDiagnostics) + { + foundDiagnostics += d.Descriptor.Description + "\n"; + } + throw new System.Exception("Expected no diagnostics. But found:" + foundDiagnostics); } } @@ -68,23 +69,23 @@ public void CheckNoDiagnostic(string source) /// 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) + private 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.Contains(rule)) + { + if (diagDescsFound.Count != 0) + { + string foundDiagnostics = ""; + foreach (var d in diagDescsFound) + { + foundDiagnostics += d.Description + "\n"; + } + throw new System.Exception("Didn't find the expected diagnostic, found:\n" + foundDiagnostics); } - if (diagDescsFound.Count != 0) - { - throw new System.Exception("Didn't find the expected diagnostic, found:\n" + builder); - } - else + else { throw new System.Exception("No diagnostics found."); } @@ -277,19 +278,19 @@ private static IEnumerable InvalidCases 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"); - + 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]"); @@ -310,7 +311,7 @@ private static IEnumerable InvalidCases 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"); From 0e9c04d1daea84e86062ed7811c6c3aedac67e77 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 22 Jan 2021 08:14:47 -0800 Subject: [PATCH 5/9] Add notes to rules in AnalyzerReleases --- .../AnalyzerReleases.Unshipped.md | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Unshipped.md b/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Unshipped.md index 33e12fae4..9644eb9e1 100644 --- a/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Unshipped.md +++ b/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Unshipped.md @@ -4,30 +4,30 @@ ### New Rules Rule ID | Category | Severity | Notes --------|----------|----------|------- -CsWinRT1000 | Usage | Error | WinRTRules -CsWinRT1001 | Usage | Error | WinRTRules -CsWinRT1002 | Usage | Error | WinRTRules -CsWinRT1003 | Usage | Error | WinRTRules -CsWinRT1004 | Usage | Error | WinRTRules -CsWinRT1005 | Usage | Error | WinRTRules -CsWinRT1006 | Usage | Error | WinRTRules -CsWinRT1007 | Usage | Error | WinRTRules -CsWinRT1008 | Usage | Error | WinRTRules -CsWinRT1009 | Usage | Error | WinRTRules -CsWinRT1010 | Usage | Error | WinRTRules -CsWinRT1011 | Usage | Error | WinRTRules -CsWinRT1012 | Usage | Error | WinRTRules -CsWinRT1013 | Usage | Error | WinRTRules -CsWinRT1014 | Usage | Error | WinRTRules -CsWinRT1015 | Usage | Error | WinRTRules -CsWinRT1016 | Usage | Error | WinRTRules -CsWinRT1017 | Usage | Error | WinRTRules -CsWinRT1018 | Usage | Error | WinRTRules -CsWinRT1019 | Usage | Error | WinRTRules -CsWinRT1020 | Usage | Error | WinRTRules -CsWinRT1021 | Usage | Error | WinRTRules -CsWinRT1022 | Usage | Error | WinRTRules -CsWinRT1023 | Usage | Error | WinRTRules -CsWinRT1024 | Usage | Error | WinRTRules -CsWinRT1025 | Usage | Error | WinRTRules -CsWinRT1026 | Usage | Error | WinRTRules \ No newline at end of file +CsWinRT1000 | Usage | Error | Property should have public `get` method +CsWinRT1001 | Usage | Error | Namespaces should match the assembly namespace or be child namespaces of the assembly namespace +CsWinRT1002 | Usage | Error | Namespaces cannot differ only by case +CsWinRT1003 | Usage | Error | Component must have at least on public type +CsWinRT1004 | Usage | Error | Public types cannot be generic +CsWinRT1005 | Usage | Error | Classes exposed to CsWinRT should be sealed +CsWinRT1006 | Usage | Error | Do not expose unsupported type +CsWinRT1007 | Usage | Error | Structs should contain at least one public field +CsWinRT1008 | Usage | Error | Interfaces should not inherit interfaces that are not valid in Windows Runtime +CsWinRT1009 | Usage | Error | Class should not have multiple constructors that take the same amount of parameters +CsWinRT1010 | Usage | Error | Methods should not use parameter names that conflict with generated parameter names +CsWinRT1011 | Usage | Error | Structs should not have private fields +CsWinRT1012 | Usage | Error | Structs should not have a constant field +CsWinRT1013 | Usage | Error | Structs should only contain basic types or other structs +CsWinRT1014 | Usage | Error | Types should not overload an operator +CsWinRT1015 | Usage | Error | Do not use `DefaultOverloadAttribute` more than once for a set of overloads +CsWinRT1016 | Usage | Error | Exactly one overload should be marked as DefaultOverload +CsWinRT1017 | Usage | Error | Array types should be one dimensional, not jagged +CsWinRT1018 | Usage | Error | Array types should be one dimensional +CsWinRT1019 | Usage | Error | Do not use the `System.Array` type for array parameters or array return values +CsWinRT1020 | Usage | Error | Do not pass parameters by `ref` +CsWinRT1021 | Usage | Error | Array parameters should not be marked `InAttribute` or `OutAttribute` +CsWinRT1022 | Usage | Error | Parameters should not be marked `InAttribute` or `OutAttribute` +CsWinRT1023 | Usage | Error | Array parameters should not be marked both `ReadOnlyArrayAttribute` and `WriteOnlyArrayAttribute` +CsWinRT1024 | Usage | Error | Array parameter marked `out` should not be declared `ReadOnlyArrayAttribute` +CsWinRT1025 | Usage | Error | Array parameter should be marked either `ReadOnlyArrayAttribute` or `WriteOnlyArrayAttribute` +CsWinRT1026 | Usage | Error | Non-array parameter should not be marked `ReadOnlyArrayAttribute` or `WriteOnlyArrayAttribute` \ No newline at end of file From f96ab5188d0af980df527b4ab66f731980f86283 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 22 Jan 2021 08:29:39 -0800 Subject: [PATCH 6/9] update help link for rules --- src/Authoring/WinRT.SourceGenerator/WinRTRules.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs index ee2569e9a..40f16fadb 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs @@ -18,7 +18,7 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes category: "Usage", defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true, - helpLinkUri: "https://docs.microsoft.com/en-us/previous-versions/hh977010(v=vs.110)"); + helpLinkUri: "https://github.com/microsoft/CsWinRT/tree/master/src/Authoring/WinRT.SourceGenerator/AnalyzerReleases.Unshipped.md"); } public static DiagnosticDescriptor PrivateGetterRule = MakeRule( From 00da9956f8962daf55a87dd9cbc437f69e3317fd Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Fri, 22 Jan 2021 09:10:28 -0800 Subject: [PATCH 7/9] fix bug in unittests --- src/Tests/DiagnosticTests/UnitTesting.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Tests/DiagnosticTests/UnitTesting.cs b/src/Tests/DiagnosticTests/UnitTesting.cs index 18e93248e..236ce5daf 100644 --- a/src/Tests/DiagnosticTests/UnitTesting.cs +++ b/src/Tests/DiagnosticTests/UnitTesting.cs @@ -47,7 +47,7 @@ [this is a workaround until we can pass AnalyzerConfigOptions in `Helpers.cs` fi /// from the cswinrt source generator based on the given source code /// [Test, TestCaseSource(nameof(ValidCases))] - private void CheckNoDiagnostic(string source) + public void CheckNoDiagnostic(string source) { Compilation compilation = CreateCompilation(source); RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); @@ -69,7 +69,7 @@ private void CheckNoDiagnostic(string source) /// it checks that a diagnostic with the same description was raised by the source generator /// [Test, TestCaseSource(nameof(InvalidCases))] - private void CodeHasDiagnostic(string testCode, DiagnosticDescriptor rule) + public void CodeHasDiagnostic(string testCode, DiagnosticDescriptor rule) { Compilation compilation = CreateCompilation(testCode); RunGenerators(compilation, out var diagnosticsFound, new Generator.SourceGenerator()); @@ -99,7 +99,7 @@ private static IEnumerable InvalidCases { // private getter yield return new TestCaseData(PrivateGetter, WinRTRules.PrivateGetterRule).SetName("Property. PrivateGetter"); - yield return new TestCaseData(PropertyNoGetter).SetName("Property. No Get, public Setter"); + yield return new TestCaseData(PropertyNoGetter, WinRTRules.PrivateGetterRule).SetName("Property. No Get, public Setter"); // 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"); From 31fe4287afb50c5cf3b1b830156d3bcf92149209 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Mon, 25 Jan 2021 09:54:20 -0800 Subject: [PATCH 8/9] fix bug in ref diagnostic being thrown --- .../DiagnosticHelpers.cs | 2 +- .../WinRT.SourceGenerator/Generator.cs | 32 +++++++++---------- .../WinRT.SourceGenerator/WinRTRules.cs | 6 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs index 8652b9354..0e614eece 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticHelpers.cs @@ -193,7 +193,7 @@ private void ParameterHasAttributeErrors(MethodDeclarationSyntax method) // Nothing can be marked `ref` if (HasModifier(param, SyntaxKind.RefKeyword)) { - Report(WinRTRules.RefParameterFound, method.GetLocation(), param.Identifier); + Report(WinRTRules.RefParameterFound, method.GetLocation(), method.Identifier, param.Identifier); } if (ParamHasInOrOutAttribute(param)) diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index 7b8c27a8f..321675c1a 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -78,12 +78,12 @@ private static string GetCsWinRTWindowsMetadata(GeneratorExecutionContext contex return cswinrtWindowsMetadata; } - private static string GetCsWinRTDependentMetadata(GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAuthoringInputs", out var winmds); - return winmds; - } - + private static string GetCsWinRTDependentMetadata(GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAuthoringInputs", out var winmds); + return winmds; + } + private string GetTempFolder(bool clearSourceFilesFromFolder = false) { if(_tempFolder == null || !File.Exists(_tempFolder)) @@ -113,15 +113,15 @@ private void GenerateSources(GeneratorExecutionContext context) string winmdFile = GetWinmdOutputFile(context); string outputDir = GetTempFolder(true); string windowsMetadata = GetCsWinRTWindowsMetadata(context); - string winmds = GetCsWinRTDependentMetadata(context); - - string arguments = string.Format( - "-component -input \"{0}\" -input {1} -include {2} -output \"{3}\" -input {4} -verbose", - winmdFile, - windowsMetadata, - assemblyName, - outputDir, - winmds); + string winmds = GetCsWinRTDependentMetadata(context); + + string arguments = string.Format( + "-component -input \"{0}\" -input {1} -include {2} -output \"{3}\" -input {4} -verbose", + winmdFile, + windowsMetadata, + assemblyName, + outputDir, + winmds); Logger.Log("Running " + cswinrtExe + " " + arguments); var processInfo = new ProcessStartInfo @@ -201,7 +201,7 @@ public void Execute(GeneratorExecutionContext context) { return; } - + Logger.Initialize(context); diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs index 40f16fadb..058425533 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs @@ -56,9 +56,9 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor UnsupportedTypeRule = MakeRule( "CsWinRT1006", "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}"); + "The member '{0}' has the type '{1}' in its signature. The type '{1}' is not a valid Windows Runtime type. " + + "Yet, the type (or its generic parameters) implement interfaces that are valid Windows Runtime types. " + + "Consider changing the type '{1} in the member signature to one of the following types from System.Collections.Generic: {2}."); public static DiagnosticDescriptor StructWithNoFieldsRule = MakeRule( "CsWinRT1007", From 02894d7f9ebc6fd2c809a033cb86e82b648ad1a5 Mon Sep 17 00:00:00 2001 From: Joshua Larkin Date: Tue, 26 Jan 2021 07:25:40 -0800 Subject: [PATCH 9/9] pr feedback --- .gitignore | 1 - src/Authoring/WinRT.SourceGenerator/WinRTRules.cs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 8af89441e..6cf0c7c25 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,3 @@ nuget/Microsoft.Windows.CsWinRT.Prerelease.targets *.binlog vs_buildtools.exe .buildtools -**(Package)* diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs index 058425533..57854135a 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTRules.cs @@ -78,8 +78,8 @@ private static DiagnosticDescriptor MakeRule(string id, string title, string mes public static DiagnosticDescriptor ParameterNamedValueRule = MakeRule( "CsWinRT1010", "Parameter Named Value Rule", - "The method {0} is used in the Windows Runtime and has a parameter named {1}." + - "The parameter name {1} is the same as the return value name used in the generated C#/WinRT interop; use a different parameter name."); + "The parameter name {1} in method {0} is the same as the return value parameter name " + + "used in the generated C#/WinRT interop; use a different parameter name."); public static DiagnosticDescriptor StructHasPrivateFieldRule = MakeRule( "CsWinRT1011",