Skip to content
This repository was archived by the owner on Jul 12, 2022. It is now read-only.

Commit 0c2541f

Browse files
author
Lakshmi Priya Sekar
committed
Make code review fixes and some rule bug fixes
1 parent 7a93c15 commit 0c2541f

File tree

5 files changed

+172
-5
lines changed

5 files changed

+172
-5
lines changed

src/CodeFormatter/CodeFormatter.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
</ItemGroup>
106106
<ItemGroup>
107107
<None Include="App.config" />
108+
<None Include="CopyrightHeader.md" />
108109
<None Include="IllegalHeaders.md" />
109110
<None Include="packages.config" />
110111
</ItemGroup>
@@ -121,5 +122,6 @@
121122
</Target> -->
122123
<Target Name="AfterBuild">
123124
<Copy SourceFiles="$(ProjectDir)IllegalHeaders.md" DestinationFolder="$(OutDir)" ContinueOnError="true" />
125+
<Copy SourceFiles="$(ProjectDir)CopyrightHeader.md" DestinationFolder="$(OutDir)" ContinueOnError="true" />
124126
</Target>
125127
</Project>

src/CodeFormatter/CopyrightHeader.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## Copyright header styles to be removed.
2+
## First line - RuleMarker
3+
## Second line - StartMarker
4+
## Last line - EndMarker
5+
6+
// ==++==
7+
//
8+
// ==--==

src/Microsoft.DotNet.CodeFormatting/Microsoft.DotNet.CodeFormatting.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
<Compile Include="Rules\HasNoIllegalHeadersFormattingRule.cs" />
9393
<Compile Include="Rules\HasNoNewLineAfterOpenBraceFormattingRule.cs" />
9494
<Compile Include="Rules\HasNoNewLineBeforeEndBraceFormattingRule.cs" />
95-
<Compile Include="Rules\HasNoXmlBasedCopyrightHeaderFormattingRule.cs" />
95+
<Compile Include="Rules\HasNoCustomCopyrightHeaderFormattingRule.cs" />
9696
<Compile Include="Rules\HasPrivateAccessorOnFieldNamesFormattingRule.cs" />
9797
<Compile Include="Rules\HasUnderScoreInPrivateFieldNamesFormattingRule.cs" />
9898
<Compile Include="Rules\HasUsingsOutsideOfNamespaceFormattingRule.cs" />
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under MIT. See LICENSE in the project root for license information.
3+
using System;
4+
using System.Collections.Generic;
5+
using System.ComponentModel.Composition;
6+
using System.IO;
7+
using System.Linq;
8+
using System.Reflection;
9+
using System.Threading;
10+
using System.Threading.Tasks;
11+
12+
using Microsoft.CodeAnalysis;
13+
using Microsoft.CodeAnalysis.CSharp;
14+
15+
namespace Microsoft.DotNet.CodeFormatting.Rules
16+
{
17+
[RuleOrder(1)]
18+
internal sealed class HasNoCustomCopyrightHeaderFormattingRule : IFormattingRule
19+
{
20+
private static string RulerMarker { get; set; }
21+
private static string StartMarker { get; set;}
22+
private static string EndMarker { get; set; }
23+
24+
public async Task<Document> ProcessAsync(Document document, CancellationToken cancellationToken)
25+
{
26+
var syntaxNode = await document.GetSyntaxRootAsync(cancellationToken) as CSharpSyntaxNode;
27+
if (syntaxNode == null)
28+
return document;
29+
30+
var triviaList = syntaxNode.GetLeadingTrivia();
31+
32+
// SetHeaders
33+
SetHeaders();
34+
35+
SyntaxTrivia start;
36+
SyntaxTrivia end;
37+
if (!TryGetStartAndEndOfXmlHeader(triviaList, out start, out end))
38+
return document;
39+
40+
var filteredList = Filter(triviaList, start, end);
41+
var newSyntaxNode = syntaxNode.WithLeadingTrivia(filteredList);
42+
return document.WithSyntaxRoot(newSyntaxNode);
43+
}
44+
45+
private static IEnumerable<SyntaxTrivia> Filter(SyntaxTriviaList triviaList, SyntaxTrivia start, SyntaxTrivia end)
46+
{
47+
var inHeader = false;
48+
49+
foreach (var trivia in triviaList)
50+
{
51+
if (trivia == start)
52+
inHeader = true;
53+
else if (trivia == end)
54+
inHeader = false;
55+
else if (!inHeader)
56+
yield return trivia;
57+
}
58+
}
59+
60+
private static bool TryGetStartAndEndOfXmlHeader(SyntaxTriviaList triviaList, out SyntaxTrivia start, out SyntaxTrivia end)
61+
{
62+
start = default(SyntaxTrivia);
63+
end = default(SyntaxTrivia);
64+
65+
var hasStart = false;
66+
var hasEnd = false;
67+
68+
foreach (var trivia in triviaList)
69+
{
70+
if (!hasStart && IsBeginningOfXmlHeader(trivia, out start))
71+
hasStart = true;
72+
73+
if (!hasEnd && IsEndOfXmlHeader(trivia, out end))
74+
hasEnd = true;
75+
}
76+
77+
return hasStart && hasEnd;
78+
}
79+
80+
private static bool IsBeginningOfXmlHeader(SyntaxTrivia trivia, out SyntaxTrivia start)
81+
{
82+
var next = GetNextComment(trivia);
83+
84+
var currentFullText = trivia.ToFullString();
85+
var nextFullText = next == null ? string.Empty : next.Value.ToFullString();
86+
87+
start = trivia;
88+
return currentFullText.StartsWith(StartMarker, StringComparison.OrdinalIgnoreCase) ||
89+
currentFullText.StartsWith(RulerMarker, StringComparison.OrdinalIgnoreCase) &&
90+
nextFullText.StartsWith(StartMarker, StringComparison.OrdinalIgnoreCase);
91+
}
92+
93+
private static bool IsEndOfXmlHeader(SyntaxTrivia trivia, out SyntaxTrivia end)
94+
{
95+
var next = GetNextComment(trivia);
96+
97+
var currentFullText = trivia.ToFullString();
98+
var nextFullText = next == null ? string.Empty : next.Value.ToFullString();
99+
100+
end = nextFullText.StartsWith(RulerMarker, StringComparison.OrdinalIgnoreCase)
101+
? next.Value
102+
: trivia;
103+
return currentFullText.StartsWith(EndMarker, StringComparison.OrdinalIgnoreCase);
104+
}
105+
106+
private static SyntaxTrivia? GetNextComment(SyntaxTrivia currentTrivia)
107+
{
108+
var trivia = currentTrivia.Token.LeadingTrivia;
109+
return trivia.SkipWhile(t => t != currentTrivia)
110+
.Skip(1)
111+
.SkipWhile(t => t.CSharpKind() != SyntaxKind.SingleLineCommentTrivia)
112+
.Select(t => (SyntaxTrivia?)t)
113+
.FirstOrDefault();
114+
}
115+
116+
private static void SetHeaders()
117+
{
118+
var filePath = Path.Combine(
119+
Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path)),
120+
"CopyrightHeader.md");
121+
122+
if (!File.Exists(filePath))
123+
{
124+
RulerMarker = "";
125+
StartMarker = "";
126+
EndMarker = "";
127+
}
128+
else
129+
{
130+
var lines = File.ReadAllLines(filePath).Where(l => !l.StartsWith("##") && !l.Equals("")).ToArray();
131+
RulerMarker = lines[0];
132+
StartMarker = lines[1];
133+
EndMarker = lines[2];
134+
}
135+
}
136+
}
137+
}

