diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/FileHeaderTestBase.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/FileHeaderTestBase.cs
index 22bfc6bf1..49223707a 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/FileHeaderTestBase.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/FileHeaderTestBase.cs
@@ -22,7 +22,7 @@ public abstract class FileHeaderTestBase : CodeFixVerifier
""settings"": {
""documentationRules"": {
""companyName"": ""FooCorp"",
- ""copyrightText"": ""Copyright (c) FooCorp. All rights reserved.""
+ ""copyrightText"": ""{copyright} {companyName}. All rights reserved.""
}
}
}
@@ -53,7 +53,7 @@ namespace Bar
public async Task TestValidFileHeaderAsync()
{
var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+// Copyright © 2015 FooCorp. All rights reserved.
//
// This is a test file.
@@ -74,7 +74,7 @@ public async Task TestValidFileHeaderWithBordersAsync()
{
var testCode = @"//----------------------------------------
//
-// Copyright (c) FooCorp. All rights reserved.
+// Copyright © 2015 FooCorp. All rights reserved.
//
// This is a test file.
//----------------------------------------
@@ -87,6 +87,79 @@ namespace Bar
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
+ ///
+ /// Verifies that the literal use of {copyright} in a header does not match the configured token {copyright}.
+ ///
+ /// A representing the asynchronous unit test.
+ [Fact]
+ public async Task TestLiteralCopyrightAsync()
+ {
+ var testCode = @"//
+// {copyright} FooCorp. All rights reserved.
+//
+// This is a test file.
+
+namespace Bar
+{
+}
+";
+
+ var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(1, 4);
+ await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
+ }
+
+ ///
+ /// Verifies that {copyright} correctly requires "Copyright ©" followed by at least a 4-digit year.
+ ///
+ /// The (malformed) string to use in the {copyright} position.
+ /// A representing the asynchronous unit test.
+ [Theory]
+ [InlineData("© 1000")]
+ [InlineData("Copyright 1000")]
+ [InlineData("Copyright ©")]
+ [InlineData("Copyright © 93")]
+ [InlineData("Copyright © 1000-93")]
+ [InlineData("Copyright © 1000, 93")]
+ public async Task TestMalformedCopyrightAsync(string copyright)
+ {
+ var testCode = $@"//
+// {copyright} FooCorp. All rights reserved.
+//
+// This is a test file.
+
+namespace Bar
+{{
+}}
+";
+
+ var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(1, 4);
+ await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
+ }
+
+ ///
+ /// Verifies that {copyright} correctly accepts multiple years (lists, spans, and mixtures of the two).
+ ///
+ /// The string to use in the {copyright} position.
+ /// A representing the asynchronous unit test.
+ [Theory]
+ [InlineData("Copyright © 1000, 1003")]
+ [InlineData("Copyright © 1000-1003")]
+ [InlineData("Copyright © 1000-1003, 1005, 1007-1010")]
+ public async Task TestMultipleCopyrightYearsAsync(string copyright)
+ {
+ var testCode = $@"//
+// {copyright} FooCorp. All rights reserved.
+//
+// This is a test file.
+
+namespace Bar
+{{
+}}
+";
+
+ await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
+ }
+
///
protected override IEnumerable GetDisabledDiagnostics()
{
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1633UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1633UnitTests.cs
index ef52a96be..18245769b 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1633UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1633UnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
+ using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
@@ -38,8 +39,8 @@ public virtual async Task TestNoFileHeaderAsync()
[Fact]
public async Task TestValidFileHeaderNoContentAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
";
@@ -53,26 +54,26 @@ public async Task TestValidFileHeaderNoContentAsync()
[Fact]
public async Task TestValidMultilineCommentFileHeadersAsync()
{
- var testCode1 = @"/*
- Copyright (c) FooCorp. All rights reserved.
+ var testCode1 = $@"/*
+ Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*/
";
- var testCode2 = @"/*
+ var testCode2 = $@"/*
- Copyright (c) FooCorp. All rights reserved.
+ Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*/
";
- var testCode3 = @"/*
- Copyright (c) FooCorp. All rights reserved.
+ var testCode3 = $@"/*
+ Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*/
";
- var testCode4 = @"/*
+ var testCode4 = $@"/*
*
- * Copyright (c) FooCorp. All rights reserved.
+ * Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
*/
";
@@ -87,17 +88,17 @@ public async Task TestValidMultilineCommentFileHeadersAsync()
[Fact]
public async Task TestValidFileHeaderWithDirectivesAsync()
{
- var testCode = @"#define MYDEFINE
+ var testCode = $@"#define MYDEFINE
#if (IGNORE_FILE_HEADERS)
#pragma warning disable SA1633
#endif
//
-// Copyright (c) FooCorp. All rights reserved.
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expected = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1633DescriptorMissing).WithLocation(1, 1);
@@ -111,13 +112,13 @@ namespace Bar
[Fact]
public async Task TestValidFileHeaderWithWhitespaceAsync()
{
- var testCode = @" //
- // Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@" //
+ // Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
@@ -136,15 +137,15 @@ namespace Foo
{
}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
#define MYDEFINE
namespace Foo
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1633DescriptorMissing).WithLocation(1, 1);
@@ -160,19 +161,19 @@ namespace Foo
[Fact]
public async Task TestNonXmlFileHeaderAsync()
{
- var testCode = @"// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
namespace Foo
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Foo
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1633DescriptorMalformed).WithLocation(1, 1);
@@ -188,20 +189,20 @@ namespace Foo
[Fact]
public async Task TestInvalidXmlFileHeaderAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
namespace Foo
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Foo
-{
-}
+{{
+}}
";
var expected = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1633DescriptorMalformed).WithLocation(1, 1);
@@ -217,22 +218,22 @@ namespace Foo
[Fact]
public async Task TestMalformedHeaderAsync()
{
- var testCode = @"//
+ var testCode = $@"//
#define MYDEFINE
namespace Foo
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
#define MYDEFINE
namespace Foo
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1633DescriptorMalformed).WithLocation(1, 1);
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1634UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1634UnitTests.cs
index e30b233a6..34289359a 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1634UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1634UnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
+ using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
@@ -32,8 +33,8 @@ namespace Bar
{
}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
//
// John Doe
@@ -41,8 +42,8 @@ namespace Bar
// This is a test file.
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 1);
@@ -58,16 +59,16 @@ namespace Bar
[Fact]
public async Task TestValidFileHeaderWithCopyrightLastAsync()
{
- var testCode = @"//
+ var testCode = $@"//
// John Doe
//
//
-// Copyright (c) FooCorp. All rights reserved.
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
@@ -86,13 +87,13 @@ namespace Bar
{
}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1635Descriptor).WithLocation(1, 4);
@@ -108,24 +109,24 @@ namespace Bar
[Fact]
public async Task TestInvalidFileHeaderWithCopyrightInWrongCaseAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
//
-// Copyright (c) FooCorp. All rights reserved.
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 1);
@@ -141,25 +142,25 @@ namespace Bar
[Fact]
public async Task TestValidMultiLineFileHeaderWithCopyrightLastAsync()
{
- var testCode = @"//
+ var testCode = $@"//
// John Doe
//
//
-// Copyright (c) FooCorp. All rights reserved.
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
// Licence is FooBar MIT.
//
namespace Bar
-{
-}
+{{
+}}
";
this.multiLineSettings = @"
{
""settings"": {
""documentationRules"": {
""companyName"": ""FooCorp"",
- ""copyrightText"": ""Copyright (c) FooCorp. All rights reserved.\n\nLicence is FooBar MIT.""
+ ""copyrightText"": ""{copyright} FooCorp. All rights reserved.\n\nLicence is FooBar MIT.""
}
}
}
@@ -183,8 +184,8 @@ namespace Bar
{
}
";
- var fixedCode = @" //
- // Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@" //
+ // Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
// FooCorp
//
@@ -192,8 +193,8 @@ namespace Bar
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 5);
@@ -218,8 +219,8 @@ namespace Bar
{
}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
//
// John Doe
@@ -227,8 +228,8 @@ namespace Bar
// This is a test file.
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 1);
@@ -254,8 +255,8 @@ namespace Bar
{
}
";
- var fixedCode = @"/*
- Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"/*
+ Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
John Doe
@@ -264,8 +265,8 @@ John Doe
*/
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 1);
@@ -291,8 +292,8 @@ namespace Bar
{
}
";
- var fixedCode = @"/*
- * Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"/*
+ * Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
*
* John Doe
@@ -301,8 +302,8 @@ namespace Bar
*/
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 1);
@@ -323,7 +324,7 @@ public async Task TestFileHeaderWithMultiLineCommentAndFieldsNeedingXmlEscapingA
""settings"": {
""documentationRules"": {
""companyName"": ""Foo & Bar \""quote\"" Corp"",
- ""copyrightText"": ""copyright (c) {companyName}. All rights reserved.\n\nLine #3""
+ ""copyrightText"": ""{copyright} {companyName}. All rights reserved.\n\nLine #3""
}
}
}
@@ -337,8 +338,8 @@ namespace Bar
}
";
- var fixedCode = @"//
-// copyright (c) Foo & Bar ""quote"" Corp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} Foo & Bar ""quote"" Corp. All rights reserved.
//
// Line #3
//
@@ -346,8 +347,8 @@ namespace Bar
// Foo & Bar Corp Bar Class
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1634Descriptor).WithLocation(1, 1);
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1635UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1635UnitTests.cs
index 3b6b7683b..8577a5e1b 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1635UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1635UnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
+ using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
@@ -27,13 +28,13 @@ namespace Bar
{
}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1635Descriptor).WithLocation(1, 4);
@@ -59,7 +60,7 @@ public async Task TestFileHeaderWithWhitespaceOnlyCopyrightAsync()
"}\r\n";
string fixedCode =
"// \r\n" +
- "// Copyright (c) FooCorp. All rights reserved.\r\n" +
+ $"// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.\r\n" +
"// \r\n" +
"\r\n" +
"namespace Bar\r\n" +
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1636UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1636UnitTests.cs
index 3dad6a391..d5e2487d2 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1636UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1636UnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
+ using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
@@ -19,7 +20,7 @@ public class SA1636UnitTests : FileHeaderTestBase
""settings"": {
""documentationRules"": {
""companyName"": ""FooCorp"",
- ""copyrightText"": ""copyright (c) {companyName}. All rights reserved.\n\nLine #3""
+ ""copyrightText"": ""{copyright} {companyName}. All rights reserved.\n\nLine #3""
}
}
}
@@ -30,7 +31,7 @@ public class SA1636UnitTests : FileHeaderTestBase
""settings"": {
""documentationRules"": {
""companyName"": ""FooCorp"",
- ""copyrightText"": ""copyright (c) {companyName}. All rights reserved.\n\nLine #3"",
+ ""copyrightText"": ""{copyright} {companyName}. All rights reserved.\n\nLine #3"",
""xmlHeader"": false
}
}
@@ -55,13 +56,13 @@ namespace Bar
{
}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(1, 4);
@@ -77,21 +78,21 @@ namespace Bar
[Fact]
public async Task TestFileHeaderWithInvalidCaseCopyrightMessageAsync()
{
- var testCode = @"//
-// copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. all rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(1, 4);
@@ -110,39 +111,39 @@ public async Task TestFileHeaderWillIgnoreLeadingAndTrailingWhitespaceAroundCopy
{
this.useMultiLineHeaderTestSettings = true;
- var testCode1 = @"//
-// copyright (c) FooCorp. All rights reserved.
+ var testCode1 = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
// Line #3
//
namespace Bar
-{
-}
+{{
+}}
";
- var testCode2 = @"/*
- copyright (c) FooCorp. All rights reserved.
+ var testCode2 = $@"/*
+ Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
Line #3
*/
namespace Bar
-{
-}
+{{
+}}
";
- var testCode3 = @"/*
+ var testCode3 = $@"/*
*
- * copyright (c) FooCorp. All rights reserved.
+ * Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
* Line #3
*
*/
namespace Bar
-{
-}
+{{
+}}
";
await this.VerifyCSharpDiagnosticAsync(new[] { testCode1, testCode2, testCode3 }, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
@@ -158,35 +159,35 @@ public async Task TestNoXmlFileHeaderWillIgnoreLeadingAndTrailingWhitespaceAroun
{
this.useNoXmlMultiLineHeaderTestSettings = true;
- var testCode1 = @"// copyright (c) FooCorp. All rights reserved.
+ var testCode1 = $@"// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
// Line #3
namespace Bar
-{
-}
+{{
+}}
";
- var testCode2 = @"/*
- * copyright (c) FooCorp. All rights reserved.
+ var testCode2 = $@"/*
+ * Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
* Line #3
*/
namespace Bar
-{
-}
+{{
+}}
";
- var testCode3 = @"/*
- copyright (c) FooCorp. All rights reserved.
+ var testCode3 = $@"/*
+ Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
Line #3
*/
namespace Bar
-{
-}
+{{
+}}
";
await this.VerifyCSharpDiagnosticAsync(new[] { testCode1, testCode2, testCode3 }, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
@@ -199,29 +200,29 @@ namespace Bar
[Fact]
public async Task TestFileHeaderFixWithReplaceCopyrightTagTextAsync()
{
- var testCode = @"//
+ var testCode = $@"//
// John Doe
//
//
-// Copyright (c) Not FooCorp. All rights reserved.
+// Copyright © {DateTime.Now.Year} Not FooCorp. All rights reserved.
//
// This is a test file.
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
+ var fixedCode = $@"//
// John Doe
//
//
-// Copyright (c) FooCorp. All rights reserved.
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
// This is a test file.
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(4, 4);
@@ -239,9 +240,9 @@ public async Task TestFileHeaderKeepsLeadingWhiteSpaceWhenFixingCopyrightMessage
{
this.useMultiLineHeaderTestSettings = true;
- var testCode = @" // FooCorp
+ var testCode = $@" // FooCorp
//
- // Not copyright (c) FooCorp. All rights reserved.
+ // Not Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
// Line #3
//
@@ -250,12 +251,12 @@ public async Task TestFileHeaderKeepsLeadingWhiteSpaceWhenFixingCopyrightMessage
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @" // FooCorp
+ var fixedCode = $@" // FooCorp
//
- // copyright (c) FooCorp. All rights reserved.
+ // Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
// Line #3
//
@@ -264,8 +265,8 @@ namespace Bar
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(2, 8);
@@ -283,10 +284,10 @@ public async Task TestFileHeaderWithMultiLineCommentAndNoLeadingStarsFixingCopyr
{
this.useMultiLineHeaderTestSettings = true;
- var testCode = @"/*
+ var testCode = $@"/*
FooCorp
- NOT copyright (c) FooCorp. All rights reserved.
+ NOT Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
Line #3
@@ -294,14 +295,14 @@ NOT copyright (c) FooCorp. All rights reserved.
*/
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"/*
+ var fixedCode = $@"/*
FooCorp
- copyright (c) FooCorp. All rights reserved.
+ Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
Line #3
@@ -309,8 +310,8 @@ namespace Bar
*/
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(3, 4);
@@ -328,10 +329,10 @@ public async Task TestFileHeaderWithMultiLineCommentAndLeadingStarsFixingCopyrig
{
this.useMultiLineHeaderTestSettings = true;
- var testCode = @"/*
+ var testCode = $@"/*
* FooCorp
*
- * NOT copyright (c) FooCorp. All rights reserved.
+ * NOT Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
* Line #3
*
@@ -339,14 +340,14 @@ public async Task TestFileHeaderWithMultiLineCommentAndLeadingStarsFixingCopyrig
*/
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"/*
+ var fixedCode = $@"/*
* FooCorp
*
- * copyright (c) FooCorp. All rights reserved.
+ * Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
* Line #3
*
@@ -354,8 +355,8 @@ namespace Bar
*/
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(3, 4);
@@ -374,9 +375,9 @@ public async Task TestFileHeaderWithMultiLineCommentAndAuthorAtTopAndLeadingStar
{
this.useMultiLineHeaderTestSettings = true;
- var testCode = @"/* FooCorp
+ var testCode = $@"/* FooCorp
*
- * NOT copyright (c) FooCorp. All rights reserved.
+ * NOT Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
* Line #3
*
@@ -384,13 +385,13 @@ public async Task TestFileHeaderWithMultiLineCommentAndAuthorAtTopAndLeadingStar
*/
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"/* FooCorp
+ var fixedCode = $@"/* FooCorp
*
- * copyright (c) FooCorp. All rights reserved.
+ * Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
* Line #3
*
@@ -398,8 +399,8 @@ namespace Bar
*/
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(2, 4);
@@ -418,8 +419,8 @@ public async Task TestFileHeaderWithMultiLineCommentAndCopyrightAtTopAndLeadingS
{
this.useMultiLineHeaderTestSettings = true;
- var testCode = @"/*
- * NOT copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"/*
+ * NOT Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
* Line #3
*
@@ -428,12 +429,12 @@ public async Task TestFileHeaderWithMultiLineCommentAndCopyrightAtTopAndLeadingS
*/
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"/*
- * copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"/*
+ * Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
*
* Line #3
*
@@ -442,8 +443,8 @@ namespace Bar
*/
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1636Descriptor).WithLocation(1, 4);
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1637UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1637UnitTests.cs
index 7c23151fc..af8b4b242 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1637UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1637UnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
+ using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
@@ -21,21 +22,21 @@ public class SA1637UnitTests : FileHeaderTestBase
[Fact]
public async Task TestCopyrightElementWithoutFileAttributeAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1637Descriptor).WithLocation(1, 4);
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1638UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1638UnitTests.cs
index 5b56ef35a..9cbb3a5c5 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1638UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1638UnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
+ using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
@@ -21,21 +22,21 @@ public class SA1638UnitTests : FileHeaderTestBase
[Fact]
public async Task TestCopyrightElementWithMismatchingFileAttributeAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1638Descriptor).WithLocation(1, 4);
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1639UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1639UnitTests.cs
index c95ce3c89..f29efa416 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1639UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1639UnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
+ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -23,13 +24,13 @@ public class SA1639UnitTests : FileHeaderTestBase
[Fact]
public async Task TestFileHeaderWithoutSummaryTagAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1639Descriptor).WithLocation(1, 1);
@@ -43,14 +44,14 @@ namespace Bar
[Fact]
public async Task TestFileHeaderWithEmptySummaryTagAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1639Descriptor).WithLocation(4, 4);
@@ -64,14 +65,14 @@ namespace Bar
[Fact]
public async Task TestFileHeaderWithWhitespaceOnlySummaryTagAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1639Descriptor).WithLocation(4, 4);
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1640UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1640UnitTests.cs
index a2f20f93b..1da765206 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1640UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1640UnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
+ using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
@@ -21,21 +22,21 @@ public class SA1640UnitTests : FileHeaderTestBase
[Fact]
public async Task TestCopyrightElementWithoutCompanyAttributeAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1640Descriptor).WithLocation(1, 4);
@@ -51,21 +52,21 @@ namespace Bar
[Fact]
public async Task TestCopyrightElementWithEmptyCompanyAttributeAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1640Descriptor).WithLocation(1, 4);
@@ -81,21 +82,21 @@ namespace Bar
[Fact]
public async Task TestCopyrightElementWithWhitespaceOnlyCompanyAttributeAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1640Descriptor).WithLocation(1, 4);
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1641UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1641UnitTests.cs
index 61a3e83fc..1091a44c1 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1641UnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1641UnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.DocumentationRules
{
+ using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
@@ -21,21 +22,21 @@ public class SA1641UnitTests : FileHeaderTestBase
[Fact]
public async Task TestCopyrightElementWithWrongCompanyAttributeAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1641Descriptor).WithLocation(1, 4);
@@ -51,21 +52,21 @@ namespace Bar
[Fact]
public async Task TestCopyrightElementWithInvalidCaseCompanyAttributeAsync()
{
- var testCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var testCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
- var fixedCode = @"//
-// Copyright (c) FooCorp. All rights reserved.
+ var fixedCode = $@"//
+// Copyright © {DateTime.Now.Year} FooCorp. All rights reserved.
//
namespace Bar
-{
-}
+{{
+}}
";
var expectedDiagnostic = this.CSharpDiagnostic(FileHeaderAnalyzers.SA1641Descriptor).WithLocation(1, 4);
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/Settings/SettingsUnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/Settings/SettingsUnitTests.cs
index 7a9820c46..b8d1a3412 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/Settings/SettingsUnitTests.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/Settings/SettingsUnitTests.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Test.Settings
{
+ using System;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
@@ -24,7 +25,7 @@ public void VerifySettingsDefaults()
var styleCopSettings = SettingsHelper.GetStyleCopSettings(default(SyntaxTreeAnalysisContext));
Assert.Equal("PlaceholderCompany", styleCopSettings.DocumentationRules.CompanyName);
- Assert.Equal("Copyright (c) PlaceholderCompany. All rights reserved.", styleCopSettings.DocumentationRules.CopyrightText);
+ Assert.Equal($"Copyright © {DateTime.Now.Year} PlaceholderCompany. All rights reserved.", styleCopSettings.DocumentationRules.CopyrightText);
Assert.True(styleCopSettings.NamingRules.AllowCommonHungarianPrefixes);
Assert.Equal(0, styleCopSettings.NamingRules.AllowedHungarianPrefixes.Length);
@@ -86,7 +87,7 @@ public async Task VerifySettingsWillUseCompanyNameInDefaultCopyrightTextAsync()
var styleCopSettings = context.GetStyleCopSettings();
Assert.Equal("TestCompany", styleCopSettings.DocumentationRules.CompanyName);
- Assert.Equal("Copyright (c) TestCompany. All rights reserved.", styleCopSettings.DocumentationRules.CopyrightText);
+ Assert.Equal($"Copyright © {DateTime.Now.Year} TestCompany. All rights reserved.", styleCopSettings.DocumentationRules.CopyrightText);
}
[Fact]
@@ -137,7 +138,7 @@ public async Task VerifyInvalidJsonBehaviorAsync()
// The result is the same as the default settings.
Assert.Equal("PlaceholderCompany", styleCopSettings.DocumentationRules.CompanyName);
- Assert.Equal("Copyright (c) PlaceholderCompany. All rights reserved.", styleCopSettings.DocumentationRules.CopyrightText);
+ Assert.Equal($"Copyright © {DateTime.Now.Year} PlaceholderCompany. All rights reserved.", styleCopSettings.DocumentationRules.CopyrightText);
}
private static async Task CreateAnalysisContextAsync(string stylecopJSON)
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/FileHeaderAnalyzers.cs b/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/FileHeaderAnalyzers.cs
index 69e8182fa..c4d6d076f 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/FileHeaderAnalyzers.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/FileHeaderAnalyzers.cs
@@ -6,6 +6,7 @@ namespace StyleCop.Analyzers.DocumentationRules
using System;
using System.Collections.Immutable;
using System.IO;
+ using System.Text.RegularExpressions;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
@@ -83,6 +84,8 @@ internal class FileHeaderAnalyzers : DiagnosticAnalyzer
private static readonly LocalizableString SA1641Description = new LocalizableResourceString(nameof(DocumentationResources.SA1641Description), DocumentationResources.ResourceManager, typeof(DocumentationResources));
private static readonly string SA1641HelpLink = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1641.md";
+ private static readonly Regex Copyright = new Regex("Copyright © [0-9]{4}((, [0-9]{4})|(-[0-9]{4}(?!-)))*");
+
///
/// Gets the diagnostic descriptor for SA1633 with a missing header.
///
@@ -374,10 +377,10 @@ private static void CheckSummaryHeader(SyntaxTreeAnalysisContext context, Compil
private static bool CompareCopyrightText(string copyrightText, StyleCopSettings settings)
{
- // make sure that both \n and \r\n are accepted from the settings.
+ // Make sure that both \n and \r\n are accepted from the settings.
+ // Convert the file header's copyright declarations into a string that will match the header.
var reformattedCopyrightTextParts = settings.DocumentationRules.CopyrightText.Replace("\r\n", "\n").Split('\n');
- var fileHeaderCopyrightTextParts = copyrightText.Replace("\r\n", "\n").Split('\n');
-
+ var fileHeaderCopyrightTextParts = Copyright.Replace(copyrightText.Replace("\r\n", "\n"), $"Copyright © {DateTime.Now.Year}").Split('\n');
if (reformattedCopyrightTextParts.Length != fileHeaderCopyrightTextParts.Length)
{
return false;
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Settings/ObjectModel/DocumentationSettings.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Settings/ObjectModel/DocumentationSettings.cs
index 23cdfe4b6..cf0c29321 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers/Settings/ObjectModel/DocumentationSettings.cs
+++ b/StyleCop.Analyzers/StyleCop.Analyzers/Settings/ObjectModel/DocumentationSettings.cs
@@ -3,6 +3,7 @@
namespace StyleCop.Analyzers.Settings.ObjectModel
{
+ using System;
using System.Collections.Immutable;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
@@ -18,7 +19,7 @@ internal class DocumentationSettings
///
/// The default value for the property.
///
- internal const string DefaultCopyrightText = "Copyright (c) {companyName}. All rights reserved.";
+ internal const string DefaultCopyrightText = "{copyright} {companyName}. All rights reserved.";
///
/// This is the backing field for the property.
@@ -167,14 +168,17 @@ private string BuildCopyrightText()
match =>
{
string key = match.Groups["Property"].Value;
- switch (key)
- {
+ switch (key)
+ {
case "companyName":
return this.CompanyName;
case "copyrightText":
return "[CircularReference]";
+ case "copyright":
+ return $"Copyright © {DateTime.Now.Year}";
+
default:
string value;
if (this.Variables.TryGetValue(key, out value))
diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json b/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json
index ed9e5a23a..7aad57a13 100644
--- a/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json
+++ b/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json
@@ -98,7 +98,7 @@
"copyrightText": {
"type": "string",
"description": "The copyright text which should appear in file headers.",
- "default": "Copyright (c) {companyName}. All rights reserved."
+ "default": "{copyright} {companyName}. All rights reserved."
},
"variables": {
"type": "object",
diff --git a/documentation/Configuration.md b/documentation/Configuration.md
index 1d5157a4e..7b47681f1 100644
--- a/documentation/Configuration.md
+++ b/documentation/Configuration.md
@@ -157,24 +157,33 @@ The following properties are used to configure copyright headers in StyleCop Ana
| Property | Default Value | Summary |
| --- | --- | --- |
| `companyName` | `"PlaceholderCompany"` | Specifies the company name which should appear in copyright notices |
+| `copyright` | `"Copyright © 2015"` | Specifies a copyright declaration. The year matches the current year. |
| `copyrightText` | `"Copyright (c) {companyName}. All rights reserved."` | Specifies the default copyright text which should appear in copyright headers |
| `xmlHeader` | **true** | Specifies whether file headers should use standard StyleCop XML format, where the copyright notice is wrapped in a `` element |
| `variables` | n/a | Specifies replacement variables which can be referenced in the `copyrightText` value |
+The `copyright` property is special, in that it will match any single four-digit year, or any comma-separated list of years or year ranges. Thus, all of the following would match the {copyright} variable:
+
+* Copyright © 2015
+* Copyright © 2010-2015
+* Copyright © 2010, 2012-2013, 2015
+
+When the `copyright` variable is in use, suggested fixes will use the current year.
+
#### Configuring Copyright Text
In order to successfully use StyleCop-checked file headers, most projects will need to configure the `companyName` property.
> The `companyName` property is so frequently customized that it is included in the default **stylecop.json** file produced by the code fix.
-The `copyrightText` property is a string which may contain placeholders. Each placeholder has the form `{variable}`, where `variable` is either `companyName` or the name of a property in the `variables` property. The following sample file shows a custom **stylecop.json** file which references both `companyName` and two custom variables within the `copyrightText`.
+The `copyrightText` property is a string which may contain placeholders. Each placeholder has the form `{variable}`, where `variable` is either `companyName`, `copyright`, or the name of a property in the `variables` property. The following sample file shows a custom **stylecop.json** file which references `companyName`, `copyright` and two custom variables within the `copyrightText`.
```json
{
"settings": {
"documentationRules": {
"companyName": "FooCorp",
- "copyrightText": "Copyright (c) {companyName}. All rights reserved.\nLicensed under the {licenseName} license. See {licenseFile} file in the project root for full license information.",
+ "copyrightText": "{copyright} {companyName}. All rights reserved.\nLicensed under the {licenseName} license. See {licenseFile} file in the project root for full license information.",
"variables": {
"licenseName": "MIT",
"licenseFile": "LICENSE",
@@ -188,7 +197,7 @@ With the above configuration, a file **TypeName.cs** would be expected to have t
```csharp
//
-// Copyright (c) FooCorp. All rights reserved.
+// Copyright © 2015 FooCorp. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
```