Skip to content

Commit 3405f85

Browse files
committed
Support added for multiline comment fixing.
Minor code changes * Triva[0].Kind!= to !Trivia[0].IsKind * Change to use SyntaxFactory.EndOfLine instead of SyntaxFactory.CRLF * Change loop to decreasing indexer * remove unneeded braces around else if inCopyright Major changes * Added leading indentation logic and tests as it's probably going to be reused for the multi line versions. * Well formed xml multi line comments autofix now works.
1 parent c3afe7b commit 3405f85

3 files changed

Lines changed: 521 additions & 26 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1634UnitTests.cs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,41 @@ namespace Bar
130130
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
131131
}
132132

133+
/// <summary>
134+
/// Verifies that we keep leading spaces in a file header when adding copyright text.
135+
/// </summary>
136+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
137+
[Fact]
138+
public async Task TestFileHeaderKeepsLeadingWhiteSpaceWhenAddingCopyrightMessageAsync()
139+
{
140+
var testCode = @" // <author>FooCorp</author>
141+
// <summary>
142+
// FooCorp Bar class
143+
// </summary>
144+
145+
namespace Bar
146+
{
147+
}
148+
";
149+
var fixedCode = @" // <copyright file=""Test0.cs"" company=""FooCorp"">
150+
// Copyright (c) FooCorp. All rights reserved.
151+
// </copyright>
152+
// <author>FooCorp</author>
153+
// <summary>
154+
// FooCorp Bar class
155+
// </summary>
156+
157+
namespace Bar
158+
{
159+
}
160+
";
161+
162+
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 5);
163+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
164+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
165+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
166+
}
167+
133168
/// <summary>
134169
/// Verifies that a file header with missing copyright text the fix leaves behind other comments.
135170
/// </summary>
@@ -154,6 +189,80 @@ namespace Bar
154189
// </author>
155190
// <summary>This is a test file.</summary>
156191
192+
namespace Bar
193+
{
194+
}
195+
";
196+
197+
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 1);
198+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
199+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
200+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
201+
}
202+
203+
/// <summary>
204+
/// Verifies that a file header with missing copyright text and a multiline comment without leading stars the fix leaves behind other comments.
205+
/// </summary>
206+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
207+
[Fact]
208+
public async Task TestFileHeaderForMultilineCommentWithoutLeadingStarsFixWithReplaceCopyrightTagTextAsync()
209+
{
210+
var testCode = @"/* <author>
211+
John Doe
212+
</author>
213+
<summary>This is a test file.</summary>
214+
*/
215+
216+
namespace Bar
217+
{
218+
}
219+
";
220+
var fixedCode = @"/* <copyright file=""Test0.cs"" company=""FooCorp"">
221+
Copyright (c) FooCorp. All rights reserved.
222+
</copyright>
223+
<author>
224+
John Doe
225+
</author>
226+
<summary>This is a test file.</summary>
227+
*/
228+
229+
namespace Bar
230+
{
231+
}
232+
";
233+
234+
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 1);
235+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
236+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
237+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
238+
}
239+
240+
/// <summary>
241+
/// Verifies that a file header with missing copyright text and a multiline comment with leading stars the fix leaves behind other comments.
242+
/// </summary>
243+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
244+
[Fact]
245+
public async Task TestFileHeaderForMultilineCommentWithLeadingStarsFixWithReplaceCopyrightTagTextAsync()
246+
{
247+
var testCode = @"/* <author>
248+
* John Doe
249+
* </author>
250+
* <summary>This is a test file.</summary>
251+
*/
252+
253+
namespace Bar
254+
{
255+
}
256+
";
257+
var fixedCode = @"/* <copyright file=""Test0.cs"" company=""FooCorp"">
258+
* Copyright (c) FooCorp. All rights reserved.
259+
* </copyright>
260+
* <author>
261+
* John Doe
262+
* </author>
263+
* <summary>This is a test file.</summary>
264+
*/
265+
157266
namespace Bar
158267
{
159268
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1636UnitTests.cs

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,228 @@ namespace Bar
230230
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
231231
}
232232

233+
/// <summary>
234+
/// Verifies that we keep leading spaces in a file header when fixing text.
235+
/// </summary>
236+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
237+
[Fact]
238+
public async Task TestFileHeaderKeepsLeadingWhiteSpaceWhenFixingCopyrightMessageAsync()
239+
{
240+
this.useMultiLineHeaderTestSettings = true;
241+
242+
var testCode = @" // <author>FooCorp</author>
243+
// <copyright file=""Test0.cs"" company=""FooCorp"">
244+
// Not copyright (c) FooCorp. All rights reserved.
245+
//
246+
// Line #3
247+
// </copyright>
248+
// <summary>
249+
// FooCorp Bar class
250+
// </summary>
251+
252+
namespace Bar
253+
{
254+
}
255+
";
256+
var fixedCode = @" // <author>FooCorp</author>
257+
// <copyright file=""Test0.cs"" company=""FooCorp"">
258+
// copyright (c) FooCorp. All rights reserved.
259+
//
260+
// Line #3
261+
// </copyright>
262+
// <summary>
263+
// FooCorp Bar class
264+
// </summary>
265+
266+
namespace Bar
267+
{
268+
}
269+
";
270+
271+
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(2, 8);
272+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
273+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
274+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
275+
}
276+
277+
/// <summary>
278+
/// Verifies that a multi line file header will be fixed correctly (for multiple line comments) without a leading star
279+
/// </summary>
280+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
281+
[Fact]
282+
public async Task TestFileHeaderWithMultiLineCommentAndNoLeadingStarsFixingCopyrightMessageStaysMultiLineAsync()
283+
{
284+
this.useMultiLineHeaderTestSettings = true;
285+
286+
var testCode = @"/*
287+
<author>FooCorp</author>
288+
<copyright file=""Test0.cs"" company=""FooCorp"">
289+
NOT copyright (c) FooCorp. All rights reserved.
290+
291+
Line #3
292+
</copyright>
293+
<summary>FooCorp Bar Class</summary>
294+
*/
295+
296+
namespace Bar
297+
{
298+
}
299+
";
300+
301+
var fixedCode = @"/*
302+
<author>FooCorp</author>
303+
<copyright file=""Test0.cs"" company=""FooCorp"">
304+
copyright (c) FooCorp. All rights reserved.
305+
306+
Line #3
307+
</copyright>
308+
<summary>FooCorp Bar Class</summary>
309+
*/
310+
311+
namespace Bar
312+
{
313+
}
314+
";
315+
316+
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(3, 4);
317+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
318+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
319+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
320+
}
321+
322+
/// <summary>
323+
/// Verifies that a multi line file header will be fixed correctly (for multiple line comments) with a leading star
324+
/// </summary>
325+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
326+
[Fact]
327+
public async Task TestFileHeaderWithMultiLineCommentAndLeadingStarsFixingCopyrightMessageStaysMultiLineAsync()
328+
{
329+
this.useMultiLineHeaderTestSettings = true;
330+
331+
var testCode = @"/*
332+
* <author>FooCorp</author>
333+
* <copyright file=""Test0.cs"" company=""FooCorp"">
334+
* NOT copyright (c) FooCorp. All rights reserved.
335+
*
336+
* Line #3
337+
* </copyright>
338+
* <summary>FooCorp Bar Class</summary>
339+
*/
340+
341+
namespace Bar
342+
{
343+
}
344+
";
345+
346+
var fixedCode = @"/*
347+
* <author>FooCorp</author>
348+
* <copyright file=""Test0.cs"" company=""FooCorp"">
349+
* copyright (c) FooCorp. All rights reserved.
350+
*
351+
* Line #3
352+
* </copyright>
353+
* <summary>FooCorp Bar Class</summary>
354+
*/
355+
356+
namespace Bar
357+
{
358+
}
359+
";
360+
361+
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(3, 4);
362+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
363+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
364+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
365+
}
366+
367+
/// <summary>
368+
/// Verifies that a multi line file header will be fixed correctly (for multiple line comments) with a leading star
369+
/// and the initial line at the top of the file.
370+
/// </summary>
371+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
372+
[Fact]
373+
public async Task TestFileHeaderWithMultiLineCommentAndAuthorAtTopAndLeadingStarsFixingCopyrightMessageStaysMultiLineAsync()
374+
{
375+
this.useMultiLineHeaderTestSettings = true;
376+
377+
var testCode = @"/* <author>FooCorp</author>
378+
* <copyright file=""Test0.cs"" company=""FooCorp"">
379+
* NOT copyright (c) FooCorp. All rights reserved.
380+
*
381+
* Line #3
382+
* </copyright>
383+
* <summary>FooCorp Bar Class</summary>
384+
*/
385+
386+
namespace Bar
387+
{
388+
}
389+
";
390+
391+
var fixedCode = @"/* <author>FooCorp</author>
392+
* <copyright file=""Test0.cs"" company=""FooCorp"">
393+
* copyright (c) FooCorp. All rights reserved.
394+
*
395+
* Line #3
396+
* </copyright>
397+
* <summary>FooCorp Bar Class</summary>
398+
*/
399+
400+
namespace Bar
401+
{
402+
}
403+
";
404+
405+
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(2, 4);
406+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
407+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
408+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
409+
}
410+
411+
/// <summary>
412+
/// Verifies that a multi line file header will be fixed correctly (for multiple line comments) with a leading star
413+
/// and the initial line at the top of the file.
414+
/// </summary>
415+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
416+
[Fact]
417+
public async Task TestFileHeaderWithMultiLineCommentAndCopyrightAtTopAndLeadingStarsFixingCopyrightMessageStaysMultiLineAsync()
418+
{
419+
this.useMultiLineHeaderTestSettings = true;
420+
421+
var testCode = @"/* <copyright file=""Test0.cs"" company=""FooCorp"">
422+
* NOT copyright (c) FooCorp. All rights reserved.
423+
*
424+
* Line #3
425+
* </copyright>
426+
* <author>FooCorp</author>
427+
* <summary>FooCorp Bar Class</summary>
428+
*/
429+
430+
namespace Bar
431+
{
432+
}
433+
";
434+
435+
var fixedCode = @"/* <copyright file=""Test0.cs"" company=""FooCorp"">
436+
* copyright (c) FooCorp. All rights reserved.
437+
*
438+
* Line #3
439+
* </copyright>
440+
* <author>FooCorp</author>
441+
* <summary>FooCorp Bar Class</summary>
442+
*/
443+
444+
namespace Bar
445+
{
446+
}
447+
";
448+
449+
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(1, 4);
450+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
451+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
452+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
453+
}
454+
233455
protected override CodeFixProvider GetCSharpCodeFixProvider()
234456
{
235457
return new FileHeaderCodeFixProvider();

0 commit comments

Comments
 (0)