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. // ```