Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 95c4f1f

Browse files
authored
Fix detection of nested types (#134)
* Allow getting DocId without prefix in Docs APIs. * Move Resolved* types to their own files. * Add AllTypesVisitor class. * Remove Resolved* classes from MSBuildLoader.cs, minor changes to existing method. * Refactor ToTripleSlashPorter to properly look for all types, including nested ones like delegates, using the AllTypesVisitor. Simplify code considerably. * Adjust unit tests to changes. Ensure no warnings or infos show up in the loaded test csproj. Co-authored-by: carlossanlop <[email protected]>
1 parent 77ff0c3 commit 95c4f1f

16 files changed

+278
-311
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Collections.Generic;
5+
using System.Threading.Tasks;
6+
using Microsoft.CodeAnalysis;
7+
8+
namespace ApiDocsSync.Libraries
9+
{
10+
11+
internal class AllTypesVisitor : SymbolVisitor
12+
{
13+
public readonly List<ISymbol> AllTypesSymbols = new();
14+
public override void VisitNamedType(INamedTypeSymbol symbol)
15+
{
16+
AllTypesSymbols.Add(symbol);
17+
foreach (INamedTypeSymbol typeMember in symbol.GetTypeMembers())
18+
{
19+
Visit(typeMember);
20+
}
21+
}
22+
public override void VisitNamespace(INamespaceSymbol symbol) => Parallel.ForEach(symbol.GetMembers(), s => s.Accept(this));
23+
public override void VisitDynamicType(IDynamicTypeSymbol symbol) => AllTypesSymbols.Add(symbol);
24+
public override void VisitFunctionPointerType(IFunctionPointerTypeSymbol symbol) => AllTypesSymbols.Add(symbol);
25+
public override void VisitAlias(IAliasSymbol symbol) => AllTypesSymbols.Add(symbol);
26+
}
27+
}

src/PortToTripleSlash/src/libraries/Docs/DocsAPI.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ namespace ApiDocsSync.Libraries.Docs
1111
{
1212
internal abstract class DocsAPI : IDocsAPI
1313
{
14+
private string? _docId;
15+
private string? _docIdUnprefixed;
1416
private List<DocsParam>? _params;
1517
private List<DocsParameter>? _parameters;
1618
private List<DocsTypeParameter>? _typeParameters;
@@ -32,7 +34,10 @@ internal abstract class DocsAPI : IDocsAPI
3234

3335
public abstract bool Changed { get; set; }
3436
public string FilePath { get; set; } = string.Empty;
35-
public abstract string DocId { get; }
37+
38+
public string DocId => _docId ??= GetApiSignatureDocId();
39+
40+
public string DocIdUnprefixed => _docIdUnprefixed ??= DocId[2..];
3641

3742
/// <summary>
3843
/// The Parameter elements found inside the Parameters section.
@@ -239,6 +244,10 @@ public DocsTypeParam AddTypeParam(string name, string value)
239244
return new DocsTypeParam(this, typeParam);
240245
}
241246

247+
// For Types, these elements are called TypeSignature.
248+
// For Members, these elements are called MemberSignature.
249+
protected abstract string GetApiSignatureDocId();
250+
242251
protected string GetNodesInPlainText(string name)
243252
{
244253
if (TryGetElement(name, addIfMissing: false, out XElement? element))

src/PortToTripleSlash/src/libraries/Docs/DocsMember.cs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ internal class DocsMember : DocsAPI
1212
{
1313
private string? _memberName;
1414
private List<DocsMemberSignature>? _memberSignatures;
15-
private string? _docId;
1615
private List<DocsException>? _exceptions;
1716

1817
public DocsMember(string filePath, DocsType parentType, XElement xeMember)
@@ -55,25 +54,6 @@ public List<DocsMemberSignature> MemberSignatures
5554
}
5655
}
5756

58-
public override string DocId
59-
{
60-
get
61-
{
62-
if (_docId == null)
63-
{
64-
_docId = string.Empty;
65-
DocsMemberSignature? ms = MemberSignatures.FirstOrDefault(x => x.Language == "DocId");
66-
if (ms == null)
67-
{
68-
string message = string.Format("Could not find a DocId MemberSignature for '{0}'", MemberName);
69-
throw new Exception(message);
70-
}
71-
_docId = ms.Value.DocIdEscaped();
72-
}
73-
return _docId;
74-
}
75-
}
76-
7757
public string MemberType
7858
{
7959
get
@@ -199,5 +179,15 @@ public DocsException AddException(string cref, string value)
199179
Changed = true;
200180
return new DocsException(this, exception);
201181
}
182+
183+
protected override string GetApiSignatureDocId()
184+
{
185+
DocsMemberSignature? dts = MemberSignatures.FirstOrDefault(x => x.Language == "DocId");
186+
if (dts == null)
187+
{
188+
throw new FormatException($"DocId TypeSignature not found for {MemberName}");
189+
}
190+
return dts.Value;
191+
}
202192
}
203193
}

