From 719498d1380d1fcae604cd0eeea5dae9b32d67d2 Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Thu, 8 Nov 2018 12:04:59 -0800 Subject: [PATCH 1/9] Restore overloads caching semantic --- .../Engine/Impl/Values/BuiltinFunctionInfo.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Analysis/Engine/Impl/Values/BuiltinFunctionInfo.cs b/src/Analysis/Engine/Impl/Values/BuiltinFunctionInfo.cs index 407ca58a5..b29f3c3cd 100644 --- a/src/Analysis/Engine/Impl/Values/BuiltinFunctionInfo.cs +++ b/src/Analysis/Engine/Impl/Values/BuiltinFunctionInfo.cs @@ -23,6 +23,7 @@ namespace Microsoft.PythonTools.Analysis.Values { internal class BuiltinFunctionInfo : BuiltinNamespace, IHasRichDescription, IHasQualifiedName { private string _doc; + private OverloadResult[] _overloadResults; private IPythonFunctionOverload[] _overloads; private BuiltinMethodInfo _method; @@ -33,7 +34,7 @@ public BuiltinFunctionInfo(IPythonFunction function, PythonAnalyzer projectState public override IPythonType PythonType => _type; - public override bool IsOfType(IAnalysisSet klass) + public override bool IsOfType(IAnalysisSet klass) => klass.Contains(ProjectState.ClassInfos[BuiltinTypeId.Function]) || klass.Contains(ProjectState.ClassInfos[BuiltinTypeId.BuiltinFunction]); public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames) { @@ -122,8 +123,16 @@ private static IEnumerable> GetParameterString(IPyt } } - public override IEnumerable Overloads - => GetFunctionOverloads().Select(o => new BuiltinFunctionOverloadResult(ProjectState, Function.Name, o, 0, () => Description)); + public override IEnumerable Overloads { + get { + if (_overloadResults == null) { + _overloadResults = GetFunctionOverloads() + .Select(o => new BuiltinFunctionOverloadResult(ProjectState, Function.Name, o, 0, () => Description)) + .ToArray(); + } + return _overloadResults; + } + } public override string Documentation => _doc ?? (_doc = Utils.StripDocumentation(Function.Documentation)); From beb681957593e1aa29127473c32f78259598737b Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Mon, 19 Nov 2018 15:28:16 -0800 Subject: [PATCH 2/9] Bug fixes --- .../Engine/Impl/Values/ProtocolInfo.cs | 23 ++++------ src/Analysis/Engine/Impl/Values/Protocols.cs | 44 +++++++++---------- .../Engine/Impl/Values/TypingTypeInfo.cs | 3 -- .../Implementation/Server.WorkspaceSymbols.cs | 7 ++- 4 files changed, 34 insertions(+), 43 deletions(-) diff --git a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs index 57e4daaca..a0bef8534 100644 --- a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs +++ b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs @@ -129,14 +129,12 @@ public override PythonMemberType MemberType { } - internal override void AddReference(Node node, AnalysisUnit analysisUnit) { - _references.GetReferences(analysisUnit.ProjectEntry as ProjectEntry)?.AddReference(new EncodedLocation(analysisUnit, node)); - } + internal override void AddReference(Node node, AnalysisUnit analysisUnit) + => _references.GetReferences(analysisUnit.ProjectEntry as ProjectEntry)?.AddReference(new EncodedLocation(analysisUnit, node)); public override IEnumerable Locations { get { - ReferenceList defns; - if (!_references.TryGetValue(DeclaringModule, out defns)) { + if (!_references.TryGetValue(DeclaringModule, out var defns)) { return Enumerable.Empty(); } return defns.Definitions.Select(l => l.GetLocationInfo()).Where(l => l != null); @@ -151,17 +149,14 @@ public override void AugmentAssign(AugmentedAssignStatement node, AnalysisUnit u } } - public override IAnalysisSet Await(Node node, AnalysisUnit unit) { - return AnalysisSet.UnionAll(_protocols.Select(p => p.Await(node, unit))); - } + public override IAnalysisSet Await(Node node, AnalysisUnit unit) + => AnalysisSet.UnionAll(_protocols.Select(p => p.Await(node, unit))); - public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) { - return AnalysisSet.UnionAll(_protocols.Select(p => p.BinaryOperation(node, unit, operation, rhs))); - } + public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) + => AnalysisSet.UnionAll(_protocols.Select(p => p.BinaryOperation(node, unit, operation, rhs))); - public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames) { - return AnalysisSet.UnionAll(_protocols.Select(p => p.Call(node, unit, args, keywordArgNames))); - } + public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames) + => AnalysisSet.UnionAll(_protocols.Select(p => p.Call(node, unit, args, keywordArgNames))); public override void DeleteMember(Node node, AnalysisUnit unit, string name) { foreach (var p in _protocols) { diff --git a/src/Analysis/Engine/Impl/Values/Protocols.cs b/src/Analysis/Engine/Impl/Values/Protocols.cs index 6fa670023..3ce502287 100644 --- a/src/Analysis/Engine/Impl/Values/Protocols.cs +++ b/src/Analysis/Engine/Impl/Values/Protocols.cs @@ -63,20 +63,19 @@ protected IAnalysisSet MakeMethod(string qualname, IReadOnlyList a public override PythonMemberType MemberType => PythonMemberType.Unknown; - // Do not return any default values from protocols. We call these directly and handle null. - public override IAnalysisSet Await(Node node, AnalysisUnit unit) => null; - public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) => null; - public override IAnalysisSet GetAsyncEnumeratorTypes(Node node, AnalysisUnit unit) => null; - public override IAnalysisSet GetAsyncIterator(Node node, AnalysisUnit unit) => null; - public override IAnalysisSet GetDescriptor(Node node, AnalysisValue instance, AnalysisValue context, AnalysisUnit unit) => null; - public override IAnalysisSet GetDescriptor(PythonAnalyzer projectState, AnalysisValue instance, AnalysisValue context) => null; - public override IAnalysisSet GetEnumeratorTypes(Node node, AnalysisUnit unit) => null; - public override IAnalysisSet GetIndex(Node node, AnalysisUnit unit, IAnalysisSet index) => null; - public override IAnalysisSet GetInstanceType() => null; - public override IEnumerable> GetItems() => null; - public override IAnalysisSet GetIterator(Node node, AnalysisUnit unit) => null; - public override IAnalysisSet GetReturnForYieldFrom(Node node, AnalysisUnit unit) => null; - public override IAnalysisSet UnaryOperation(Node node, AnalysisUnit unit, PythonOperator operation) => null; + public override IAnalysisSet Await(Node node, AnalysisUnit unit) => AnalysisSet.Empty; + public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) => AnalysisSet.Empty; + public override IAnalysisSet GetAsyncEnumeratorTypes(Node node, AnalysisUnit unit) => AnalysisSet.Empty; + public override IAnalysisSet GetAsyncIterator(Node node, AnalysisUnit unit) => AnalysisSet.Empty; + public override IAnalysisSet GetDescriptor(Node node, AnalysisValue instance, AnalysisValue context, AnalysisUnit unit) => AnalysisSet.Empty; + public override IAnalysisSet GetDescriptor(PythonAnalyzer projectState, AnalysisValue instance, AnalysisValue context) => AnalysisSet.Empty; + public override IAnalysisSet GetEnumeratorTypes(Node node, AnalysisUnit unit) => AnalysisSet.Empty; + public override IAnalysisSet GetIndex(Node node, AnalysisUnit unit, IAnalysisSet index) => AnalysisSet.Empty; + public override IAnalysisSet GetInstanceType() => AnalysisSet.Empty; + public override IEnumerable> GetItems() => Enumerable.Empty< KeyValuePair>(); + public override IAnalysisSet GetIterator(Node node, AnalysisUnit unit) => AnalysisSet.Empty; + public override IAnalysisSet GetReturnForYieldFrom(Node node, AnalysisUnit unit) => AnalysisSet.Empty; + public override IAnalysisSet UnaryOperation(Node node, AnalysisUnit unit, PythonOperator operation) => AnalysisSet.Empty; public override IDictionary GetAllMembers(IModuleContext moduleContext, GetMemberOptions options = GetMemberOptions.None) { EnsureMembers(); @@ -131,7 +130,13 @@ class NameProtocol : Protocol { private readonly BuiltinTypeId _typeId; private List> _richDescription; - public NameProtocol(ProtocolInfo self, string name, string documentation = null, BuiltinTypeId typeId = BuiltinTypeId.Unknown, PythonMemberType memberType = PythonMemberType.Unknown) : base(self) { + public NameProtocol( + ProtocolInfo self, + string name, + string documentation = null, + BuiltinTypeId typeId = BuiltinTypeId.Unknown, + PythonMemberType memberType = PythonMemberType.Unknown) + : base(self) { _name = name; _doc = documentation; _typeId = typeId; @@ -139,13 +144,8 @@ public NameProtocol(ProtocolInfo self, string name, string documentation = null, _richDescription = new List> { new KeyValuePair(WellKnownRichDescriptionKinds.Type, _name) }; } - public NameProtocol(ProtocolInfo self, IPythonType type) : base(self) { - _name = type.Name; - _doc = type.Documentation; - _typeId = type.TypeId; - MemberType = type.MemberType; - _richDescription = new List> { new KeyValuePair(WellKnownRichDescriptionKinds.Type, _name) }; - } + public NameProtocol(ProtocolInfo self, IPythonType type) + : this(self, type.Name, type.Documentation, type.TypeId, type.MemberType) { } public void ExtendDescription(KeyValuePair part) { _richDescription.Add(part); diff --git a/src/Analysis/Engine/Impl/Values/TypingTypeInfo.cs b/src/Analysis/Engine/Impl/Values/TypingTypeInfo.cs index 27dc88b02..0ace7ec05 100644 --- a/src/Analysis/Engine/Impl/Values/TypingTypeInfo.cs +++ b/src/Analysis/Engine/Impl/Values/TypingTypeInfo.cs @@ -236,10 +236,7 @@ public TypingTypeInfoFinalizer(ExpressionEvaluator eval, Node node, AnalysisUnit private IAnalysisSet MakeTuple(params IAnalysisSet[] types) { var p = new ProtocolInfo(Entry, State); - var np = new NameProtocol(p, Types[BuiltinTypeId.Tuple]); var tp = new TupleProtocol(p, types); - np.ExtendDescription(tp.GetRichDescription()); - p.AddProtocol(np); p.AddProtocol(tp); return p; } diff --git a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs index a23156b14..a8aef5e28 100644 --- a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs +++ b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs @@ -78,10 +78,9 @@ private static IEnumerable GetModuleVariables(ProjectEntry entry, 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)) { - return true; - } + if (m.Values.Any(v => v.DeclaringModule == entry || + v.Locations.MaybeEnumerate().Any(l => l.DocumentUri == entry.DocumentUri))) { + return string.IsNullOrEmpty(prefix) || m.Name.StartsWithOrdinal(prefix, ignoreCase: true); } return false; }) From 3e923887892aa3d39cb388e7e437af98f16bb4a0 Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Tue, 20 Nov 2018 17:09:05 -0800 Subject: [PATCH 3/9] Null checks and better initialize and return locations --- .../Interpreter/Ast/AstPythonBoundMethod.cs | 3 +- .../Impl/Interpreter/Ast/AstPythonModule.cs | 2 +- .../Impl/Interpreter/Ast/AstPythonProperty.cs | 2 +- .../Impl/Interpreter/Ast/AstPythonType.cs | 2 +- .../Interpreter/Ast/AstScrapedPythonModule.cs | 2 +- src/Analysis/Engine/Impl/MemberResult.cs | 2 +- src/Analysis/Engine/Impl/ModuleTable.cs | 2 +- .../Engine/Impl/Values/BoundMethodInfo.cs | 6 +- .../Engine/Impl/Values/BuiltinNamespace.cs | 10 +- .../Engine/Impl/Values/MemberReferences.cs | 3 +- .../Engine/Impl/Values/MultipleMemberInfo.cs | 2 +- .../Engine/Impl/Values/ProtocolInfo.cs | 125 +++++++++--------- src/Analysis/Engine/Impl/Values/Protocols.cs | 6 +- .../Impl/Values/SpecializedNamespace.cs | 50 ++----- .../Implementation/Server.WorkspaceSymbols.cs | 9 +- 15 files changed, 91 insertions(+), 135 deletions(-) diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBoundMethod.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBoundMethod.cs index 6795312cc..645a6b772 100644 --- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBoundMethod.cs +++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBoundMethod.cs @@ -16,6 +16,7 @@ using System.Collections.Generic; using Microsoft.PythonTools.Analysis; +using Microsoft.PythonTools.Analysis.Infrastructure; namespace Microsoft.PythonTools.Interpreter.Ast { class AstPythonBoundMethod : IPythonBoundFunction, ILocatedMember { @@ -27,6 +28,6 @@ public AstPythonBoundMethod(IPythonFunction function, IPythonType selfType) { public IPythonFunction Function { get; } public IPythonType SelfType { get; } public PythonMemberType MemberType => PythonMemberType.Method; - public IEnumerable Locations => (Function as ILocatedMember)?.Locations; + public IEnumerable Locations => (Function as ILocatedMember)?.Locations.MaybeEnumerate(); } } diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonModule.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonModule.cs index db99531bd..c8340e216 100644 --- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonModule.cs +++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonModule.cs @@ -94,7 +94,7 @@ public string Documentation { public Uri DocumentUri { get; } public PythonMemberType MemberType => PythonMemberType.Module; public Dictionary Properties { get; } = new Dictionary(); - public IEnumerable Locations { get; } + public IEnumerable Locations { get; } = Enumerable.Empty(); public int AnalysisVersion => 1; public IModuleContext AnalysisContext => null; diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonProperty.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonProperty.cs index 69f79bb1d..ef1271188 100644 --- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonProperty.cs +++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonProperty.cs @@ -14,7 +14,7 @@ public AstPythonProperty( ILocationInfo location ) { IsReadOnly = true; - Locations = new[] { location }; + Locations = location != null ? new[] { location } : Enumerable.Empty(); FunctionDefinition = definition; } diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonType.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonType.cs index 1e20fc680..ddb3b19ad 100644 --- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonType.cs +++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonType.cs @@ -58,7 +58,7 @@ private AstPythonType(string name, Dictionary members, IEnumera _members = members; _mro = Array.Empty(); DeclaringModule = NoDeclModule; - Locations = locations; + Locations = locations ?? Enumerable.Empty(); } internal void AddMembers(IEnumerable> members, bool overwrite) { diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstScrapedPythonModule.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstScrapedPythonModule.cs index ab6210430..2449e6e65 100644 --- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstScrapedPythonModule.cs +++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstScrapedPythonModule.cs @@ -90,7 +90,7 @@ public virtual IEnumerable GetMemberNames(IModuleContext moduleContext) internal PythonAst Ast { get; private set; } #if DEBUG - public IEnumerable Locations { get; private set; } = new LocationInfo[0]; + public IEnumerable Locations { get; private set; } = Enumerable.Empty(); #endif protected virtual List GetScrapeArguments(IPythonInterpreterFactory factory) { diff --git a/src/Analysis/Engine/Impl/MemberResult.cs b/src/Analysis/Engine/Impl/MemberResult.cs index 89bcad1f5..4c28edaa5 100644 --- a/src/Analysis/Engine/Impl/MemberResult.cs +++ b/src/Analysis/Engine/Impl/MemberResult.cs @@ -85,7 +85,7 @@ internal MemberResult(string name, Func> vars, Func

- public IEnumerable Locations => Values.SelectMany(ns => ns.Locations); + public IEnumerable Locations => Values.SelectMany(ns => ns.Locations.MaybeEnumerate()); public IEnumerable Values => _vars.Value; diff --git a/src/Analysis/Engine/Impl/ModuleTable.cs b/src/Analysis/Engine/Impl/ModuleTable.cs index 6cef3d215..a31c11abe 100644 --- a/src/Analysis/Engine/Impl/ModuleTable.cs +++ b/src/Analysis/Engine/Impl/ModuleTable.cs @@ -416,7 +416,7 @@ internal override bool ModuleContainsMember(IModuleContext context, string name) return false; } - foreach (var location in type.Locations) { + foreach (var location in type.Locations.WhereNotNull()) { if (location.FilePath != modInfo.ProjectEntry.FilePath) { // declared in another module return false; diff --git a/src/Analysis/Engine/Impl/Values/BoundMethodInfo.cs b/src/Analysis/Engine/Impl/Values/BoundMethodInfo.cs index 4285efce4..67e53eb56 100644 --- a/src/Analysis/Engine/Impl/Values/BoundMethodInfo.cs +++ b/src/Analysis/Engine/Impl/Values/BoundMethodInfo.cs @@ -9,14 +9,14 @@ // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS // OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY // IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -// MERCHANTABLITY OR NON-INFRINGEMENT. +// MERCHANTABILITY OR NON-INFRINGEMENT. // // See the Apache Version 2.0 License for specific language governing // permissions and limitations under the License. using System.Collections.Generic; using System.Linq; -using System.Text; +using Microsoft.PythonTools.Analysis.Infrastructure; using Microsoft.PythonTools.Interpreter; using Microsoft.PythonTools.Parsing.Ast; @@ -45,7 +45,7 @@ public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet[] a public override IPythonProjectEntry DeclaringModule => Function.DeclaringModule; public override int DeclaringVersion => Function.DeclaringVersion; - public override IEnumerable Locations => Function.Locations; + public override IEnumerable Locations => Function.Locations.MaybeEnumerate(); public override BuiltinTypeId TypeId => BuiltinTypeId.Function; public IEnumerable> GetRichDescription() { diff --git a/src/Analysis/Engine/Impl/Values/BuiltinNamespace.cs b/src/Analysis/Engine/Impl/Values/BuiltinNamespace.cs index 1c1dfad7c..2315ef2df 100644 --- a/src/Analysis/Engine/Impl/Values/BuiltinNamespace.cs +++ b/src/Analysis/Engine/Impl/Values/BuiltinNamespace.cs @@ -111,15 +111,7 @@ public MemberContainerType ContainedValue { public virtual ILocatedMember GetLocatedMember() => null; - public override IEnumerable Locations { - get { - var locatedMem = GetLocatedMember(); - if (locatedMem != null) { - return locatedMem.Locations; - } - return LocationInfo.Empty; - } - } + public override IEnumerable Locations => GetLocatedMember()?.Locations.MaybeEnumerate(); public override bool Equals(object obj) { if (obj is BuiltinNamespace bn && GetType() == bn.GetType()) { diff --git a/src/Analysis/Engine/Impl/Values/MemberReferences.cs b/src/Analysis/Engine/Impl/Values/MemberReferences.cs index 321361647..6690cd0cf 100644 --- a/src/Analysis/Engine/Impl/Values/MemberReferences.cs +++ b/src/Analysis/Engine/Impl/Values/MemberReferences.cs @@ -17,6 +17,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.PythonTools.Analysis.Analyzer; +using Microsoft.PythonTools.Analysis.Infrastructure; using Microsoft.PythonTools.Interpreter; using Microsoft.PythonTools.Parsing.Ast; @@ -62,7 +63,7 @@ public IEnumerable GetDefinitions(string name, IMemberContainer var member = innerContainer.GetMember(context, name) as ILocatedMember; if (member != null) { - res.AddRange(member.Locations.Select(loc => new DefinitionList(loc))); + res.AddRange(member.Locations.MaybeEnumerate().Select(loc => new DefinitionList(loc))); } return res; diff --git a/src/Analysis/Engine/Impl/Values/MultipleMemberInfo.cs b/src/Analysis/Engine/Impl/Values/MultipleMemberInfo.cs index 8eb039d81..822674bf9 100644 --- a/src/Analysis/Engine/Impl/Values/MultipleMemberInfo.cs +++ b/src/Analysis/Engine/Impl/Values/MultipleMemberInfo.cs @@ -228,7 +228,7 @@ public override string ShortDescription { } } - public override IEnumerable Locations => _members.SelectMany(m => m.Locations); + public override IEnumerable Locations => _members.SelectMany(m => m.Locations.MaybeEnumerate()); IModule IModule.GetChildPackage(IModuleContext context, string name) { var children = new List(); diff --git a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs index a0bef8534..309282704 100644 --- a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs +++ b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs @@ -137,7 +137,7 @@ public override IEnumerable Locations { if (!_references.TryGetValue(DeclaringModule, out var defns)) { return Enumerable.Empty(); } - return defns.Definitions.Select(l => l.GetLocationInfo()).Where(l => l != null); + return defns.Definitions.Select(l => l.GetLocationInfo()).ExcludeDefault(); } } @@ -268,85 +268,78 @@ public override bool Equals(object obj) { public override int GetHashCode() => ObjectComparer.Instance.GetHashCode(_protocols); - internal override bool UnionEquals(AnalysisValue av, int strength) { - if (av is ProtocolInfo pi) { - if (strength > 0) { - return Name == pi.Name; - } - return ObjectComparer.Instance.Equals(_protocols, pi._protocols); - } - return false; - } + internal override bool UnionEquals(AnalysisValue av, int strength) + => av is ProtocolInfo pi ? ObjectComparer.Instance.Equals(_protocols, pi._protocols) : false; - internal override int UnionHashCode(int strength) { - if (strength > 0) { - return Name.GetHashCode(); - } - return GetHashCode(); + internal override int UnionHashCode(int strength) { + if (strength > 0) { + return Name.GetHashCode(); } + return GetHashCode(); + } - internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength) { - if (strength > 0 && av is ProtocolInfo pi && pi.Push()) { - try { - var name = _protocols.OfType().FirstOrDefault(); - if (_protocols.Count == 1 && name != null) { - return this; - } - - var protocols = _protocols.Union(pi._protocols, out bool changed); - if (!changed) { - return this; - } + internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength) { + if (strength > 0 && av is ProtocolInfo pi && pi.Push()) { + try { + var name = _protocols.OfType().FirstOrDefault(); + if (_protocols.Count == 1 && name != null) { + return this; + } - if (name != null) { - protocols.Split(out _, out protocols); - protocols = protocols.Add(name); - } + var protocols = _protocols.Union(pi._protocols, out bool changed); + if (!changed) { + return this; + } - return new ProtocolInfo(DeclaringModule, State) { - _protocols = protocols - }; - } finally { - pi.Pop(); + if (name != null) { + protocols.Split(out _, out protocols); + protocols = protocols.Add(name); } - } - return this; + return new ProtocolInfo(DeclaringModule, State) { + _protocols = protocols + }; + } finally { + pi.Pop(); + } } - public virtual IEnumerable> GetRichDescription() { - var names = _protocols.OfType().ToArray(); - Debug.Assert(names.Length <= 1, "Multiple names are not supported"); - var name = names.FirstOrDefault(); - if (name != null) { - return name.GetRichDescription(); - } + return this; + } - var res = new List>(); - var namespaces = _protocols.OfType().ToArray(); - var tuples = _protocols.OfType().ToArray(); - var other = _protocols.OfType().Except(names).Except(namespaces).ToArray(); - - if (namespaces.Any()) { - var addComma = false; - res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Misc, "(")); - foreach (var p in namespaces) { - if (addComma) { - res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Comma, ", ")); - } - addComma = true; - res.AddRange(p.GetRichDescription()); + public virtual IEnumerable> GetRichDescription() { + var names = _protocols.OfType().ToArray(); + Debug.Assert(names.Length <= 1, "Multiple names are not supported"); + var name = names.FirstOrDefault(); + if (name != null) { + return name.GetRichDescription(); + } + + var res = new List>(); + var namespaces = _protocols.OfType().ToArray(); + var tuples = _protocols.OfType().ToArray(); + var other = _protocols.OfType().Except(names).Except(namespaces).ToArray(); + + if (namespaces.Any()) { + var addComma = false; + res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Misc, "(")); + foreach (var p in namespaces) { + if (addComma) { + res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Comma, ", ")); } - res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Misc, ")")); + addComma = true; + res.AddRange(p.GetRichDescription()); } + res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Misc, ")")); + } - foreach (var p in other) { - res.AddRange(p.GetRichDescription().ToArray()); - } + foreach (var p in other) { + res.AddRange(p.GetRichDescription().ToArray()); + } - res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.EndOfDeclaration, string.Empty)); + res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.EndOfDeclaration, string.Empty)); - return res; - } + return res; } } +} diff --git a/src/Analysis/Engine/Impl/Values/Protocols.cs b/src/Analysis/Engine/Impl/Values/Protocols.cs index 3ce502287..5bbdf69e0 100644 --- a/src/Analysis/Engine/Impl/Values/Protocols.cs +++ b/src/Analysis/Engine/Impl/Values/Protocols.cs @@ -851,12 +851,12 @@ public override IAnalysisSet GetDescriptor(PythonAnalyzer projectState, Analysis public override IEnumerable> GetItems() => _actualType.GetItems(); public override IAnalysisSet GetIterator(Node node, AnalysisUnit unit) => _actualType.GetIterator(node, unit); public override IAnalysisSet GetReturnForYieldFrom(Node node, AnalysisUnit unit) => _actualType.GetReturnForYieldFrom(node, unit); - public override IEnumerable Locations => _actualType.Locations; + public override IEnumerable Locations => _actualType.Locations.MaybeEnumerate(); public override IMro Mro => _actualType.Mro; - public override IEnumerable Overloads => _actualType.Overloads; + public override IEnumerable Overloads => _actualType.Overloads.MaybeEnumerate(); public override int? GetLength() => _actualType.GetLength(); internal override IAnalysisSet Resolve(AnalysisUnit unit, ResolutionContext context) => _actualType.Resolve(unit, context); - internal override IEnumerable References => _actualType.References; + internal override IEnumerable References => _actualType.References.MaybeEnumerate(); public override IAnalysisSet ReverseBinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) => _actualType.ReverseBinaryOperation(node, unit, operation, rhs); diff --git a/src/Analysis/Engine/Impl/Values/SpecializedNamespace.cs b/src/Analysis/Engine/Impl/Values/SpecializedNamespace.cs index 486f051c9..f853b64e5 100644 --- a/src/Analysis/Engine/Impl/Values/SpecializedNamespace.cs +++ b/src/Analysis/Engine/Impl/Values/SpecializedNamespace.cs @@ -9,7 +9,7 @@ // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS // OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY // IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -// MERCHANTABLITY OR NON-INFRINGEMENT. +// MERCHANTABILITY OR NON-INFRINGEMENT. // // See the Apache Version 2.0 License for specific language governing // permissions and limitations under the License. @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.PythonTools.Analysis.Infrastructure; using Microsoft.PythonTools.Interpreter; using Microsoft.PythonTools.Parsing.Ast; @@ -208,52 +209,17 @@ public override bool IsOfType(IAnalysisSet klass) { return _original.IsOfType(klass); } - public override IEnumerable Locations { - get { - if (_original == null) { - return new LocationInfo[0]; - } - return _original.Locations; - } - } + public override IEnumerable Locations => _original.Locations?.MaybeEnumerate(); - public override string Name => _original == null ? base.Name : this._original.Name; + public override string Name => _original == null ? base.Name : _original.Name; - public override IEnumerable Overloads { - get { - if (_original == null) { - return new OverloadResult[0]; - } - return _original.Overloads; - } - } + public override IEnumerable Overloads =>_original.Overloads.MaybeEnumerate(); - public override IPythonType PythonType { - get { - if (_original == null) { - return null; - } - return _original.PythonType; - } - } + public override IPythonType PythonType => _original?.PythonType; - internal override IEnumerable References { - get { - if (_original == null) { - return new LocationInfo[0]; - } - return _original.References; - } - } + internal override IEnumerable References => _original.References?.MaybeEnumerate(); - public override PythonMemberType MemberType { - get { - if (_original == null) { - return PythonMemberType.Unknown; - } - return _original.MemberType; - } - } + public override PythonMemberType MemberType => _original == null ? PythonMemberType.Unknown : _original.MemberType; public override IAnalysisSet ReverseBinaryOperation(Node node, AnalysisUnit unit, Parsing.PythonOperator operation, IAnalysisSet rhs) { if (_original == null) { diff --git a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs index a8aef5e28..41d671991 100644 --- a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs +++ b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs @@ -79,7 +79,10 @@ private static IEnumerable GetModuleVariables(ProjectEntry entry, var result = all .Where(m => { if (m.Values.Any(v => v.DeclaringModule == entry || - v.Locations.MaybeEnumerate().Any(l => l.DocumentUri == entry.DocumentUri))) { + v.Locations + .MaybeEnumerate() + .WhereNotNull() + .Any(l => l.DocumentUri == entry.DocumentUri))) { return string.IsNullOrEmpty(prefix) || m.Name.StartsWithOrdinal(prefix, ignoreCase: true); } return false; @@ -95,7 +98,7 @@ private SymbolInformation ToSymbolInformation(IMemberResult m) { _kind = m.MemberType.ToString().ToLowerInvariant() }; - var loc = m.Locations.FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); + var loc = m.Locations.MaybeEnumerate().FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); if (loc != null) { res.location = new Location { uri = loc.DocumentUri, @@ -151,7 +154,7 @@ private DocumentSymbol ToDocumentSymbol(IMemberResult m, Dictionary(); } - var loc = m.Locations.FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); + var loc = m.Locations.MaybeEnumerate().FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); if (loc != null) { res.range = new SourceSpan( new SourceLocation(loc.StartLine, loc.StartColumn), From 81b5f04a343ee9447185448fe7ad55e7b946b4c0 Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Wed, 21 Nov 2018 09:07:45 -0800 Subject: [PATCH 4/9] CR feedback --- .../Engine/Impl/Values/ProtocolInfo.cs | 112 +++++++++--------- .../Implementation/Server.WorkspaceSymbols.cs | 6 +- 2 files changed, 61 insertions(+), 57 deletions(-) diff --git a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs index 309282704..dd2c93ded 100644 --- a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs +++ b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs @@ -271,75 +271,75 @@ public override bool Equals(object obj) { internal override bool UnionEquals(AnalysisValue av, int strength) => av is ProtocolInfo pi ? ObjectComparer.Instance.Equals(_protocols, pi._protocols) : false; - internal override int UnionHashCode(int strength) { - if (strength > 0) { - return Name.GetHashCode(); + internal override int UnionHashCode(int strength) { + if (strength > 0) { + return Name.GetHashCode(); + } + return GetHashCode(); } - return GetHashCode(); - } - internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength) { - if (strength > 0 && av is ProtocolInfo pi && pi.Push()) { - try { - var name = _protocols.OfType().FirstOrDefault(); - if (_protocols.Count == 1 && name != null) { - return this; - } + internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength) { + if (strength > 0 && av is ProtocolInfo pi && pi.Push()) { + try { + var name = _protocols.OfType().FirstOrDefault(); + if (_protocols.Count == 1 && name != null) { + return this; + } - var protocols = _protocols.Union(pi._protocols, out bool changed); - if (!changed) { - return this; - } + var protocols = _protocols.Union(pi._protocols, out bool changed); + if (!changed) { + return this; + } - if (name != null) { - protocols.Split(out _, out protocols); - protocols = protocols.Add(name); - } + if (name != null) { + protocols.Split(out _, out protocols); + protocols = protocols.Add(name); + } - return new ProtocolInfo(DeclaringModule, State) { - _protocols = protocols - }; - } finally { - pi.Pop(); + return new ProtocolInfo(DeclaringModule, State) { + _protocols = protocols + }; + } finally { + pi.Pop(); + } } - } - return this; - } - - public virtual IEnumerable> GetRichDescription() { - var names = _protocols.OfType().ToArray(); - Debug.Assert(names.Length <= 1, "Multiple names are not supported"); - var name = names.FirstOrDefault(); - if (name != null) { - return name.GetRichDescription(); + return this; } - var res = new List>(); - var namespaces = _protocols.OfType().ToArray(); - var tuples = _protocols.OfType().ToArray(); - var other = _protocols.OfType().Except(names).Except(namespaces).ToArray(); - - if (namespaces.Any()) { - var addComma = false; - res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Misc, "(")); - foreach (var p in namespaces) { - if (addComma) { - res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Comma, ", ")); + public virtual IEnumerable> GetRichDescription() { + var names = _protocols.OfType().ToArray(); + Debug.Assert(names.Length <= 1, "Multiple names are not supported"); + var name = names.FirstOrDefault(); + if (name != null) { + return name.GetRichDescription(); + } + + var res = new List>(); + var namespaces = _protocols.OfType().ToArray(); + var tuples = _protocols.OfType().ToArray(); + var other = _protocols.OfType().Except(names).Except(namespaces).ToArray(); + + if (namespaces.Any()) { + var addComma = false; + res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Misc, "(")); + foreach (var p in namespaces) { + if (addComma) { + res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Comma, ", ")); + } + addComma = true; + res.AddRange(p.GetRichDescription()); } - addComma = true; - res.AddRange(p.GetRichDescription()); + res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Misc, ")")); } - res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.Misc, ")")); - } - foreach (var p in other) { - res.AddRange(p.GetRichDescription().ToArray()); - } + foreach (var p in other) { + res.AddRange(p.GetRichDescription().ToArray()); + } - res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.EndOfDeclaration, string.Empty)); + res.Add(new KeyValuePair(WellKnownRichDescriptionKinds.EndOfDeclaration, string.Empty)); - return res; + return res; + } } } -} diff --git a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs index 41d671991..765778c35 100644 --- a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs +++ b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs @@ -154,7 +154,11 @@ private DocumentSymbol ToDocumentSymbol(IMemberResult m, Dictionary(); } - var loc = m.Locations.MaybeEnumerate().FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); + var loc = m.Locations + .MaybeEnumerate() + .WhereNotNull() + .FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); + if (loc != null) { res.range = new SourceSpan( new SourceLocation(loc.StartLine, loc.StartColumn), From 1610e90f230b14e1fee600c8a66375ea1bec021d Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Wed, 21 Nov 2018 10:04:28 -0800 Subject: [PATCH 5/9] More checks --- src/Analysis/Engine/Impl/Values/ProtocolInfo.cs | 7 +------ .../Impl/Implementation/Server.WorkspaceSymbols.cs | 6 +++++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs index dd2c93ded..7543dce84 100644 --- a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs +++ b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs @@ -271,12 +271,7 @@ public override bool Equals(object obj) { internal override bool UnionEquals(AnalysisValue av, int strength) => av is ProtocolInfo pi ? ObjectComparer.Instance.Equals(_protocols, pi._protocols) : false; - internal override int UnionHashCode(int strength) { - if (strength > 0) { - return Name.GetHashCode(); - } - return GetHashCode(); - } + internal override int UnionHashCode(int strength) => strength > 0 ? Name.GetHashCode() : GetHashCode(); internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength) { if (strength > 0 && av is ProtocolInfo pi && pi.Push()) { diff --git a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs index 765778c35..5ad9099e8 100644 --- a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs +++ b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs @@ -98,7 +98,11 @@ private SymbolInformation ToSymbolInformation(IMemberResult m) { _kind = m.MemberType.ToString().ToLowerInvariant() }; - var loc = m.Locations.MaybeEnumerate().FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); + var loc = m.Locations + .MaybeEnumerate() + .WhereNotNull() + .FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); + if (loc != null) { res.location = new Location { uri = loc.DocumentUri, From 698043a86a68a6b04f5f99ac66b3042882b5bfd4 Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Wed, 21 Nov 2018 10:26:10 -0800 Subject: [PATCH 6/9] Couple more checks --- src/Analysis/Engine/Impl/EncodedLocation.cs | 15 +++------------ src/Analysis/Engine/Impl/ModuleAnalysis.cs | 2 +- src/Analysis/Engine/Impl/ModuleTable.cs | 2 +- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/Analysis/Engine/Impl/EncodedLocation.cs b/src/Analysis/Engine/Impl/EncodedLocation.cs index cf5ddcb19..f8ba0bc13 100644 --- a/src/Analysis/Engine/Impl/EncodedLocation.cs +++ b/src/Analysis/Engine/Impl/EncodedLocation.cs @@ -55,13 +55,9 @@ public EncodedLocation(ILocationResolver resolver, object location) { public bool IsAlive => (Resolver as ICanExpire)?.IsAlive ?? true; - public override int GetHashCode() { - return (Resolver?.GetHashCode() ?? 0) ^ (Location?.GetHashCode() ?? 0); - } + public override int GetHashCode() => (Resolver?.GetHashCode() ?? 0) ^ (Location?.GetHashCode() ?? 0); - public override bool Equals(object obj) { - return obj is EncodedLocation location && Equals(location); - } + public override bool Equals(object obj) => obj is EncodedLocation location && Equals(location); #region IEquatable Members @@ -71,11 +67,6 @@ public bool Equals(EncodedLocation other) { #endregion - public ILocationInfo GetLocationInfo() { - if (Resolver == null) { - return Location as ILocationInfo; - } - return Resolver.ResolveLocation(Location); - } + public ILocationInfo GetLocationInfo() => Resolver?.ResolveLocation(Location) ?? Location as ILocationInfo; } } diff --git a/src/Analysis/Engine/Impl/ModuleAnalysis.cs b/src/Analysis/Engine/Impl/ModuleAnalysis.cs index c58ad31b3..3c328585c 100644 --- a/src/Analysis/Engine/Impl/ModuleAnalysis.cs +++ b/src/Analysis/Engine/Impl/ModuleAnalysis.cs @@ -124,7 +124,7 @@ internal static IEnumerable ToVariables(IReferenceable referen varType = VariableType.Definition; } - foreach (var loc in type.Locations.WhereNotNull()) { + foreach (var loc in type.Locations.MaybeEnumerate().WhereNotNull()) { yield return new AnalysisVariable(def, varType, loc); } } diff --git a/src/Analysis/Engine/Impl/ModuleTable.cs b/src/Analysis/Engine/Impl/ModuleTable.cs index a31c11abe..2731a4f07 100644 --- a/src/Analysis/Engine/Impl/ModuleTable.cs +++ b/src/Analysis/Engine/Impl/ModuleTable.cs @@ -416,7 +416,7 @@ internal override bool ModuleContainsMember(IModuleContext context, string name) return false; } - foreach (var location in type.Locations.WhereNotNull()) { + foreach (var location in type.Locations.MaybeEnumerate().WhereNotNull()) { if (location.FilePath != modInfo.ProjectEntry.FilePath) { // declared in another module return false; From 953b451b813cceb2fb3f0720592f829f9bf85b89 Mon Sep 17 00:00:00 2001 From: Mikhail Arkhipov Date: Fri, 23 Nov 2018 14:55:08 -0800 Subject: [PATCH 7/9] Move check to MemberResult --- src/Analysis/Engine/Impl/MemberResult.cs | 2 +- .../Engine/Impl/Values/SpecializedNamespace.cs | 2 +- .../Implementation/Server.WorkspaceSymbols.cs | 15 +++------------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/Analysis/Engine/Impl/MemberResult.cs b/src/Analysis/Engine/Impl/MemberResult.cs index 4c28edaa5..e8cfe0f8f 100644 --- a/src/Analysis/Engine/Impl/MemberResult.cs +++ b/src/Analysis/Engine/Impl/MemberResult.cs @@ -85,7 +85,7 @@ internal MemberResult(string name, Func> vars, Func

- public IEnumerable Locations => Values.SelectMany(ns => ns.Locations.MaybeEnumerate()); + public IEnumerable Locations => Values.SelectMany(ns => ns.Locations.MaybeEnumerate()).ExcludeDefault(); public IEnumerable Values => _vars.Value; diff --git a/src/Analysis/Engine/Impl/Values/SpecializedNamespace.cs b/src/Analysis/Engine/Impl/Values/SpecializedNamespace.cs index f853b64e5..f1e5346c6 100644 --- a/src/Analysis/Engine/Impl/Values/SpecializedNamespace.cs +++ b/src/Analysis/Engine/Impl/Values/SpecializedNamespace.cs @@ -209,7 +209,7 @@ public override bool IsOfType(IAnalysisSet klass) { return _original.IsOfType(klass); } - public override IEnumerable Locations => _original.Locations?.MaybeEnumerate(); + public override IEnumerable Locations => _original?.Locations?.MaybeEnumerate(); public override string Name => _original == null ? base.Name : _original.Name; diff --git a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs index 5ad9099e8..f22e38b7e 100644 --- a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs +++ b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs @@ -79,10 +79,7 @@ private static IEnumerable GetModuleVariables(ProjectEntry entry, var result = all .Where(m => { if (m.Values.Any(v => v.DeclaringModule == entry || - v.Locations - .MaybeEnumerate() - .WhereNotNull() - .Any(l => l.DocumentUri == entry.DocumentUri))) { + v.Locations.Any(l => l.DocumentUri == entry.DocumentUri))) { return string.IsNullOrEmpty(prefix) || m.Name.StartsWithOrdinal(prefix, ignoreCase: true); } return false; @@ -98,10 +95,7 @@ private SymbolInformation ToSymbolInformation(IMemberResult m) { _kind = m.MemberType.ToString().ToLowerInvariant() }; - var loc = m.Locations - .MaybeEnumerate() - .WhereNotNull() - .FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); + var loc = m.Locations.FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); if (loc != null) { res.location = new Location { @@ -158,10 +152,7 @@ private DocumentSymbol ToDocumentSymbol(IMemberResult m, Dictionary(); } - var loc = m.Locations - .MaybeEnumerate() - .WhereNotNull() - .FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); + var loc = m.Locations.FirstOrDefault(l => !string.IsNullOrEmpty(l.FilePath)); if (loc != null) { res.range = new SourceSpan( From 91532fd562f8d2035904c7b959afdbc0e49e8d03 Mon Sep 17 00:00:00 2001 From: Mikhail Arkhipov Date: Fri, 23 Nov 2018 14:58:37 -0800 Subject: [PATCH 8/9] Check --- .../Impl/Implementation/Server.WorkspaceSymbols.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs index f22e38b7e..285f1a99d 100644 --- a/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs +++ b/src/LanguageServer/Impl/Implementation/Server.WorkspaceSymbols.cs @@ -79,7 +79,10 @@ private static IEnumerable GetModuleVariables(ProjectEntry entry, var result = all .Where(m => { if (m.Values.Any(v => v.DeclaringModule == entry || - v.Locations.Any(l => l.DocumentUri == entry.DocumentUri))) { + v.Locations + .MaybeEnumerate() + .ExcludeDefault() + .Any(l => l.DocumentUri == entry.DocumentUri))) { return string.IsNullOrEmpty(prefix) || m.Name.StartsWithOrdinal(prefix, ignoreCase: true); } return false; From 992b5bdf6db5d8149980d3dfc0ae8365529100e3 Mon Sep 17 00:00:00 2001 From: Mikhail Arkhipov Date: Fri, 23 Nov 2018 15:12:08 -0800 Subject: [PATCH 9/9] Simplify --- src/Analysis/Engine/Impl/Values/ProtocolInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs index 7543dce84..8c355d6c8 100644 --- a/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs +++ b/src/Analysis/Engine/Impl/Values/ProtocolInfo.cs @@ -269,7 +269,7 @@ public override bool Equals(object obj) { public override int GetHashCode() => ObjectComparer.Instance.GetHashCode(_protocols); internal override bool UnionEquals(AnalysisValue av, int strength) - => av is ProtocolInfo pi ? ObjectComparer.Instance.Equals(_protocols, pi._protocols) : false; + => av is ProtocolInfo pi && ObjectComparer.Instance.Equals(_protocols, pi._protocols); internal override int UnionHashCode(int strength) => strength > 0 ? Name.GetHashCode() : GetHashCode();