diff options
author | Tlakaelel Axayakatl Ceja <tlakaelel.ceja@microsoft.com> | 2021-06-23 00:39:17 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-23 00:39:17 +0300 |
commit | a07cab7b71a1321a9e68571c0b6095144a177b4e (patch) | |
tree | 4e9cb01d00280165b78290556a54adbcfe09d8c2 /docs | |
parent | f2588193553431636b9853b0f87209fa395a72c5 (diff) |
Match Attributes for virtual methods and overrides (#2046)
Add analyzer logic to create a diagnostic if attributes don't match between all interface implementations or overrides
Use IL2046 to display errors for RUC
Use IL3003 to display errors for RAF
Add IL3003 to error-codes.md
Add tests
Adds support for nullable attribute operations
Add support for adding metadata information into the compilation
Divide the current warning message into 4 different more insightful diagnostic messages following the structure implemented in ObsoleteAttribute messages
Add IL2046 to diagnostic format to ILLink.Shared
Diffstat (limited to 'docs')
-rw-r--r-- | docs/error-codes.md | 116 |
1 files changed, 113 insertions, 3 deletions
diff --git a/docs/error-codes.md b/docs/error-codes.md index 3f59b374d..2ef1b68ff 100644 --- a/docs/error-codes.md +++ b/docs/error-codes.md @@ -782,10 +782,13 @@ This is technically possible if a custom assembly defines `DynamicDependencyAttr } ``` -#### `IL2046` Trim analysis: Presence of 'RequiresUnreferencedCodeAttribute' on method 'method' doesn't match overridden method 'base method'. All overridden methods must have 'RequiresUnreferencedCodeAttribute'. +#### `IL2046`: Trim analysis: Member 'member' with 'RequiresUnreferencedCodeAttribute' has a member 'member' without 'RequiresUnreferencedCodeAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. -- All overrides of a virtual method including the base method must either have or not have the `RequiresUnreferencedCodeAttribute`. +- For all interfaces and overrides the implementation 'RequiresUnreferencedCodeAttribute' must match the definition 'RequiresUnreferecedCodeAttribute', either all the members contain the attribute o none of them. + Here is a list of posible scenarios where the warning can be generated: + + A base member has the attribute but the derived member does not have the attribute ```C# public class Base { @@ -795,10 +798,53 @@ This is technically possible if a custom assembly defines `DynamicDependencyAttr public class Derived : Base { - // IL2046: Presence of 'RequiresUnreferencedCodeAttribute' on method 'Derived.TestMethod()' doesn't match overridden method 'Base.TestMethod'. All overridden methods must have 'RequiresUnreferencedCodeAttribute'. + // IL2046: Base member 'Base.TestMethod' with 'RequiresUnreferencedCodeAttribute' has a derived member 'Derived.TestMethod()' without 'RequiresUnreferencedCodeAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. + public override void TestMethod() {} + } + ``` + A derived member has the attribute but the overriden base member does not have the attribute + ```C# + public class Base + { + public virtual void TestMethod() {} + } + + public class Derived : Base + { + // IL2046: Member 'Derived.TestMethod()' with 'RequiresUnreferencedCodeAttribute' overrides base member 'Base.TestMethod()' without 'RequiresUnreferencedCodeAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. + [RequireUnreferencedCode("Message")] public override void TestMethod() {} } ``` + An interface member has the attribute but it's implementation does not have the attribute + ```C# + interface IRUC + { + [RequiresUnreferencedCode("Message")] + void TestMethod(); + } + + class Implementation : IRUC + { + // IL2046: Interface member 'IRUC.TestMethod()' with 'RequiresUnreferencedCodeAttribute' has an implementation member 'Implementation.TestMethod()' without 'RequiresUnreferencedCodeAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. + public void TestMethod () { } + } + ``` + An implementation member has the attribute but the interface that implementes does not have the attribute + + ```C# + interface IRUC + { + void TestMethod(); + } + + class Implementation : IRUC + { + [RequiresUnreferencedCode("Message")] + // IL2046: Member 'Implementation.TestMethod()' with 'RequiresUnreferencedCodeAttribute' implements interface member 'IRUC.TestMethod()' without 'RequiresUnreferencedCodeAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. + public void TestMethod () { } + } + ``` #### `IL2048`: Internal attribute 'RemoveAttributeInstances' can only be used on a type, but is being used on 'member' @@ -1682,3 +1728,67 @@ class Test MethodWithAssemblyFilesUsage(); } ``` + +#### `IL3003`: Member 'member' with 'RequiresAssemblyFilesAttribute' has a member 'member' without 'RequiresAssemblyFilesAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. + +- For all interfaces and overrides the implementation 'RequiresAssemblyFilesAttribute' must match the definition 'RequiresAssemblyFilesAttribute', either all the members contain the attribute o none of them. + + Here is a list of posible scenarios where the warning can be generated: + + A base member has the attribute but the derived member does not have the attribute + ```C# + public class Base + { + [RequiresAssemblyFiles] + public virtual void TestMethod() {} + } + + public class Derived : Base + { + // IL3003: Base member 'Base.TestMethod' with 'RequiresAssemblyFilesAttribute' has a derived member 'Derived.TestMethod()' without 'RequiresAssemblyFilesAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. + public override void TestMethod() {} + } + ``` + A derived member has the attribute but the overriden base member does not have the attribute + ```C# + public class Base + { + public virtual void TestMethod() {} + } + + public class Derived : Base + { + // IL3003: Member 'Derived.TestMethod()' with 'RequiresAssemblyFilesAttribute' overrides base member 'Base.TestMethod()' without 'RequiresAssemblyFilesAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. + [RequiresAssemblyFiles] + public override void TestMethod() {} + } + ``` + An interface member has the attribute but it's implementation does not have the attribute + ```C# + interface IRAF + { + [RequiresAssemblyFiles] + void TestMethod(); + } + + class Implementation : IRAF + { + // IL3003: Interface member 'IRAF.TestMethod()' with 'RequiresAssemblyFilesAttribute' has an implementation member 'Implementation.TestMethod()' without 'RequiresAssemblyFilesAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. + public void TestMethod () { } + } + ``` + An implementation member has the attribute but the interface that implementes does not have the attribute + + ```C# + interface IRAF + { + void TestMethod(); + } + + class Implementation : IRAF + { + [RequiresAssemblyFiles] + // IL3003: Member 'Implementation.TestMethod()' with 'RequiresAssemblyFilesAttribute' implements interface member 'IRAF.TestMethod()' without 'RequiresAssemblyFilesAttribute'. For all interfaces and overrides the implementation attribute must match the definition attribute. + public void TestMethod () { } + } + ```
\ No newline at end of file |