Created
June 28, 2021 22:02
-
-
Save ZacharyPatten/cb37ae76a01b68d34efdfe7de7c041c4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| System.Console.WriteLine("Hello World!"); | |
| #pragma warning disable IDE0060 // Remove unused parameter | |
| #pragma warning disable CA1822 // Mark members as static | |
| #region Analyzer #01: not all parameters accounted for | |
| namespace Analyzer1_Example1 | |
| { | |
| // There is no warning that "B" is missing XML docs for "T2". | |
| /// <summary>hello world</summary> | |
| /// <typeparam name="T1">hello world</typeparam> | |
| public class A<T1> { } | |
| /// <inheritdoc cref="A{T1}" /> | |
| public class B<T1, T2> { } | |
| } | |
| namespace Analyzer1_Example2 | |
| { | |
| // There is no warning that "A.Method2" is missing XML docs for "T1" and "t1". | |
| public class A | |
| { | |
| /// <summary>hello world</summary> | |
| public int Method1() => throw new System.Exception(); | |
| /// <inheritdoc cref="Method1"/> | |
| public void Method2<T1>(T1 t1) => throw new System.Exception(); | |
| } | |
| } | |
| #endregion | |
| #region Analyzer #02: no source to inherit from | |
| namespace Analyzer2_Example1 | |
| { | |
| // "A.Method" uses inheritdoc, but there is no source to inherit from. | |
| public class A | |
| { | |
| /// <inheritdoc /> | |
| public void Method() => throw new System.Exception(); | |
| } | |
| } | |
| namespace Analyzer2_Example2 | |
| { | |
| // "B.Method" uses inheritdoc, but there is no source to inherit from. | |
| public class A | |
| { | |
| /// <summary>hello world</summary> | |
| public int Method<TCompare>() => throw new System.Exception(); | |
| } | |
| public class B : A | |
| { | |
| /// <inheritdoc /> | |
| public new void Method<TCompare>() => throw new System.Exception(); | |
| } | |
| } | |
| namespace Analyzer2_Example3 | |
| { | |
| // "B.Method" uses inheritdoc, but it is static, and this currently doesn't work. | |
| public class A | |
| { | |
| /// <summary>hello world</summary> | |
| public static void Method() => throw new System.Exception(); | |
| } | |
| public class B : A | |
| { | |
| /// <inheritdoc /> | |
| public static new void Method() => throw new System.Exception(); | |
| } | |
| } | |
| #endregion | |
| #region Analyzer #03: inherit <returns> on "void" return methods or classes | |
| namespace Analyzer3_Example1 | |
| { | |
| // "A.Method2" inherits a "<returns>" XML node but has a "void" return type | |
| // which currently shows up in the IDE (which IMO may need to be considered | |
| // a bug) | |
| public class A | |
| { | |
| /// <summary>hello world</summary> | |
| /// <returns>hello world</returns> | |
| public int Method1() => throw new System.Exception(); | |
| /// <inheritdoc cref="Method1"/> | |
| public void Method2() => throw new System.Exception(); | |
| } | |
| } | |
| namespace Analyzer3_Example2 | |
| { | |
| // "A" inherits a "<returns>" XML node but is a class | |
| /// <inheritdoc cref="A.Method"/> | |
| public class A | |
| { | |
| /// <summary>hello world</summary> | |
| /// <returns>hello world</returns> | |
| public int Method() => throw new System.Exception(); | |
| } | |
| } | |
| #endregion | |
| #region Analyzer #04: inherit <exception> on methods that can't throw that type | |
| namespace Analyzer4_Example1 | |
| { | |
| // "A.Method2" inherits a "<exception>" when it doesn't throw that type of exception | |
| public class A | |
| { | |
| /// <summary>hello world</summary> | |
| /// <exception cref="System.NotImplementedException" /> | |
| public void Method1() => throw new System.NotImplementedException(); | |
| /// <inheritdoc cref="Method1"/> | |
| public void Method2() => throw new System.Exception(); | |
| } | |
| } | |
| #endregion | |
| #region Analyzer #05: explicit inheritdoc when not necessary | |
| namespace Analyzer5_Example1 | |
| { | |
| // the inheritdoc on "B" has an explicit "cref" when it is not necessary | |
| /// <summary>hello world</summary> | |
| public class A { } | |
| /// <inheritdoc cref="A"/> | |
| public class B : A { } | |
| } | |
| namespace Analyzer5_Example2 | |
| { | |
| // the inheritdoc on "C" has an explicit "cref" when it is not necessary | |
| /// <summary>hello world</summary> | |
| public class A { } | |
| /// <inheritdoc/> | |
| public class B : A { } | |
| /// <inheritdoc cref="A"/> | |
| public class C : B { } | |
| } | |
| namespace Analyzer5_Example3 | |
| { | |
| // the inheritdoc's on "C" has an explicit "cref" when it is not necessary | |
| // and there only needs to be one inheritdoc | |
| /// <summary>hello world</summary> | |
| public class A { } | |
| /// <inheritdoc/> | |
| public class B : A { } | |
| /// <inheritdoc cref="B"/> | |
| /// <inheritdoc cref="A"/> | |
| public class C : B { } | |
| } | |
| #endregion | |
| #region Analyzer #06: incorrect order when you want to override | |
| namespace Analyzer6_Example1 | |
| { | |
| // "B<T1>" inheritdoc's from "A<T1>" and attempts to override the XML | |
| // docs for "T1" but due to how the ordering of the XML docs are currently | |
| // processed, it is not overriding. In order to override, the overrides | |
| // must come before the inheritdoc. | |
| /// <summary>hello world</summary> | |
| /// <typeparam name="T1">hello world</typeparam> | |
| public class A<T1> { } | |
| /// <inheritdoc cref="A{T1}"/> | |
| /// <typeparam name="T1">goodbye world</typeparam> | |
| public class B<T1> : A<T1> { } | |
| } | |
| #endregion | |
| #region Analyzer #07: valid inheritdoc but everything is overriden | |
| namespace Analyzer7_Example1 | |
| { | |
| // "B" has inheritdoc but nothing is inherited because every | |
| // XML node is overriden | |
| /// <summary>hello world</summary> | |
| public class A { } | |
| /// <summary>goodbye world</summary> | |
| /// <inheritdoc /> | |
| public class B : A { } | |
| } | |
| #endregion | |
| #region Analyzer #08: cyclic inheritdocs | |
| namespace Analyzer8_Example1 | |
| { | |
| // "A" and "B" have cyclic inheritdocs | |
| /// <inheritdoc cref="B"/> | |
| /// <summary>hello world</summary> | |
| public class A { } | |
| /// <inheritdoc cref="A"/> | |
| /// <summary>goodbye world</summary> | |
| public class B { } | |
| } | |
| namespace Analyzer8_Example2 | |
| { | |
| // "A" and "B" have cyclic inheritdocs | |
| /// <inheritdoc cref="B"/> | |
| /// <summary>hello world</summary> | |
| public class A { } | |
| /// <inheritdoc/> | |
| /// <summary>goodbye world</summary> | |
| public class B : A { } | |
| } | |
| #endregion | |
| #region Analyzer #09: inheriting only standard nodes that are not standard for the inheriting member | |
| namespace Analyzer9_Example1 | |
| { | |
| // "A", "A.Field", "A.Property", and "A.Event" only inherits | |
| // a "params" XML node, but "params" is not not a standard node for | |
| // classes, fields, properties, or events | |
| /// <inheritdoc cref="Method{T1}(T1)"/> | |
| public class A | |
| { | |
| /// <param name="t1">hello world</param> | |
| public int Method<T1>(T1 t1) => throw new System.Exception(); | |
| /// <inheritdoc cref="Method{T1}(T1)"/> | |
| public int Field; | |
| /// <inheritdoc cref="Method{T1}(T1)"/> | |
| public int Property => throw new System.Exception(); | |
| /// <inheritdoc cref="Method{T1}(T1)"/> | |
| public event System.Action Event; | |
| } | |
| } | |
| #endregion | |
| #region Analyzer #10: encourage inheritdoc instead of copy-paste | |
| // Note: I think this is a duplicate of https://github.com/DotNetAnalyzers/DocumentationAnalyzers/issues/16 | |
| namespace Analyzer10_Example1 | |
| { | |
| // "A" and "B" contain identical XML docs and therefore "inheritdoc" | |
| // should be prefered to duplication | |
| /// <summary>hello world</summary> | |
| public class A { } | |
| /// <summary>hello world</summary> | |
| public class B : A { } | |
| } | |
| namespace Analyzer10_Example2 | |
| { | |
| // "A" and "B" contain identical "summary" XML nodes and therefore | |
| // "inheritdoc" should be prefered to duplication. | |
| /// <summary>hello world</summary> | |
| public class A { } | |
| /// <summary>hello world</summary> | |
| /// <typeparam name="T1">hello world</typeparam> | |
| public class B<T1> : A { } | |
| } | |
| #endregion | |
| #region Analyzer #11: returns on non-returns member | |
| namespace Analyzer11_Example1 | |
| { | |
| // "A" has "<returns>" but it is a class | |
| /// <returns>hello world</returns> | |
| public class A { } | |
| } | |
| #endregion | |
| #region Analyzer #12: valid inheritdoc but source doesn't have XML docs | |
| namespace Analyzer12_Example1 | |
| { | |
| // "B" inheritdoc's from "A", but "A" has no XML docs. | |
| public class A { } | |
| /// <inheritdoc cref="A"/> | |
| public class B { } | |
| } | |
| #endregion | |
| #region Analyzer #13: encourage <value> instead of <returns> | |
| namespace Analyzer13_Example1 | |
| { | |
| // "A.Property" has <returns> but <value> is generally prefered for properties | |
| public class A | |
| { | |
| /// <returns>hello world</returns> | |
| public int Property => throw new System.Exception(); | |
| } | |
| } | |
| namespace Analyzer13_Example2 | |
| { | |
| // "A.Property" has both <value> and <returns> so there should probably only be <value> | |
| public class A | |
| { | |
| /// <value>hello world</value> | |
| /// <returns>hello world</returns> | |
| public int Property => throw new System.Exception(); | |
| } | |
| } | |
| #endregion | |
| #region Analyzer #14: encourage <typeparamref...> and <paramref...> and maybe <see...> | |
| namespace Analyzer14_Example1 | |
| { | |
| // "A.Method1" includes "T1", "T2", "t1", and "t2" in the summary, which might be better | |
| // represented with <typeparamref...> and <paramref...> as done in "A.Method2" | |
| public class A | |
| { | |
| /// <summary>Takes a t1 and t2 which are types T1 and T2 respectively.</summary> | |
| public void Method1<T1, T2>(T1 t1, T2 t2) => throw new System.Exception(); | |
| /// <summary>Takes a <paramref name="t1"/> and <paramref name="t2"/> which are types <typeparamref name="T1"/> and <typeparamref name="T2"/> respectively.</summary> | |
| public void Method2<T1, T2>(T1 t1, T2 t2) => throw new System.Exception(); | |
| } | |
| } | |
| #endregion | |
| #region Analyzer #15: encourage the use of <br/> and maybe <list> | |
| namespace Analyzer15_Example1 | |
| { | |
| // The XML docs on "A" pretty clearly want to be a list. That can | |
| // be achieved with either <br/> or <list> as demonstrated in "B" | |
| // and "C" | |
| /// <summary> | |
| /// 1. hello world | |
| /// 2. hello world | |
| /// 3. hello world | |
| /// </summary> | |
| public class A { } | |
| /// <summary> | |
| /// 1. hello world<br/> | |
| /// 2. hello world<br/> | |
| /// 3. hello world | |
| /// </summary> | |
| public class B { } | |
| /// <summary> | |
| /// <list type="number"> | |
| /// <item>hello world</item> | |
| /// <item>hello world</item> | |
| /// <item>hello world</item> | |
| /// </list> | |
| /// </summary> | |
| public class C { } | |
| } | |
| #endregion | |
| #pragma warning restore IDE0060 // Remove unused parameter | |
| #pragma warning restore CA1822 // Mark members as static |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
<inheritdoc/>in these scenarios, the corresponding analyzer package would need to support diagnostics for the standard case where only a<summary>element is provided. It would be reasonable to file a feature request for the general form in dotnet/roslyn-analyzers.<returns>element to a type) and handle<inheritdoc>as a side benefit.<value>for properties. See dotnet/roslyn#8627 and all the items linked to it.