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

Limit amount of symbols calculated for a file #201

Merged
merged 9 commits into from
Oct 5, 2018
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 @@ -59,5 +59,24 @@ public static bool SetEquals<T>(this IEnumerable<T> source, IEnumerable<T> other

public static IEnumerable<T> Keys<T, U>(this IEnumerable<KeyValuePair<T, U>> source) => source.Select(GetKey);
public static IEnumerable<T> ExcludeDefault<T>(this IEnumerable<T> source) => source.Where(i => !Equals(i, default(T)));


public static IEnumerable<T> TraverseBreadthFirst<T>(this T root, Func<T, IEnumerable<T>> selectChildren) {
var items = new Queue<T>();
items.Enqueue(root);
while (items.Count > 0) {
var item = items.Dequeue();
yield return item;

var childen = selectChildren(item);
if (childen == null) {
continue;
}

foreach (var child in childen) {
items.Enqueue(child);
}
}
}
}
}
7 changes: 5 additions & 2 deletions src/Analysis/Engine/Impl/Values/Protocols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -385,10 +385,13 @@ protected override Protocol UnionMergeTypes(Protocol p) {
}

class TupleProtocol : IterableProtocol {
internal readonly IAnalysisSet[] _values;
private readonly IAnalysisSet[] _values;

public TupleProtocol(ProtocolInfo self, IEnumerable<IAnalysisSet> values) : base(self, AnalysisSet.UnionAll(values)) {
_values = values.Select(s => s.AsUnion(1)).ToArray();

var argTypes = _values.SelectMany(e => e.Select(v => v is IHasQualifiedName qn ? qn.FullyQualifiedName : v.ShortDescription));
Name = "tuple[{0}]".FormatInvariant(string.Join(", ", argTypes));
}

protected override void EnsureMembers(IDictionary<string, IAnalysisSet> members) {
Expand All @@ -415,7 +418,7 @@ public override IAnalysisSet GetIndex(Node node, AnalysisUnit unit, IAnalysisSet
return AnalysisSet.UnionAll(constants.Select(GetItem));
}

public override string Name => "tuple";
public override string Name { get; }

public override IEnumerable<KeyValuePair<string, string>> GetRichDescription() {
if (_values.Any()) {
Expand Down
1 change: 1 addition & 0 deletions src/LanguageServer/Impl/Definitions/ServerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class PythonAnalysisOptions {

public bool openFilesOnly;
public int symbolsHierarchyDepthLimit = 10;
public int symbolsHierarchyMaxSymbols = 1000;

public string[] errors { get; } = Array.Empty<string>();
public string[] warnings { get; } = Array.Empty<string>();
Expand Down
36 changes: 17 additions & 19 deletions src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
Expand All @@ -26,7 +27,8 @@

namespace Microsoft.Python.LanguageServer.Implementation {
public sealed partial class Server {
private static int _symbolHierarchyDepthLimit = 1;
private static int _symbolHierarchyDepthLimit = 10;
private static int _symbolHierarchyMaxSymbols = 1000;

public override async Task<SymbolInformation[]> WorkspaceSymbols(WorkspaceSymbolParams @params, CancellationToken cancellationToken) {
await WaitForCompleteAnalysisAsync(cancellationToken);
Expand Down Expand Up @@ -72,8 +74,9 @@ private static async Task<List<IMemberResult>> GetModuleVariablesAsync(ProjectEn
}

private static IEnumerable<IMemberResult> GetModuleVariables(ProjectEntry entry, GetMemberOptions opts, string prefix, IModuleAnalysis analysis) {
var all = analysis.GetAllMembers(SourceLocation.None, opts);
return all
var breadthFirst = analysis.Scope.TraverseBreadthFirst(s => s.Children);
var all = breadthFirst.SelectMany(c => analysis.GetAllAvailableMembersFromScope(c, opts));
var result = all
.Where(m => {
if (m.Values.Any(v => v.DeclaringModule == entry || v.Locations.Any(l => l.DocumentUri == entry.DocumentUri))) {
if (string.IsNullOrEmpty(prefix) || m.Name.StartsWithOrdinal(prefix, ignoreCase: true)) {
Expand All @@ -82,17 +85,10 @@ private static IEnumerable<IMemberResult> GetModuleVariables(ProjectEntry entry,
}
return false;
})
.Concat(GetChildScopesVariables(analysis, analysis.Scope, opts, 0));
.Take(_symbolHierarchyMaxSymbols);
return result;
}

private static IEnumerable<IMemberResult> GetChildScopesVariables(IModuleAnalysis analysis, IScope scope, GetMemberOptions opts, int currentDepth)
=> currentDepth < _symbolHierarchyDepthLimit
? scope.Children.SelectMany(c => GetScopeVariables(analysis, c, opts, currentDepth))
: Enumerable.Empty<IMemberResult>();

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

private SymbolInformation ToSymbolInformation(IMemberResult m) {
var res = new SymbolInformation {
name = m.Name,
Expand All @@ -115,8 +111,8 @@ private SymbolInformation ToSymbolInformation(IMemberResult m) {
}

private DocumentSymbol[] ToDocumentSymbols(List<IMemberResult> members) {
var childMap = new Dictionary<IMemberResult, List<IMemberResult>>();
var topLevel = new List<IMemberResult>();
var childMap = new Dictionary<IMemberResult, List<IMemberResult>>();

foreach (var m in members) {
var parent = members.FirstOrDefault(x => x.Scope?.Node == m.Scope?.OuterScope?.Node && x.Name == m.Scope?.Name);
Expand All @@ -131,10 +127,10 @@ private DocumentSymbol[] ToDocumentSymbols(List<IMemberResult> members) {
}

var symbols = topLevel
.GroupBy(mr => mr.Name)
.Select(g => g.First())
.Select(m => ToDocumentSymbol(m, childMap, 0))
.ToArray();
.GroupBy(mr => mr.Name)
.Select(g => g.First())
.Select(m => ToDocumentSymbol(m, childMap, 0))
.ToArray();

return symbols;
}
Expand All @@ -149,9 +145,11 @@ private DocumentSymbol ToDocumentSymbol(IMemberResult m, Dictionary<IMemberResul
};

if (childMap.TryGetValue(m, out var children) && currentDepth < _symbolHierarchyDepthLimit) {
res.children = children.Select(x => ToDocumentSymbol(x, childMap, currentDepth + 1)).ToArray();
res.children = children
.Select(x => ToDocumentSymbol(x, childMap, currentDepth + 1))
.ToArray();
} else {
res.children = new DocumentSymbol[0];
res.children = Array.Empty<DocumentSymbol>();
}

var loc = m.Locations.FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath));
Expand Down
1 change: 1 addition & 0 deletions src/LanguageServer/Impl/Implementation/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ private bool HandleConfigurationChanges(ServerSettings newSettings) {
Settings = newSettings;

_symbolHierarchyDepthLimit = Settings.analysis.symbolsHierarchyDepthLimit;
_symbolHierarchyMaxSymbols = Settings.analysis.symbolsHierarchyMaxSymbols;

if (oldSettings == null) {
return true;
Expand Down
1 change: 1 addition & 0 deletions src/LanguageServer/Impl/LanguageServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ public async Task DidChangeConfiguration(JToken token, CancellationToken cancell
settings.analysis.openFilesOnly = GetSetting(analysis, "openFilesOnly", false);
settings.diagnosticPublishDelay = GetSetting(analysis, "diagnosticPublishDelay", 1000);
settings.symbolsHierarchyDepthLimit = GetSetting(analysis, "symbolsHierarchyDepthLimit", 10);
settings.symbolsHierarchyMaxSymbols = GetSetting(analysis, "symbolsHierarchyMaxSymbols", 1000);

_ui.SetLogLevel(GetLogLevel(analysis));

Expand Down
1 change: 1 addition & 0 deletions src/LanguageServer/Impl/LanguageServerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ namespace Microsoft.Python.LanguageServer.Implementation {
public sealed class LanguageServerSettings: ServerSettings {
public int diagnosticPublishDelay = 1000;
public int symbolsHierarchyDepthLimit = 10;
public int symbolsHierarchyMaxSymbols = 1000;
}
}