src/PortToTripleSlash/src/libraries/Docs/DocsType.cs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ internal class DocsType : DocsAPI
1919
private string? _name;
2020
private string? _fullName;
2121
private string? _namespace;
22-
private string? _docId;
2322
private string? _baseTypeName;
2423
private List<string>? _interfaceNames;
2524
private List<DocsAttribute>? _attributes;
@@ -114,24 +113,6 @@ public List<DocsTypeSignature> TypeSignatures
114113
}
115114
}
116115

117-
public override string DocId
118-
{
119-
get
120-
{
121-
if (_docId == null)
122-
{
123-
DocsTypeSignature? dts = TypeSignatures.FirstOrDefault(x => x.Language == "DocId");
124-
if (dts == null)
125-
{
126-
string message = $"DocId TypeSignature not found for FullName";
127-
throw new Exception($"DocId TypeSignature not found for FullName");
128-
}
129-
_docId = dts.Value.DocIdEscaped();
130-
}
131-
return _docId;
132-
}
133-
}
134-
135116
public XElement? Base
136117
{
137118
get
@@ -266,5 +247,15 @@ public override string ToString()
266247
{
267248
return FullName;
268249
}
250+
251+
protected override string GetApiSignatureDocId()
252+
{
253+
DocsTypeSignature? dts = TypeSignatures.FirstOrDefault(x => x.Language == "DocId");
254+
if (dts == null)
255+
{
256+
throw new FormatException($"DocId TypeSignature not found for {FullName}");
257+
}
258+
return dts.Value;
259+
}
269260
}
270261
}

src/PortToTripleSlash/src/libraries/Docs/IDocsAPI.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ internal interface IDocsAPI
1313
public abstract bool Changed { get; set; }
1414
public abstract string FilePath { get; set; }
1515
public abstract string DocId { get; }
16+
public abstract string DocIdUnprefixed { get; }
1617
public abstract XElement Docs { get; }
1718
public abstract List<DocsParameter> Parameters { get; }
1819
public abstract List<DocsParam> Params { get; }

