BRO1603: Documentation text should end with a period¶
Summary, remarks, parameter, type parameter, return value, value and exception text are sentences and end with a period. Replaces StyleCop SA1629.
Example¶
Before¶
public class Prices
{
/// <summary>Applies a discount</summary>
/// <param name="price">The full price</param>
/// <returns>The discounted price, see <see cref="Prices"/></returns>
public decimal Discount(decimal price) => price * 0.9m;
}
After¶
public class Prices
{
/// <summary>Applies a discount.</summary>
/// <param name="price">The full price.</param>
/// <returns>The discounted price, see <see cref="Prices"/>.</returns>
public decimal Discount(decimal price) => price * 0.9m;
}
Why¶
Consistent punctuation makes generated documentation and IntelliSense read as prose, and it's the convention in the .NET documentation.
How the fix works¶
A period is added right after the last text, or after an inline element at the end (<see cref="..."/>, <c>). A
trailing space stays after the period.
This rule reads documentation as XML, which the compiler only does when the project generates documentation
(<GenerateDocumentationFile>true</GenerateDocumentationFile>), like StyleCop (its SA0001 says so).
Not reported¶
- Text that ends with
?,!or:. A question, an exclamation or an introduction is a finished sentence. - Text that ends with
,or;(1033 => "en",,value;): a line of code or a list that goes on. - A period followed only by closing punctuation:
(see above.),"done.",'done.',[note.]. - Text that ends with a block element, like a list or a code sample.
- Empty elements.
- Text that is only a number (
<summary>0</summary>on an enum member,0x1F): a value, not a sentence. - Text whose last word ends in a period and digits (
Supports HTML 5.0): a period after it reads as part of the number. - Text that ends with an inline element whose own text ends a sentence:
<paramref name="name">The name of the request.</paramref>,<see cref="X">is it done?</see>. In<c>, which holds code, only a quoted sentence counts (<c>"User logged in."</c>);Calls <c>Done.</c>gets its period. - Events and finalizers: StyleCop's SA1629 doesn't check their documentation, and neither does this rule.
- Text that ends in code: its last word contains a bracket, brace,
=,;,:, a slash,|,$,#,_or a backtick (digraph {,Example: A1:B10,Run(x), a URL). A period would read as part of the code. A closing)without its(in the word ends a parenthetical and still gets the period ((in ms).). A quoted literal at the end that reads as code is code too: followed by;, with an escape, or a punctuation char (Default is ',';,Usually "\r\n",The separator ','); a quoted word (the word "done") still gets its period. - Elements StyleCop doesn't know are passed over, like StyleCop: the text before them counts. Text that ends with
<devremarks>...</devremarks>(vs-threading) is checked where the sentence before it ends, and gets no period after the element. The period goes after an inline element:<c>,<see>,<paramref>,<typeparamref>, and HTML's<a>,<b>,<i>,<u>,<em>,<strong>,<sub>,<sup>,<span>,<tt>(StyleCop passes over those too and puts the period before them). - Tags named in
stylebro_exclude_from_punctuation_check(see Configuration). - Documentation whose XML is malformed:
IComparable<T>in prose opens an elementTthat takes the summary's end tag, and a bare<(when a < b) opens an element that never closes, so where the text ends is a guess. A bare&that starts no entity (this & that) is malformed too (the compiler reports CS1570). Writea < b,&,IComparable<T>or<see cref="IComparable{T}"/>, then the rule checks it again. The other rules that edit documentation (BRO1604-BRO1614, BRO1616-BRO1619) skip it too.
Text that ends in an XML entity (List<T>) gets the period after the entity. Spaces between the text and a
closing tag on the same line make way for the period: evaluates to true </returns> becomes
evaluates to true.</returns>, not true. </returns>.
Configuration¶
[*.cs]
# Tags whose text isn't checked, comma-separated (default: seealso)
stylebro_exclude_from_punctuation_check = seealso, example
StyleCop's documentationRules.excludeFromPunctuationCheck, with the same default; stylebro-migrate writes it from
stylecop.json when a team changed it. An excluded tag isn't checked at the top level or nested (an excluded para
inside a summary). The rule checks summary, remarks, param, typeparam, returns, value and exception
anyway, so seealso is never checked, set or not.
Compared with StyleCop¶
Same results as StyleCop, except:
- text ending with
?,!or:, which StyleCop reports and turns intoquestion?.; - a period followed by a closing quote or bracket (
"done."), which StyleCop reports and turns into"done.".(#2860); StyleCop accepts only.); - text ending in an entity: StyleCop 1.2.0-beta.556 reports the entity's
;and its fix replaces it (>., #3802, fixed after beta.556); - text ending in code (
digraph {,A1:B10), which StyleCop reports and turns intodigraph {.; - text ending in a
<c>element that quotes a sentence (<c>"User {User} logged in."</c>), which StyleCop reports and turns into</c>.(#2784, open); - text ending in an inline element with text of its own (
<see cref="X">a sentence.</see>): StyleCop passes over it and checks the text before it, so it reportsEnds with <see ...>and writesEnds with. <see ...>; StyleBro checks the element's own text and puts a missing period after the element; - text whose last word ends in a period and digits (
HTML 5.0), which StyleCop turns into5.0..
StyleCop checks every top-level tag not in excludeFromPunctuationCheck; StyleBro only the tags listed above.