src/Microsoft.DotNet.CodeFormatting/Rules/HasNoIllegalHeadersFormattingRule.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ public async Task<Document> ProcessAsync(Document document, CancellationToken ca
2525
return document;
2626

2727
var leadingTrivia = syntaxNode.GetLeadingTrivia();
28-
IEnumerable<SyntaxTrivia> newTrivia = leadingTrivia;
28+
SyntaxTriviaList newTrivia = leadingTrivia;
2929
var illegalHeaders = GetIllegalHeaders();
3030

3131
foreach (var trivia in leadingTrivia)
3232
{
33-
if (illegalHeaders.Any(trivia.ToFullString().Contains))
33+
if (illegalHeaders.Any(s => trivia.ToFullString().IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0))
3434
{
35-
newTrivia = newTrivia.Where(t => t.ToFullString() != trivia.ToFullString());
35+
newTrivia = RemoveTrivia(newTrivia, trivia);
3636
}
3737
}
3838

@@ -42,7 +42,7 @@ public async Task<Document> ProcessAsync(Document document, CancellationToken ca
4242
return document.WithSyntaxRoot(syntaxNode.WithLeadingTrivia(newTrivia));
4343
}
4444

45-
public static HashSet<string> GetIllegalHeaders()
45+
private static HashSet<string> GetIllegalHeaders()
4646
{
4747
var filePath = Path.Combine(
4848
Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path)),
@@ -55,5 +55,25 @@ public static HashSet<string> GetIllegalHeaders()
5555

5656
return new HashSet<string>(File.ReadAllLines(filePath).Where(l => !l.StartsWith("##") && !l.Equals("")), StringComparer.OrdinalIgnoreCase);
5757
}
58+
59+
private static SyntaxTriviaList RemoveTrivia(SyntaxTriviaList leadingTrivia, SyntaxTrivia trivia)
60+
{
61+
SyntaxTriviaList newTrivia = leadingTrivia;
62+
var index = leadingTrivia.IndexOf(trivia);
63+
if (leadingTrivia.ElementAt(index + 1).CSharpKind() == SyntaxKind.EndOfLineTrivia)
64+
{
65+
// Remove trivia
66+
newTrivia = newTrivia.RemoveAt(index);
67+
// Remove end of line after trivia
68+
newTrivia = newTrivia.RemoveAt(index);
69+
}
70+
else
71+
{
72+
// Remove trivia
73+
newTrivia = newTrivia.RemoveAt(index);
74+
}
75+
76+
return newTrivia;
77+
}
5878
}
5979
}

0 commit comments

Comments
 (0)