Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Commit 0b62fa5

Browse files
author
MikhailArkhipov
committed
Symbols limit
1 parent 6d4956f commit 0b62fa5

5 files changed

Lines changed: 49 additions & 21 deletions

File tree

src/Analysis/Engine/Impl/Infrastructure/Extensions/EnumerableExtensions.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,24 @@ public static bool SetEquals<T>(this IEnumerable<T> source, IEnumerable<T> other
5959

6060
public static IEnumerable<T> Keys<T, U>(this IEnumerable<KeyValuePair<T, U>> source) => source.Select(GetKey);
6161
public static IEnumerable<T> ExcludeDefault<T>(this IEnumerable<T> source) => source.Where(i => !Equals(i, default(T)));
62+
63+
64+
public static IEnumerable<T> TraverseBreadthFirst<T>(this T root, Func<T, IEnumerable<T>> selectChildren) {
65+
var items = new Queue<T>();
66+
items.Enqueue(root);
67+
while (items.Count > 0) {
68+
var item = items.Dequeue();
69+
yield return item;
70+
71+
var childen = selectChildren(item);
72+
if (childen == null) {
73+
continue;
74+
}
75+
76+
foreach (var child in childen) {
77+
items.Enqueue(child);
78+
}
79+
}
80+
}
6281
}
6382
}

src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// See the Apache Version 2.0 License for specific language governing
1515
// permissions and limitations under the License.
1616

17+
using System;
1718
using System.Collections.Generic;
1819
using System.Linq;
1920
using System.Threading;
@@ -26,7 +27,7 @@
2627

2728
namespace Microsoft.Python.LanguageServer.Implementation {
2829
public sealed partial class Server {
29-
private static int _symbolHierarchyDepthLimit = 1;
30+
private static int _symbolHierarchyMaxSymbols = 1000;
3031

3132
public override async Task<SymbolInformation[]> WorkspaceSymbols(WorkspaceSymbolParams @params, CancellationToken cancellationToken) {
3233
await WaitForCompleteAnalysisAsync(cancellationToken);
@@ -82,16 +83,16 @@ private static IEnumerable<IMemberResult> GetModuleVariables(ProjectEntry entry,
8283
}
8384
return false;
8485
})
85-
.Concat(GetChildScopesVariables(analysis, analysis.Scope, opts, 0));
86+
.Take(_symbolHierarchyMaxSymbols)
87+
.Concat(GetChildScopesVariables(analysis, analysis.Scope, opts))
88+
.Take(_symbolHierarchyMaxSymbols);
8689
}
8790

88-
private static IEnumerable<IMemberResult> GetChildScopesVariables(IModuleAnalysis analysis, IScope scope, GetMemberOptions opts, int currentDepth)
89-
=> currentDepth < _symbolHierarchyDepthLimit
90-
? scope.Children.SelectMany(c => GetScopeVariables(analysis, c, opts, currentDepth))
91-
: Enumerable.Empty<IMemberResult>();
91+
private static IEnumerable<IMemberResult> GetChildScopesVariables(IModuleAnalysis analysis, IScope scope, GetMemberOptions opts)
92+
=> scope.TraverseBreadthFirst(s => s.Children).SelectMany(c => GetScopeVariables(analysis, c, opts));
9293

93-
private static IEnumerable<IMemberResult> GetScopeVariables(IModuleAnalysis analysis, IScope scope, GetMemberOptions opts, int currentDepth)
94-
=> analysis.GetAllAvailableMembersFromScope(scope, opts).Concat(GetChildScopesVariables(analysis, scope, opts, currentDepth + 1));
94+
private static IEnumerable<IMemberResult> GetScopeVariables(IModuleAnalysis analysis, IScope scope, GetMemberOptions opts)
95+
=> analysis.GetAllAvailableMembersFromScope(scope, opts).Concat(GetChildScopesVariables(analysis, scope, opts));
9596

