Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,16 @@ public override bool IsTriviaWithEndOfLine()
}

// Use conditional weak table so we always return same identity for structured trivia
private static readonly ConditionalWeakTable<SyntaxNode, Dictionary<CodeAnalysis.SyntaxTrivia, WeakReference<SyntaxNode>>> s_structuresTable
= new ConditionalWeakTable<SyntaxNode, Dictionary<CodeAnalysis.SyntaxTrivia, WeakReference<SyntaxNode>>>();
//
// As there are commonly few structured trivia per parent, use a SmallDictionary for
// mapping from trivia to StructuredTriviaSyntax. Testing against roslyn, of parents
// containing structured trivia:
// 81.2% contain 1 structured trivia
// 96.5% contain 2 or fewer structured trivia
// 99.6% contain 4 or fewer structured trivia
// 100% contain 7 or fewer structured trivia
private static readonly ConditionalWeakTable<SyntaxNode, SmallDictionary<CodeAnalysis.SyntaxTrivia, SyntaxNode>> s_structuresTable
= new ConditionalWeakTable<SyntaxNode, SmallDictionary<CodeAnalysis.SyntaxTrivia, SyntaxNode>>();

/// <summary>
/// Gets the syntax node represented the structure of this trivia, if any. The HasStructure property can be used to
Expand All @@ -270,36 +278,29 @@ public override bool IsTriviaWithEndOfLine()
/// </remarks>
public override SyntaxNode GetStructure(Microsoft.CodeAnalysis.SyntaxTrivia trivia)
{
if (trivia.HasStructure)
if (!trivia.HasStructure)
{
var parent = trivia.Token.Parent;
if (parent != null)
{
SyntaxNode structure;
var structsInParent = s_structuresTable.GetOrCreateValue(parent);
lock (structsInParent)
{
if (!structsInParent.TryGetValue(trivia, out var weakStructure))
{
structure = CSharp.Syntax.StructuredTriviaSyntax.Create(trivia);
structsInParent.Add(trivia, new WeakReference<SyntaxNode>(structure));
}
else if (!weakStructure.TryGetTarget(out structure))
{
structure = CSharp.Syntax.StructuredTriviaSyntax.Create(trivia);
weakStructure.SetTarget(structure);
}
}
return null;
}

return structure;
}
else
var parent = trivia.Token.Parent;
if (parent is null)
{
return CSharp.Syntax.StructuredTriviaSyntax.Create(trivia);
}

SyntaxNode structure;
var structsInParent = s_structuresTable.GetOrCreateValue(parent);
lock (structsInParent)
{
if (!structsInParent.TryGetValue(trivia, out structure))
{
return CSharp.Syntax.StructuredTriviaSyntax.Create(trivia);
structure = CSharp.Syntax.StructuredTriviaSyntax.Create(trivia);
structsInParent.Add(trivia, structure);
}
}

return null;
return structure;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
End Function

' Use conditional weak table so we always return same identity for structured trivia
Private Shared ReadOnly s_structuresTable As New ConditionalWeakTable(Of SyntaxNode, Dictionary(Of Microsoft.CodeAnalysis.SyntaxTrivia, WeakReference(Of SyntaxNode)))
'
' As there are commonly few structured trivia per parent, use a SmallDictionary for
' mapping from trivia to StructuredTriviaSyntax. Testing against roslyn, of parents
' containing structured trivia:
' 81.2% contain 1 structured trivia
' 96.5% contain 2 or fewer structured trivia
' 99.6% contain 4 or fewer structured trivia
' 100% contain 7 or fewer structured trivia
Private Shared ReadOnly s_structuresTable As New ConditionalWeakTable(Of SyntaxNode, SmallDictionary(Of Microsoft.CodeAnalysis.SyntaxTrivia, SyntaxNode))

Public Overrides Function GetStructure(trivia As Microsoft.CodeAnalysis.SyntaxTrivia) As SyntaxNode
If Not trivia.HasStructure Then
Expand All @@ -219,13 +227,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
Dim structsInParent = s_structuresTable.GetOrCreateValue(parent)

SyncLock structsInParent
Dim weakStructure As WeakReference(Of SyntaxNode) = Nothing
If Not structsInParent.TryGetValue(trivia, weakStructure) Then
If Not structsInParent.TryGetValue(trivia, [structure]) Then
[structure] = VisualBasic.Syntax.StructuredTriviaSyntax.Create(trivia)
structsInParent.Add(trivia, New WeakReference(Of SyntaxNode)([structure]))
ElseIf Not weakStructure.TryGetTarget([structure]) Then
[structure] = VisualBasic.Syntax.StructuredTriviaSyntax.Create(trivia)
weakStructure.SetTarget([structure])
structsInParent.Add(trivia, [structure])
End If
End SyncLock

Expand Down
Loading