src/PortToTripleSlash/src/libraries/MSBuildLoader.cs

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ private bool TryGetResolvedWorkspace(string projectPath, bool isMono, [NotNullWh
121121
return null;
122122
}
123123

124-
private async Task<ResolvedProject?> TryGetResolvedProjectAsync(ResolvedWorkspace resolvedWorkspace, string projectPath, CancellationToken cancellationToken)
124+
private async Task<ResolvedProject?> TryGetResolvedProjectAsync(ResolvedWorkspace resolvedWorkspace, string projectPath, CancellationToken cancellationToken)
125125
{
126126
cancellationToken.ThrowIfCancellationRequested();
127127

@@ -135,11 +135,10 @@ private bool TryGetResolvedWorkspace(string projectPath, bool isMono, [NotNullWh
135135
{
136136
Log.Info($"Found the project in this workspace. Attempting to get compilation...");
137137
Compilation? compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
138-
139138
if (compilation != null)
140139
{
141140
Log.Info($"Found the compilation for this project. Creating the resolved project...");
142-
resolvedProject = new ResolvedProject(resolvedWorkspace, project, compilation);
141+
resolvedProject = new ResolvedProject(resolvedWorkspace, projectPath, project, compilation);
143142
resolvedWorkspace.ResolvedProjects.Add(resolvedProject);
144143
}
145144
else
@@ -178,45 +177,4 @@ private static void ThrowIfDiagnosticsFound(ResolvedWorkspace resolvedWorkspace,
178177
}
179178
}
180179
}
181-
182-
public class ResolvedWorkspace
183-
{
184-
public MSBuildWorkspace Workspace { get; private set; }
185-
public List<ResolvedProject> ResolvedProjects { get; }
186-
public ResolvedWorkspace(MSBuildWorkspace workspace)
187-
{
188-
Workspace = workspace;
189-
ResolvedProjects = new List<ResolvedProject>();
190-
}
191-
}
192-
193-
public class ResolvedProject
194-
{
195-
public ResolvedWorkspace ResolvedWorkspace { get; private set; }
196-
public Project Project { get; private set; }
197-
public Compilation Compilation { get; private set; }
198-
public ResolvedProject(ResolvedWorkspace resolvedWorkspace, Project project, Compilation compilation)
199-
{
200-
ResolvedWorkspace = resolvedWorkspace;
201-
Project = project;
202-
Compilation = compilation;
203-
}
204-
}
205-
206-
public class ResolvedLocation
207-
{
208-
public string TypeName { get; private set; }
209-
public ResolvedProject ResolvedProject { get; private set; }
210-
public Location Location { get; private set; }
211-
public SyntaxTree Tree { get; set; }
212-
public SemanticModel Model { get; set; }
213-
public ResolvedLocation(string typeName, ResolvedProject resolvedProject, Location location, SyntaxTree tree)
214-
{
215-
TypeName = typeName;
216-
ResolvedProject = resolvedProject;
217-
Location = location;
218-
Tree = tree;
219-
Model = resolvedProject.Compilation.GetSemanticModel(Tree);
220-
}
221-
}
222180
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.CodeAnalysis;
5+
6+
namespace ApiDocsSync.Libraries
7+
{
8+
public class ResolvedLocation
9+
{
10+
public string TypeName { get; private set; }
11+
public ResolvedProject ResolvedProject { get; private set; }
12+
public Location Location { get; private set; }
13+
public SyntaxTree Tree { get; set; }
14+
public SemanticModel Model { get; set; }
15+
public ResolvedLocation(string typeName, ResolvedProject resolvedProject, Location location, SyntaxTree tree)
16+
{
17+
TypeName = typeName;
18+
ResolvedProject = resolvedProject;
19+
Location = location;
20+
Tree = tree;
21+
Model = resolvedProject.Compilation.GetSemanticModel(Tree);
22+
}
23+
}
24+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.CodeAnalysis;
5+
6+
namespace ApiDocsSync.Libraries
7+
{
8+
public class ResolvedProject
9+
{
10+
public ResolvedWorkspace ResolvedWorkspace { get; private set; }
11+
public Project Project { get; private set; }
12+
public Compilation Compilation { get; private set; }
13+
public string ProjectPath { get; private set; }
14+
public ResolvedProject(ResolvedWorkspace resolvedWorkspace, string projectPath, Project project, Compilation compilation)
15+
{
16+
ResolvedWorkspace = resolvedWorkspace;
17+
Project = project;
18+
Compilation = compilation;
19+
ProjectPath = projectPath;
20+
}
21+
}
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Collections.Generic;
5+
using Microsoft.CodeAnalysis.MSBuild;
6+
7+
namespace ApiDocsSync.Libraries
8+
{
9+
public class ResolvedWorkspace
10+
{
11+
public MSBuildWorkspace Workspace { get; private set; }
12+
public List<ResolvedProject> ResolvedProjects { get; }
13+
public ResolvedWorkspace(MSBuildWorkspace workspace)
14+
{
15+
Workspace = workspace;
16+
ResolvedProjects = new List<ResolvedProject>();
17+
}
18+
}
19+
}

0 commit comments

Comments
 (0)