9697
private SymbolInformation ToSymbolInformation(IMemberResult m) {
9798
var res = new SymbolInformation {
@@ -115,8 +116,9 @@ private SymbolInformation ToSymbolInformation(IMemberResult m) {
115116
}
116117

117118
private DocumentSymbol[] ToDocumentSymbols(List<IMemberResult> members) {
118-
var childMap = new Dictionary<IMemberResult, List<IMemberResult>>();
119119
var topLevel = new List<IMemberResult>();
120+
var childMap = new Dictionary<IMemberResult, List<IMemberResult>>();
121+
var totalCount = 0;
120122

121123
foreach (var m in members) {
122124
var parent = members.FirstOrDefault(x => x.Scope?.Node == m.Scope?.OuterScope?.Node && x.Name == m.Scope?.Name);
@@ -128,18 +130,23 @@ private DocumentSymbol[] ToDocumentSymbols(List<IMemberResult> members) {
128130
} else {
129131
topLevel.Add(m);
130132
}
133+
if (++totalCount >= _symbolHierarchyMaxSymbols) {
134+
break;
135+
}
131136
}
132137

133-
var symbols = topLevel
134-
.GroupBy(mr => mr.Name)
135-
.Select(g => g.First())
136-
.Select(m => ToDocumentSymbol(m, childMap, 0))
137-
.ToArray();
138+
var symbols = topLevel.SelectMany(t => t
139+
.TraverseBreadthFirst(c => childMap.ContainsKey(c) ? childMap[c] : Enumerable.Empty<IMemberResult>())
140+
.Take(_symbolHierarchyMaxSymbols)
141+
.GroupBy(mr => mr.Name)
142+
.Select(g => g.First())
143+
.Select(m => ToDocumentSymbol(m, childMap)))
144+
.ToArray();
138145

139146
return symbols;
140147
}
141148

142-
private DocumentSymbol ToDocumentSymbol(IMemberResult m, Dictionary<IMemberResult, List<IMemberResult>> childMap, int currentDepth) {
149+
private DocumentSymbol ToDocumentSymbol(IMemberResult m, Dictionary<IMemberResult, List<IMemberResult>> childMap) {
143150
var res = new DocumentSymbol {
144151
name = m.Name,
145152
detail = m.Name,
@@ -148,10 +155,12 @@ private DocumentSymbol ToDocumentSymbol(IMemberResult m, Dictionary<IMemberResul
148155
_functionKind = GetFunctionKind(m)
149156
};
150157

151-
if (childMap.TryGetValue(m, out var children) && currentDepth < _symbolHierarchyDepthLimit) {
152-
res.children = children.Select(x => ToDocumentSymbol(x, childMap, currentDepth + 1)).ToArray();
158+
if (childMap.TryGetValue(m, out var children)) {
159+
res.children = children
160+
.Select(x => ToDocumentSymbol(x, childMap))
161+
.ToArray();
153162
} else {
154-
res.children = new DocumentSymbol[0];
163+
res.children = Array.Empty<DocumentSymbol>();
155164
}
156165

157166
var loc = m.Locations.FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath));

src/LanguageServer/Impl/Implementation/Server.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ private bool HandleConfigurationChanges(ServerSettings newSettings) {
684684
var oldSettings = Settings;
685685
Settings = newSettings;
686686

687-
_symbolHierarchyDepthLimit = Settings.analysis.symbolsHierarchyDepthLimit;
687+
_symbolHierarchyMaxSymbols = Settings.analysis.symbolsHierarchyMaxSymbols;
688688

689689
if (oldSettings == null) {
690690
return true;

src/LanguageServer/Impl/LanguageServer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public async Task DidChangeConfiguration(JToken token, CancellationToken cancell
142142
var analysis = pythonSection["analysis"];
143143
settings.analysis.openFilesOnly = GetSetting(analysis, "openFilesOnly", false);
144144
settings.diagnosticPublishDelay = GetSetting(analysis, "diagnosticPublishDelay", 1000);
145-
settings.symbolsHierarchyDepthLimit = GetSetting(analysis, "symbolsHierarchyDepthLimit", 10);
145+
settings.symbolsHierarchyMaxSymbols = GetSetting(analysis, "symbolsHierarchyDepthLimit", 1000);
146146

147147
_ui.SetLogLevel(GetLogLevel(analysis));
148148

src/LanguageServer/Impl/LanguageServerSettings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
namespace Microsoft.Python.LanguageServer.Implementation {
1818
public sealed class LanguageServerSettings: ServerSettings {
1919
public int diagnosticPublishDelay = 1000;
20-
public int symbolsHierarchyDepthLimit = 10;
20+
public int symbolsHierarchyMaxSymbols = 1000;
2121
}
2222
}

0 commit comments

Comments
 (0)