1
- using System . Collections . Immutable ;
2
- using System . Diagnostics . CodeAnalysis ;
3
- using Google . Protobuf . Collections ;
4
1
using Microsoft . CodeAnalysis ;
5
2
using Microsoft . CodeAnalysis . CSharp ;
6
3
using Microsoft . CodeAnalysis . CSharp . Syntax ;
@@ -22,31 +19,43 @@ public class ScipCSharpSyntaxWalker : CSharpSyntaxWalker
22
19
private readonly Dictionary < ISymbol , ScipSymbol > _globals ;
23
20
private readonly Dictionary < ISymbol , ScipSymbol > _locals = new ( SymbolEqualityComparer . Default ) ;
24
21
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.
25
25
private readonly SymbolDisplayFormat _format = new (
26
26
globalNamespaceStyle : SymbolDisplayGlobalNamespaceStyle . OmittedAsContaining ,
27
- typeQualificationStyle : SymbolDisplayTypeQualificationStyle . NameAndContainingTypesAndNamespaces ,
27
+ typeQualificationStyle : SymbolDisplayTypeQualificationStyle . NameOnly ,
28
28
genericsOptions : SymbolDisplayGenericsOptions . IncludeTypeParameters |
29
29
SymbolDisplayGenericsOptions . IncludeVariance |
30
30
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 |
34
37
SymbolDisplayMemberOptions . IncludeContainingType |
35
38
SymbolDisplayMemberOptions . IncludeExplicitInterface ,
36
39
delegateStyle : SymbolDisplayDelegateStyle . NameAndSignature ,
37
40
extensionMethodStyle : SymbolDisplayExtensionMethodStyle . InstanceMethod ,
38
- parameterOptions : SymbolDisplayParameterOptions . IncludeType | SymbolDisplayParameterOptions . IncludeName |
41
+ parameterOptions : SymbolDisplayParameterOptions . IncludeType |
42
+ SymbolDisplayParameterOptions . IncludeName |
39
43
SymbolDisplayParameterOptions . IncludeDefaultValue |
40
44
SymbolDisplayParameterOptions . IncludeExtensionThis |
41
45
SymbolDisplayParameterOptions . IncludeOptionalBrackets |
42
46
SymbolDisplayParameterOptions . IncludeParamsRefOut ,
43
47
propertyStyle : SymbolDisplayPropertyStyle . ShowReadWriteDescriptor ,
44
- localOptions : SymbolDisplayLocalOptions . IncludeType | SymbolDisplayLocalOptions . IncludeRef |
48
+ localOptions : SymbolDisplayLocalOptions . IncludeType |
49
+ SymbolDisplayLocalOptions . IncludeRef |
45
50
SymbolDisplayLocalOptions . IncludeConstantValue ,
46
- kindOptions : SymbolDisplayKindOptions . IncludeTypeKeyword | SymbolDisplayKindOptions . IncludeMemberKeyword |
51
+ kindOptions : SymbolDisplayKindOptions . IncludeTypeKeyword |
52
+ SymbolDisplayKindOptions . IncludeMemberKeyword |
47
53
SymbolDisplayKindOptions . IncludeNamespaceKeyword ,
48
54
miscellaneousOptions : SymbolDisplayMiscellaneousOptions . AllowDefaultLiteral |
49
- SymbolDisplayMiscellaneousOptions . ExpandNullable
55
+ SymbolDisplayMiscellaneousOptions . UseSpecialTypes |
56
+ SymbolDisplayMiscellaneousOptions . UseAsterisksInMultiDimensionalArrays |
57
+ SymbolDisplayMiscellaneousOptions . IncludeNullableReferenceTypeModifier |
58
+ SymbolDisplayMiscellaneousOptions . EscapeKeywordIdentifiers
50
59
) ;
51
60
52
61
public ScipCSharpSyntaxWalker (
@@ -174,7 +183,6 @@ public override void VisitParameter(ParameterSyntax node)
174
183
//------------------
175
184
176
185
177
-
178
186
private ScipSymbol CreateScipSymbol ( ISymbol ? sym )
179
187
{
180
188
if ( sym == null )
@@ -310,6 +318,22 @@ private static string MethodDisambiguator(ISymbol sym)
310
318
return "" ;
311
319
}
312
320
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
+
313
337
314
338
private void VisitOccurrence ( ISymbol ? symbol , Location location , bool isDefinition )
315
339
{
@@ -361,19 +385,31 @@ private void VisitOccurrence(ISymbol? symbol, Location location, bool isDefiniti
361
385
var baseType = namedTypeSymbol . BaseType ;
362
386
while ( baseType != null )
363
387
{
388
+ var baseTypeSymbol = CreateScipSymbol ( baseType ) . Value ;
389
+ if ( IsIgnoredRelationshipSymbol ( baseTypeSymbol ) )
390
+ {
391
+ break ;
392
+ }
393
+
364
394
info . Relationships . Add ( new Relationship
365
395
{
366
- Symbol = CreateScipSymbol ( baseType ) . Value ,
396
+ Symbol = baseTypeSymbol ,
367
397
IsImplementation = true
368
398
} ) ;
369
399
baseType = baseType . BaseType ;
370
400
}
371
401
372
402
foreach ( var interfaceSymbol in namedTypeSymbol . AllInterfaces )
373
403
{
404
+ var interfaceSymbolSymbol = CreateScipSymbol ( interfaceSymbol ) . Value ;
405
+ if ( IsIgnoredRelationshipSymbol ( interfaceSymbolSymbol ) )
406
+ {
407
+ continue ;
408
+ }
409
+
374
410
info . Relationships . Add ( new Relationship
375
411
{
376
- Symbol = CreateScipSymbol ( interfaceSymbol ) . Value ,
412
+ Symbol = interfaceSymbolSymbol ,
377
413
IsImplementation = true
378
414
} ) ;
379
415
}
@@ -448,6 +484,10 @@ private static IEnumerable<int> LocationToRange(Location location)
448
484
449
485
private static bool IsLocalSymbol ( ISymbol sym )
450
486
{
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 ) ;
452
492
}
453
493
}
0 commit comments