Skip to content

Commit 20534f8

Browse files
authored
Miscellaneous fixes (#17)
- More human friendly documentation formatting - Skip noisy symbol relationships - Add a few more test cases - Update snapshot output format to not emit trailing whitespace - Add comments to better explain some of the existing code
1 parent ed0b7c7 commit 20534f8

25 files changed

+671
-651
lines changed

ScipDotnet.Tests/SnapshotTests.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Text;
77
using DiffPlex.DiffBuilder;
88
using DiffPlex.DiffBuilder.Model;
9+
using Microsoft.CodeAnalysis.CSharp.Syntax;
910
using Scip;
1011
using Index = Scip.Index;
1112

@@ -106,7 +107,12 @@ private static string DiffStrings(string obtained, string expected)
106107

107108
if (i > 0 && diff.Lines[i - 1].Type == ChangeType.Unchanged)
108109
{
109-
sb.Append(" ").AppendLine(diff.Lines[i - 1].Text);
110+
var text = diff.Lines[i - 1].Text;
111+
if (text.Length > 0)
112+
{
113+
sb.Append(" ");
114+
}
115+
sb.AppendLine(text);
110116
}
111117

112118
switch (line.Type)
@@ -221,7 +227,7 @@ private string FormatDocument(Index index, Document document)
221227
for (var lineNumber = 0; lineNumber < lines.Length; lineNumber++)
222228
{
223229
var line = lines[lineNumber].Replace("\t", " ");
224-
sb.Append(" ").AppendLine(line);
230+
sb.Append(line.Length > 0 ? " " : "").AppendLine(line);
225231
while (occurrenceIndex < occurrences.Count)
226232
{
227233
var occurrence = occurrences[occurrenceIndex];

ScipDotnet/ScipCSharpSyntaxWalker.cs

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using System.Collections.Immutable;
2-
using System.Diagnostics.CodeAnalysis;
3-
using Google.Protobuf.Collections;
41
using Microsoft.CodeAnalysis;
52
using Microsoft.CodeAnalysis.CSharp;
63
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -22,31 +19,43 @@ public class ScipCSharpSyntaxWalker : CSharpSyntaxWalker
2219
private readonly Dictionary<ISymbol, ScipSymbol> _globals;
2320
private readonly Dictionary<ISymbol, ScipSymbol> _locals = new(SymbolEqualityComparer.Default);
2421

22+
// Custom formatting options to render symbol documentation. Feel free to tweak these parameters.
23+
// The options were derived by multiple rounds of experimentation with the goal of striking a
24+
// balance between showing detailed/accurate information without using too verbose syntax.
2525
private readonly SymbolDisplayFormat _format = new(
2626
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining,
27-
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
27+
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly,
2828
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters |
2929
SymbolDisplayGenericsOptions.IncludeVariance |
3030
SymbolDisplayGenericsOptions.IncludeTypeConstraints,
31-
memberOptions: SymbolDisplayMemberOptions.IncludeAccessibility | SymbolDisplayMemberOptions.IncludeModifiers |
32-
SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeRef |
33-
SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeConstantValue |
31+
memberOptions: SymbolDisplayMemberOptions.IncludeAccessibility |
32+
SymbolDisplayMemberOptions.IncludeModifiers |
33+
SymbolDisplayMemberOptions.IncludeParameters |
34+
SymbolDisplayMemberOptions.IncludeRef |
35+
SymbolDisplayMemberOptions.IncludeType |
36+
SymbolDisplayMemberOptions.IncludeConstantValue |
3437
SymbolDisplayMemberOptions.IncludeContainingType |
3538
SymbolDisplayMemberOptions.IncludeExplicitInterface,
3639
delegateStyle: SymbolDisplayDelegateStyle.NameAndSignature,
3740
extensionMethodStyle: SymbolDisplayExtensionMethodStyle.InstanceMethod,
38-
parameterOptions: SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeName |
41+
parameterOptions: SymbolDisplayParameterOptions.IncludeType |
42+
SymbolDisplayParameterOptions.IncludeName |
3943
SymbolDisplayParameterOptions.IncludeDefaultValue |
4044
SymbolDisplayParameterOptions.IncludeExtensionThis |
4145
SymbolDisplayParameterOptions.IncludeOptionalBrackets |
4246
SymbolDisplayParameterOptions.IncludeParamsRefOut,
4347
propertyStyle: SymbolDisplayPropertyStyle.ShowReadWriteDescriptor,
44-
localOptions: SymbolDisplayLocalOptions.IncludeType | SymbolDisplayLocalOptions.IncludeRef |
48+
localOptions: SymbolDisplayLocalOptions.IncludeType |
49+
SymbolDisplayLocalOptions.IncludeRef |
4550
SymbolDisplayLocalOptions.IncludeConstantValue,
46-
kindOptions: SymbolDisplayKindOptions.IncludeTypeKeyword | SymbolDisplayKindOptions.IncludeMemberKeyword |
51+
kindOptions: SymbolDisplayKindOptions.IncludeTypeKeyword |
52+
SymbolDisplayKindOptions.IncludeMemberKeyword |
4753
SymbolDisplayKindOptions.IncludeNamespaceKeyword,
4854
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.AllowDefaultLiteral |
49-
SymbolDisplayMiscellaneousOptions.ExpandNullable
55+
SymbolDisplayMiscellaneousOptions.UseSpecialTypes |
56+
SymbolDisplayMiscellaneousOptions.UseAsterisksInMultiDimensionalArrays |
57+
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier |
58+
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers
5059
);
5160

5261
public ScipCSharpSyntaxWalker(
@@ -174,7 +183,6 @@ public override void VisitParameter(ParameterSyntax node)
174183
//------------------
175184

176185

177-
178186
private ScipSymbol CreateScipSymbol(ISymbol? sym)
179187
{
180188
if (sym == null)
@@ -310,6 +318,22 @@ private static string MethodDisambiguator(ISymbol sym)
310318
return "";
311319
}
312320

321+
private readonly string[] _isIgnoredRelationshipSymbol =
322+
{
323+
" System/Object#",
324+
" System/Enum#",
325+
" System/ValueType#",
326+
};
327+
328+
// Returns true if this symbol should not be emitted as a SymbolInformation relationship symbol.
329+
// The reason we ignore these symbols is because they appear automatically for a large number of
330+
// symbols putting pressure on our backend to index the inverted index. It's not particularly useful anyways
331+
// to query all the implementations of something like System/Object#.
332+
private bool IsIgnoredRelationshipSymbol(string symbol)
333+
{
334+
return _isIgnoredRelationshipSymbol.Any(symbol.EndsWith);
335+
}
336+
313337

314338
private void VisitOccurrence(ISymbol? symbol, Location location, bool isDefinition)
315339
{
@@ -361,19 +385,31 @@ private void VisitOccurrence(ISymbol? symbol, Location location, bool isDefiniti
361385
var baseType = namedTypeSymbol.BaseType;
362386
while (baseType != null)
363387
{
388+
var baseTypeSymbol = CreateScipSymbol(baseType).Value;
389+
if (IsIgnoredRelationshipSymbol(baseTypeSymbol))
390+
{
391+
break;
392+
}
393+
364394
info.Relationships.Add(new Relationship
365395
{
366-
Symbol = CreateScipSymbol(baseType).Value,
396+
Symbol = baseTypeSymbol,
367397
IsImplementation = true
368398
});
369399
baseType = baseType.BaseType;
370400
}
371401

372402
foreach (var interfaceSymbol in namedTypeSymbol.AllInterfaces)
373403
{
404+
var interfaceSymbolSymbol = CreateScipSymbol(interfaceSymbol).Value;
405+
if (IsIgnoredRelationshipSymbol(interfaceSymbolSymbol))
406+
{
407+
continue;
408+
}
409+
374410
info.Relationships.Add(new Relationship
375411
{
376-
Symbol = CreateScipSymbol(interfaceSymbol).Value,
412+
Symbol = interfaceSymbolSymbol,
377413
IsImplementation = true
378414
});
379415
}
@@ -448,6 +484,10 @@ private static IEnumerable<int> LocationToRange(Location location)
448484

449485
private static bool IsLocalSymbol(ISymbol sym)
450486
{
451-
return sym.Kind == SymbolKind.Local || (sym.Kind != SymbolKind.Namespace && sym.Name.Equals(""));
487+
return sym.Kind == SymbolKind.Local ||
488+
// Anonymous classes/methods have empty names and can not be accessed outside their file.
489+
// The "global namespace" (parent of all namespaces) also has an empty name and should not
490+
// be treated as a local variable.
491+
(sym.Name.Equals("") && sym.Kind != SymbolKind.Namespace);
452492
}
453493
}

snapshots/input/syntax/Main/Enums.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
13
namespace Main;
24

5+
[SuppressMessage("ReSharper", "all")]
36
public class Enums
47
{
58
enum EnumWithIntValues

snapshots/input/syntax/Main/Literals.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
13
namespace Main;
24

5+
[SuppressMessage("ReSharper", "all")]
36
public class Literals
47
{
58
string Interpolation()

snapshots/input/syntax/Main/Preprocessors.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
13
namespace Main;
24

5+
[SuppressMessage("ReSharper", "all")]
36
public class Preprocessors
47
{
58
string OS()

snapshots/input/syntax/Main/Records.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ public Person(string FirstName) : this(FirstName, FirstName)
4242

4343
record Teacher(string FirstName, string LastName, string Subject) : Person(FirstName, LastName), I1, I2;
4444

45+
void UsingRecords()
46+
{
47+
var person = new Person("a", "b");
48+
var teacher = new Teacher("a", "b", "c");
49+
}
50+
4551
record I3<T>;
4652

4753
record Teacher2() : I3<Person>(), I1;

0 commit comments

Comments
 (0)