Skip to content

Commit 39d8ea9

Browse files
committed
tmp
1 parent d7ff895 commit 39d8ea9

File tree

5 files changed

+342
-58
lines changed

5 files changed

+342
-58
lines changed

src/PortToTripleSlash/.lutignore

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
## The .lutignore file is used by Live Unit Testing to ignore Visual Studio temporary files, build results,
2+
## and files generated by popular Visual Studio add-ons when creating a private copy of the source tree that
3+
## Live Unit Testing uses for its build.
4+
##
5+
## This file has same format as git's .gitignore file (https://git-scm.com/docs/gitignore). In fact, in the
6+
## case where a .lutignore file is not found, but a .gitignore file is found, Live Unit Testing will use the
7+
## .gitignore file directly for the above purpose.
8+
9+
# User-specific files
10+
*.suo
11+
*.user
12+
*.userprefs
13+
*.sln.docstates
14+
.vs/
15+
.vscode/
16+
.packages/
17+
.dotnet/
18+
.tools/
19+
.idea/
20+
21+
# Build results
22+
[Dd]ebug/
23+
[Rr]elease/
24+
[Bb]inaries/
25+
[Bb]in/
26+
[Oo]bj/
27+
x64/
28+
TestResults/
29+
30+
# Debug artifactss
31+
launchSettings.json
32+
33+
# Click-Once directory
34+
publish/
35+
36+
# Publish Web Output
37+
*.Publish.xml
38+
39+
# NuGet Packages Directory
40+
packages/
41+
42+
# NuGet V3 artifacts
43+
[Nn]u[Gg]et.exe
44+
*-packages.config
45+
*.nuget.props
46+
*.nuget.targets
47+
project.lock.json
48+
msbuild.binlog
49+
*.project.lock.json
50+
51+
# Miscellaneous
52+
*_i.c
53+
*_p.c
54+
*.ilk
55+
*.meta
56+
*.obj
57+
*.pch
58+
*.pdb
59+
*.pgc
60+
*.pgd
61+
*.sbr
62+
*.tlb
63+
*.tli
64+
*.tlh
65+
*.tmp
66+
*.tmp_proj
67+
*.log
68+
*.wrn
69+
*.vspscc
70+
*.vssscc
71+
.builds
72+
*.pidb
73+
*.scc
74+
sql/
75+
*.Cache
76+
ClientBin/
77+
[Ss]tyle[Cc]op.*
78+
~$*
79+
*~
80+
*.dbmdl
81+
*.[Pp]ublish.xml
82+
*.pfx
83+
*.publishsettings
84+
85+
# Visual Studio cache files
86+
*.sln.ide/
87+
88+
# Visual C++ cache files
89+
ipch/
90+
*.aps
91+
*.ncb
92+
*.opensdf
93+
*.sdf
94+
*.cachefile
95+
*.VC.opendb
96+
*.VC.db
97+
98+
# Windows Store app package directory
99+
AppPackages/
100+
101+
# Visual Studio profiler
102+
*.psess
103+
*.vsp
104+
*.vspx
105+
106+
# Guidance Automation Toolkit
107+
*.gpState
108+
109+
# ReSharper
110+
_ReSharper*/
111+
*.[Rr]e[Ss]harper
112+
*.DotSettings
113+
114+
# TeamCity is a build add-in
115+
_TeamCity*
116+
117+
# DotCover is a Code Coverage Tool
118+
*.dotCover
119+
120+
# NCrunch
121+
*.ncrunch*
122+
.*crunch*.local.xml
123+
124+
# Upgrade backups
125+
_UpgradeReport_Files/
126+
Backup*/
127+
UpgradeLog*.XML
128+
UpgradeLog*.htm
129+
130+
# SQL Server files
131+
App_Data/*.mdf
132+
App_Data/*.ldf
133+
134+
#LightSwitch generated files
135+
GeneratedArtifacts/
136+
_Pvt_Extensions/
137+
ModelManifest.xml
138+
139+
# Windows image file caches
140+
Thumbs.db
141+
ehthumbs.db
142+
143+
# Folder config file
144+
Desktop.ini
145+
146+
# Recycle Bin used on file shares
147+
$RECYCLE.BIN/
148+
149+
# Mac desktop service store files
150+
.DS_Store
151+
152+
# WPF temp projects
153+
*wpftmp.*
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<LUTConfig Version="1.0">
2+
<Repository />
3+
<ParallelBuilds>true</ParallelBuilds>
4+
<ParallelTestRuns>true</ParallelTestRuns>
5+
<TestCaseTimeout>180000</TestCaseTimeout>
6+
</LUTConfig>

src/PortToTripleSlash/src/libraries/RoslynTripleSlash/TripleSlashSyntaxRewriter.cs

Lines changed: 66 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Diagnostics;
77
using System.Diagnostics.CodeAnalysis;
88
using System.Linq;
9+
using System.Xml.Linq;
910
using ApiDocsSync.PortToTripleSlash.Docs;
1011
using Microsoft.CodeAnalysis;
1112
using Microsoft.CodeAnalysis.CSharp;
@@ -164,10 +165,14 @@ internal class TripleSlashSyntaxRewriter : CSharpSyntaxRewriter
164165
private const string Space = " ";
165166
private const string NewLine = "\n";
166167

168+
private static readonly char[] _NewLineSeparators = ['\n', '\r'];
169+
private const StringSplitOptions _NewLineSplitOptions = StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries;
170+
167171
private DocsCommentsContainer DocsComments { get; }
168172
private ResolvedLocation Location { get; }
169173
private SemanticModel Model => Location.Model;
170174

175+
171176
public TripleSlashSyntaxRewriter(DocsCommentsContainer docsComments, ResolvedLocation resolvedLocation) : base(visitIntoStructuredTrivia: false)
172177
{
173178
DocsComments = docsComments;
@@ -422,105 +427,117 @@ internal static SyntaxList<SyntaxNode> GetOrCreateXmlNodes(IDocsAPI api, SyntaxL
422427
{
423428
List<SyntaxNode> updated = new();
424429

425-
if(TryGetOrCreateXmlNode(originalXmls, SummaryTag, api.Summary, attributeValue: null, out XmlNodeSyntax? summaryNode, out _))
430+
if(TryGetOrCreateXmlRows(originalXmls, SummaryTag, api.Summary, attributeValue: null, indentationTrivia, out List<XmlNodeSyntax> summaryNodes, out _))
426431
{
427-
updated.AddRange(GetXmlRow(summaryNode, indentationTrivia));
432+
updated.AddRange(summaryNodes);
428433
}
429434

430-
if (TryGetOrCreateXmlNode(originalXmls, ValueTag, api.Value, attributeValue: null, out XmlNodeSyntax? valueNode, out _))
435+
if (TryGetOrCreateXmlRows(originalXmls, ValueTag, api.Value, attributeValue: null, indentationTrivia, out List<XmlNodeSyntax> valueNodes, out _))
431436
{
432-
updated.AddRange(GetXmlRow(valueNode, indentationTrivia));
437+
updated.AddRange(valueNodes);
433438
}
434439

435440
foreach (DocsTypeParam typeParam in api.TypeParams)
436441
{
437-
if (TryGetOrCreateXmlNode(originalXmls, TypeParamTag, typeParam.Value, attributeValue: typeParam.Name, out XmlNodeSyntax? typeParamNode, out _))
442+
if (TryGetOrCreateXmlRows(originalXmls, TypeParamTag, typeParam.Value, attributeValue: typeParam.Name, indentationTrivia, out List<XmlNodeSyntax> typeParamNodes, out _))
438443
{
439-
updated.AddRange(GetXmlRow(typeParamNode, indentationTrivia));
444+
updated.AddRange(typeParamNodes);
440445
}
441446
}
442447

443448
foreach (DocsParam param in api.Params)
444449
{
445-
if (TryGetOrCreateXmlNode(originalXmls, ParamTag, param.Value, attributeValue: param.Name, out XmlNodeSyntax? paramNode, out _))
450+
if (TryGetOrCreateXmlRows(originalXmls, ParamTag, param.Value, attributeValue: param.Name, indentationTrivia, out List<XmlNodeSyntax> paramNodes, out _))
446451
{
447-
updated.AddRange(GetXmlRow(paramNode, indentationTrivia));
452+
updated.AddRange(paramNodes);
448453
}
449454
}
450455

451-
if (TryGetOrCreateXmlNode(originalXmls, ReturnsTag, api.Returns, attributeValue: null, out XmlNodeSyntax? returnsNode, out _))
456+
if (TryGetOrCreateXmlRows(originalXmls, ReturnsTag, api.Returns, attributeValue: null, indentationTrivia, out List<XmlNodeSyntax> returnsNodes, out _))
452457
{
453-
updated.AddRange(GetXmlRow(returnsNode, indentationTrivia));
458+
updated.AddRange(returnsNodes);
454459
}
455460

456461
foreach (DocsException exception in api.Exceptions)
457462
{
458-
if (TryGetOrCreateXmlNode(originalXmls, ExceptionTag, exception.Value, attributeValue: exception.Cref[2..], out XmlNodeSyntax? exceptionNode, out _))
463+
if (TryGetOrCreateXmlRows(originalXmls, ExceptionTag, exception.Value, attributeValue: exception.Cref[2..], indentationTrivia, out List<XmlNodeSyntax> exceptionNodes, out _))
459464
{
460-
updated.AddRange(GetXmlRow(exceptionNode, indentationTrivia));
465+
updated.AddRange(exceptionNodes);
461466
}
462467
}
463468

464-
if (TryGetOrCreateXmlNode(originalXmls, RemarksTag, api.Remarks, attributeValue: null, out XmlNodeSyntax? remarksNode, out bool isBackported) &&
469+
if (TryGetOrCreateXmlRows(originalXmls, RemarksTag, api.Remarks, attributeValue: null, indentationTrivia, out List<XmlNodeSyntax> remarksNodes, out bool isBackported) &&
465470
(!isBackported || (isBackported && !skipRemarks)))
466471
{
467-
updated.AddRange(GetXmlRow(remarksNode!, indentationTrivia));
472+
updated.AddRange(remarksNodes);
468473
}
469474

470475
return new SyntaxList<SyntaxNode>(updated);
471476
}
472477

473-
private static IEnumerable<XmlNodeSyntax> GetXmlRow(XmlNodeSyntax item, SyntaxTrivia? indentationTrivia)
478+
private static bool TryGetOrCreateXmlRows(SyntaxList<XmlNodeSyntax> originalXmls, string tagName,
479+
string apiDocsText, string? attributeValue, SyntaxTrivia? indentationTrivia, out List<XmlNodeSyntax> rows, out bool isBackported)
474480
{
475-
yield return GetIndentationNode(indentationTrivia);
476-
yield return GetTripleSlashNode();
477-
yield return item;
478-
yield return GetNewLineNode();
479-
}
481+
rows = [];
480482

481-
private static bool TryGetOrCreateXmlNode(SyntaxList<XmlNodeSyntax> originalXmls, string tagName,
482-
string apiDocsText, string? attributeValue, [NotNullWhen(returnValue: true)] out XmlNodeSyntax? node, out bool isBackported)
483-
{
484-
SyntaxTokenList contentTokens;
483+
if (apiDocsText.IsDocsEmpty())
484+
{
485+
isBackported = false;
485486

486-
isBackported = false;
487+
// Not yet documented in api docs, so try to see if it was already documented in triple slash
488+
XmlNodeSyntax? xmlNode = originalXmls.FirstOrDefault(xmlNode => DoesNodeHaveTag(xmlNode, tagName));
487489

488-
if (!apiDocsText.IsDocsEmpty())
489-
{
490-
isBackported = true;
490+
if (xmlNode != null)
491+
{
492+
rows.Add(xmlNode);
493+
return true;
494+
}
495+
496+
// We don't want to add an empty xml item. We want don't want to add one in this case, it needs
497+
// to be missing on purpose so the developer sees the build error and adds it manually.
498+
499+
return false;
500+
}
491501

502+
isBackported = true;
503+
504+
List<XmlNodeSyntax> nodes = new();
505+
506+
bool first = true;
507+
foreach (string line in apiDocsText.Split(_NewLineSeparators, _NewLineSplitOptions))
508+
{
492509
// Overwrite the current triple slash with the text that comes from api docs
493510
SyntaxToken textLiteral = SyntaxFactory.XmlTextLiteral(
494511
leading: SyntaxFactory.TriviaList(),
495-
text: apiDocsText,
496-
value: apiDocsText,
512+
text: line,
513+
value: line,
497514
trailing: SyntaxFactory.TriviaList());
498515

499-
contentTokens = SyntaxFactory.TokenList(textLiteral);
500-
}
501-
else
502-
{
503-
// Not yet documented in api docs, so try to see if it was documented in triple slash
504-
XmlNodeSyntax? xmlNode = originalXmls.FirstOrDefault(xmlNode => DoesNodeHasTag(xmlNode, tagName));
516+
XmlTextSyntax xmlText = SyntaxFactory.XmlText().WithTextTokens(SyntaxFactory.TokenList(textLiteral));
505517

506-
if (xmlNode != null)
518+
if (first)
507519
{
508-
XmlElementSyntax xmlElement = (XmlElementSyntax)xmlNode;
509-
XmlTextSyntax xmlText = (XmlTextSyntax)xmlElement.Content.Single();
510-
contentTokens = xmlText.TextTokens;
520+
nodes.Add(xmlText);
521+
first = false;
511522
}
512523
else
513524
{
514-
// We don't want to add an empty xml item. We want don't want to add one in this case, it needs
515-
// to be missing on purpose so the developer sees the build error and adds it manually.
516-
node = null;
517-
return false;
525+
IEnumerable<XmlNodeSyntax> content = GetXmlRow(xmlText, indentationTrivia);
526+
nodes.AddRange(content);
518527
}
519528
}
520529

521-
node = CreateXmlNode(tagName, contentTokens, attributeValue);
530+
rows.AddRange(GetXmlRow(CreateXmlNode(tagName, nodes.ToArray(), attributeValue), indentationTrivia));
531+
522532
return true;
523533
}
534+
private static IEnumerable<XmlNodeSyntax> GetXmlRow(XmlNodeSyntax item, SyntaxTrivia? indentationTrivia)
535+
{
536+
yield return GetIndentationNode(indentationTrivia);
537+
yield return GetTripleSlashNode();
538+
yield return item;
539+
yield return GetNewLineNode();
540+
}
524541

525542
private static XmlTextSyntax GetTripleSlashNode()
526543
{
@@ -566,10 +583,8 @@ private static XmlTextSyntax GetNewLineNode()
566583
return SyntaxFactory.XmlText().WithTextTokens(SyntaxFactory.TokenList(tokens));
567584
}
568585

569-
private static XmlElementSyntax CreateXmlNode(string tagName, SyntaxTokenList contentTokens, string? attributeValue = null)
586+
private static XmlElementSyntax CreateXmlNode(string tagName, XmlNodeSyntax[] content, string? attributeValue = null)
570587
{
571-
SyntaxList<XmlNodeSyntax> content = SyntaxFactory.SingletonList<XmlNodeSyntax>(SyntaxFactory.XmlText().WithTextTokens(contentTokens));
572-
573588
XmlElementSyntax result;
574589

575590
switch (tagName)
@@ -614,7 +629,7 @@ private static XmlElementSyntax CreateXmlNode(string tagName, SyntaxTokenList co
614629
return result;
615630
}
616631

617-
private static XmlElementSyntax GetXmlAttributedElement(SyntaxList<XmlNodeSyntax> content, string tagName, string attributeName, string attributeValue)
632+
private static XmlElementSyntax GetXmlAttributedElement(IEnumerable<XmlNodeSyntax> content, string tagName, string attributeName, string attributeValue)
618633
{
619634
Debug.Assert(!string.IsNullOrWhiteSpace(tagName));
620635
Debug.Assert(!string.IsNullOrWhiteSpace(attributeName));
@@ -639,10 +654,10 @@ private static XmlElementSyntax GetXmlAttributedElement(SyntaxList<XmlNodeSyntax
639654

640655
XmlElementEndTagSyntax endTag = SyntaxFactory.XmlElementEndTag(SyntaxFactory.XmlName(SyntaxFactory.Identifier(tagName)));
641656

642-
return SyntaxFactory.XmlElement(startTag, content, endTag);
657+
return SyntaxFactory.XmlElement(startTag, SyntaxFactory.List(content), endTag);
643658
}
644659

645-
private static bool DoesNodeHasTag(SyntaxNode xmlNode, string tagName)
660+
private static bool DoesNodeHaveTag(SyntaxNode xmlNode, string tagName)
646661
{
647662
if (tagName == ExceptionTag)
648663
{

0 commit comments

Comments
 (0)