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

Commit 7544f54

Browse files
committed
Some work on the new idea
1 parent 1c36943 commit 7544f54

File tree

3 files changed

+134
-2
lines changed

3 files changed

+134
-2
lines changed

src/Microsoft.DotNet.CodeFormatting/FormattingEngineImplementation.cs

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,25 @@ internal sealed class FormattingEngineImplementation : IFormattingEngine
2222
{
2323
private readonly IEnumerable<IFormattingFilter> _filters;
2424
private readonly IEnumerable<IFormattingRule> _rules;
25+
private readonly IEnumerable<ISyntaxFormattingRule> _syntaxRules;
26+
private readonly IEnumerable<ILocalSemanticFormattingRule> _localSemanticRules;
27+
private readonly IEnumerable<IGlobalSemanticFormattingRule> _globalSemanticRules;
28+
private readonly bool _verbose;
29+
private readonly Stopwatch _watch = new Stopwatch();
2530

2631
[ImportingConstructor]
27-
public FormattingEngineImplementation([ImportMany] IEnumerable<IFormattingFilter> filters,
28-
[ImportMany] IEnumerable<Lazy<IFormattingRule, IOrderMetadata>> rules)
32+
public FormattingEngineImplementation(
33+
[ImportMany] IEnumerable<IFormattingFilter> filters,
34+
[ImportMany] IEnumerable<Lazy<IFormattingRule, IOrderMetadata>> rules,
35+
[ImportMany] IEnumerable<Lazy<ISyntaxFormattingRule, IOrderMetadata>> syntaxRules,
36+
[ImportMany] IEnumerable<Lazy<ILocalSemanticFormattingRule, IOrderMetadata>> localSemanticRules,
37+
[ImportMany] IEnumerable<Lazy<IGlobalSemanticFormattingRule, IOrderMetadata>> globalSemanticRules)
2938
{
3039
_filters = filters;
3140
_rules = rules.OrderBy(r => r.Metadata.Order).Select(r => r.Value);
41+
_syntaxRules = syntaxRules.OrderBy(r => r.Metadata.Order).Select(r => r.Value);
42+
_localSemanticRules = localSemanticRules.OrderBy(r => r.Metadata.Order).Select(r => r.Value);
43+
_globalSemanticRules = globalSemanticRules.OrderBy(r => r.Metadata.Order).Select(r => r.Value);
3244
}
3345

3446
public Task<bool> FormatSolutionAsync(Solution solution, CancellationToken cancellationToken)
@@ -115,6 +127,97 @@ private async Task<Document> RewriteDocumentAsync(Document document, List<Tuple<
115127
return await ChangeEncoding(document, originalEncoding);
116128
}
117129

130+
private void StartDocument(Document document)
131+
{
132+
Console.Write("\tProcessing {0}", document.Name);
133+
_watch.Restart();
134+
}
135+
136+
private void EndDocument()
137+
{
138+
_watch.Stop();
139+
if (_verbose && _watch.Elapsed.TotalSeconds > 1)
140+
{
141+
142+
}
143+
}
144+
145+
private Task<Solution> FormatDocumentsSyntaxPass(Solution originalSolution, IReadOnlyList<DocumentId> documentIds, CancellationToken cancellationToken)
146+
{
147+
Console.WriteLine("Syntax Pass");
148+
149+
var currentSolution = originalSolution;
150+
foreach (var documentId in documentIds)
151+
{
152+
var document = originalSolution.GetDocument(documentId);
153+
154+
Console.Write("\tProcessing {0}", document.Name);
155+
156+
watch.Restart();
157+
var newRoot = await documentFunc(document);
158+
watch.Stop();
159+
160+
if (_verbose && watch.Elapsed.TotalSeconds > 1)
161+
{
162+
Console.Write(" {0} seconds", watch.Elapsed.TotalSeconds);
163+
}
164+
Console.WriteLine();
165+
166+
if (newRoot != null)
167+
{
168+
currentSolution = currentSolution.WithDocumentSyntaxRoot(documentId, newRoot);
169+
}
170+
}
171+
172+
return currentSolution;
173+
}
174+
175+
private async Task<Solution> FormatDocumentsLocalSemanticPass(Solution originalSolution, IReadOnlyList<DocumentId> documentIds, CancellationToken cancellationToken)
176+
{
177+
Console.WriteLine("Local Semantic Pass");
178+
Func<Document, Task<SyntaxTree> documentFunc = async(documentFunc) =>
179+
{
180+
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken);
181+
if (syntaxRoot == null)
182+
{
183+
return null;
184+
}
185+
186+
return FormatLocalSemantic(document, syntaxRoot);
187+
};
188+
189+
return FormatDocumentsCore(originalSolution, documentIds, documentFunc, cancellationToken);
190+
}
191+
192+
private async Task<Solution> FormatDocumentsCore(
193+
Solution originalSolution,
194+
IReadOnlyList<DocumentId> documentIds,
195+
Func<Document, Task<SyntaxTree> documentFunc,
196+
CancellationToken cancellationToken)
197+
{
198+
}
199+
200+
private Task<SyntaxTree> FormatSyntaxTree(Document document, SyntaxNode syntaxRoot)
201+
{
202+
foreach (var syntaxRule in _syntaxRules)
203+
{
204+
syntaxRoot = syntaxRule.Process(syntaxRoot);
205+
}
206+
207+
return Task.FromResult(root);
208+
}
209+
210+
private async Task<SyntaxTree> FormatLocalSemantic(Document originalDocument, SyntaxNode originalSyntaxRoot)
211+
{
212+
var currentSyntaxRoot = originalSyntaxRoot;
213+
foreach (var localSemanticRule in _localSemanticRules)
214+
{
215+
currentSyntaxRoot = await localSemanticRule.ProcessAsync(originalDocument, originalSyntaxRoot, currentSyntaxRoot)
216+
}
217+
218+
return currentSyntaxRoot;
219+
}
220+
118221
private async Task<Document> ChangeEncoding(Document document, Encoding encoding)
119222
{
120223
var text = await document.GetTextAsync();

src/Microsoft.DotNet.CodeFormatting/IFormattingFilter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
namespace Microsoft.DotNet.CodeFormatting
1010
{
11+
// TODO: does this need to be async?
1112
internal interface IFormattingFilter
1213
{
1314
Task<bool> ShouldBeProcessedAsync(Document document);

src/Microsoft.DotNet.CodeFormatting/IFormattingRule.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,36 @@
99

1010
namespace Microsoft.DotNet.CodeFormatting
1111
{
12+
// TODO: delete
1213
internal interface IFormattingRule
1314
{
1415
Task<Document> ProcessAsync(Document document, CancellationToken cancellationToken);
1516
}
17+
18+
/// <summary>
19+
/// Rules which need no semantic information and operate on parse trees only
20+
/// </summary>
21+
internal interface ISyntaxFormattingRule
22+
{
23+
SyntaxNode Process(SyntaxNode syntaxRoot);
24+
}
25+
26+
/// <summary>
27+
/// Rules which possibly need semantic information but only operate on a
28+
/// specific document.
29+
/// </summary>
30+
internal interface ILocalSemanticFormattingRule
31+
{
32+
Task Record(Document document, SyntaxRoot )
33+
34+
Task<SyntaxNode> ProcessAsync(Document originalDocument, SyntaxNode originalSyntaxRoot, SyntaxNode currentSyntaxRoot, CancellationToken cancellationToken);
35+
}
36+
37+
/// <summary>
38+
/// Rules which can affect more than the local document
39+
/// </summary>
40+
internal interface IGlobalSemanticFormattingRule
41+
{
42+
Task<Solution> ProcessAsync(Solution solution, CancellationToken cancellationToken);
43+
}
1644
}

0 commit comments

Comments
 (0)